计算机系统应用教程网站

网站首页 > 技术文章 正文

传统图像处理案例:对比两张图的差异

btikc 2024-10-12 10:21:45 技术文章 14 ℃ 0 评论

今天想和大家分享的一个例子,很简单,就是对比两张图存在什么差异。

没错,大体就是像“大家一起来找茬”找不同的益智游戏那样。

玩法就是上下两张图片存在不同,让你对比并找出差异点。但是现在来说,这类游戏可以用算法来实现了。现在浮躁的人们,连玩儿都不认真对待了,一心想着那个名次排行榜。

下面就说一下最简单的实现方式。

就拿下面这张图来举例子:

我们仔细观察,就可以看出上下两张图的不同点:

  • 左上角的气球不一样,一个椭圆,一个心形。
  • 左边小橘猫戴的帽子不一样,底纹颜色不一样。
  • 中间蛋糕底座不一样,一个有托,一个没有。
  • 最右侧红狗耳朵不一样,一个耷拉着,一个翘起。

首先,我们会面对这么一张图片。可能是游戏截屏截来的,也可能通过接口或其他方式得来的。那么,第一步得把它的图片分割开,变成两张图片才好进行对比。

# 读取图像
image = cv2.imread("img.png")
# 将图像转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 对灰度图像进行二值化处理,然后进行反转
_, binary_mask = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)
# 查找轮廓 cv2.CHAIN_APPROX_SIMPLE 只保留端点
contours, _ = cv2.findContours(binary_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 每个边界框由四个值表示:x和y是边界框左上角的坐标,w和h是边界框的宽和高
bounding_boxes = [cv2.boundingRect(contour) for contour in contours]

首先,我们读入图片,之后通过cv2.cvtColor转为灰度图。

转为灰度图的好处就是便于处理,因为彩色图是3个通道,而灰度图只有1个通道。当转为灰度之后,再对图像进行二值化操作。

二值化操作cv2.threshold让原来灰度数值变为非黑即白,轮廓更加明显。以二值化数据为基础,再对数据进行轮廓查找cv2.findContours

白色(255)是有值,黑色(0)默认是空白,通过轮廓就可以圈画出上下两张图。这样就得到了两张待对比的图片。

cv2.boundingRect可以从轮廓中圈出一个矩形。它里面包含了矩形的左上角的x,y坐标,以及图片的宽度w和高度h。因此,很方便就可以把这两张图从原图中剪出来,为了便于后续处理,我们直接从灰度图中裁剪。

img1_x, img1_y, img1_w, img1_h = boxes[0]
img2_x, img2_y, img2_w, img2_h = boxes[1]
gray1 = gray[img1_y:img1_y+img1_h, img1_x:img1_x+img1_w]
gray2 = gray[img2_y:img2_y+img2_h, img2_x:img2_x+img2_w]

通过cv2.absdiff就可以计算两张灰度图的差异:

# 计算图像差异
diff = cv2.absdiff(gray1, gray2)

这是什么意思呢?两张图如果完全一样,那么它俩应该是重合的,两者相减该是空白。但凡有些差别,那么两者的差异就会显现出来。

差异找到了,下面我们得把它标记出来。同样,又用到了二值化和寻找轮廓那一套方法。

# 二值化差异图像
_, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
bounding_boxes = [cv2.boundingRect(contour) for contour in contours]

最后,我们把轮廓给绘制到原图上,就得到了最终结果:

for x, y, w, h in bounding_boxes:
    x , y = x + img1_x, y + img1_y
    cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)

这就是“大家来找茬(找不同)”自动排查算法的最简实现方式。

首先,速度上我们肯定不如机器快。其次在识别度上,差异少的时候我们还可以用肉眼判断,当差异多了,我们真的很受限。就比如下面图片中小樱桃的方向,木地板的花纹等等。

当然,类似问题在实际操作过程中,会面临具体的问题,比如图片大小不一致等问题。但是这类思路是值得借鉴的。

就比如以下案例是在工业生产中的实践。当机械设备进行作业前拍摄一张图片,作业完毕后再进行一张图片。对比两者的区别,可以排查出设备是否有变化。

通过对变化进行分析,可以自动进行安全提醒。比如出现外壳损毁、螺丝脱落或者意外夹带出作业场地的物料等情况。

通过这个例子告诉大家,技术只是一个功能实现。但是当它被拓展到行业的应用场景中,它会发生很大变化。这个变化就是玩游戏和安全警示的区别。因此,技术不值钱,想法才是生产力。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表