网站首页 > 技术文章 正文
今天想和大家分享的一个例子,很简单,就是对比两张图存在什么差异。
没错,大体就是像“大家一起来找茬”找不同的益智游戏那样。
玩法就是上下两张图片存在不同,让你对比并找出差异点。但是现在来说,这类游戏可以用算法来实现了。现在浮躁的人们,连玩儿都不认真对待了,一心想着那个名次排行榜。
下面就说一下最简单的实现方式。
就拿下面这张图来举例子:
我们仔细观察,就可以看出上下两张图的不同点:
- 左上角的气球不一样,一个椭圆,一个心形。
- 左边小橘猫戴的帽子不一样,底纹颜色不一样。
- 中间蛋糕底座不一样,一个有托,一个没有。
- 最右侧红狗耳朵不一样,一个耷拉着,一个翘起。
首先,我们会面对这么一张图片。可能是游戏截屏截来的,也可能通过接口或其他方式得来的。那么,第一步得把它的图片分割开,变成两张图片才好进行对比。
# 读取图像
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)
这就是“大家来找茬(找不同)”自动排查算法的最简实现方式。
首先,速度上我们肯定不如机器快。其次在识别度上,差异少的时候我们还可以用肉眼判断,当差异多了,我们真的很受限。就比如下面图片中小樱桃的方向,木地板的花纹等等。
当然,类似问题在实际操作过程中,会面临具体的问题,比如图片大小不一致等问题。但是这类思路是值得借鉴的。
就比如以下案例是在工业生产中的实践。当机械设备进行作业前拍摄一张图片,作业完毕后再进行一张图片。对比两者的区别,可以排查出设备是否有变化。
通过对变化进行分析,可以自动进行安全提醒。比如出现外壳损毁、螺丝脱落或者意外夹带出作业场地的物料等情况。
通过这个例子告诉大家,技术只是一个功能实现。但是当它被拓展到行业的应用场景中,它会发生很大变化。这个变化就是玩游戏和安全警示的区别。因此,技术不值钱,想法才是生产力。
- 上一篇: HOG-定向梯度直方图(汽车标识识别)
- 下一篇: OpenCV-Python 轮廓:入门 | 二十一
猜你喜欢
- 2024-10-12 智能监测:皮带输送系统堵料问题的解决方案
- 2024-10-12 Python-OpenCV 10. 图像边缘算法 opencv边缘识别
- 2024-10-12 Net AI学习笔记系列第五章 net教程
- 2024-10-12 深度学习和神经网络——图像读取和显示
- 2024-10-12 十三句Python搞定找茬游戏 找茬游戏规则
- 2024-10-12 「深度学习」手把手教你用PythonOpenCV物体识别-识别水果
- 2024-10-12 python代码实现OpenCV 轮廓近似原理
- 2024-10-12 OpenCV找出图片中的圆并标注圆心 opencv检测圆代码
- 2024-10-12 分享3个干货满满的Python实战项目,点赞收藏
- 2024-10-12 OpenCV(28)——凸包 opencv轮廓凹凸
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)