jetson nano opencv 打开 CSI摄像头_opencv找图片中的不同

滑稽研究所 8ca5a31f257a6cab9e11990a11437556.gif

opencv找图片中的不同

哈喽,大家好呀,我是滑稽君。本期我们想要识别下面图片中的不同之处,并标记出来。下图中除了比较明显的app的位置变化之外,4g信号的使用情况也不同(箭头一明一暗)。

ade525e3c27396f7f437d85f9404d7b0.png

4a12a75e07ef4c7cb607782a924aa31f.png

两个图片比较的先决条件必须处于同一环境,如我们截取定点监控摄像头的录像,在不同时间任意截取两张图片比较都是满足条件的。因为它拍摄的是同一地点,变化的只有行人和车辆。我们的素材也是在同一屏幕,不同情况下截取。

a18889f31a27e0796e72d3dd4040dc19.gif

视频讲解:

我们先看源代码,然后跟着不同阶段的图片处理结果来过一遍思路。

源代码:

import cv2import numpy as npimg = cv2.imread('images/3.png',0)imgx = cv2.imread('images/3.png')img2 = cv2.imread('images/4.png',0)imgy = cv2.imread('images/4.png')#缩放到合适大小img=cv2.resize(img,None,fx=0.4,fy=0.4)imgx=cv2.resize(imgx,None,fx=0.4,fy=0.4)img2=cv2.resize(img2,None,fx=0.4,fy=0.4)imgy=cv2.resize(imgy,None,fx=0.4,fy=0.4)print(img.shape,img2.shape)imgBlur = cv2.GaussianBlur(img, (7, 7), 1)imgBlur2 = cv2.GaussianBlur(img2, (7, 7), 1)# 获取图形轮廓imgCanny = cv2.Canny(imgBlur, 50, 80)imgCanny2 = cv2.Canny(imgBlur2, 50, 80)#二值化操作kernel = np.ones((5, 5), np.uint8)ref = cv2.threshold(imgCanny, 10, 255, cv2.THRESH_BINARY_INV)[1]ref2 = cv2.threshold(imgCanny, 10, 255, cv2.THRESH_BINARY)[1]ref3 = cv2.threshold(imgCanny2, 10, 255, cv2.THRESH_BINARY_INV)[1]#与运算img4 = cv2.bitwise_and(imgCanny2,imgCanny2,mask=ref)img5 = cv2.bitwise_and(ref2,ref2,mask=ref3)res1 = cv2.add(img4,img5)imgd = cv2.dilate(res1, kernel, iterations=2)img1 = imgx.copy()def getContours(img):    contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)    # contours接受识别出的所有轮廓    # hierarchy各个轮廓之间的关系,我们本次用不到。    for cnt in contours:        area = cv2.contourArea(cnt)        # 这个输出各个轮廓的面积        #print(area)        #if 0 <= area <=6000 :        # 给我们的轮廓描边        print(area)        cv2.drawContours(img1, cnt, -1, (0, 255, 0), 2)        # 轮廓的长度        peri = cv2.arcLength(cnt, True)        # 找出轮廓的突变值        approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)        # approx找到的是一个轮廓有几个突变值,有几个角就会有几个突变值        # 返回的是一个list,输出他的长度,就可以知道到底有几个角        print(len(approx))        x, y, w, h = cv2.boundingRect(approx)  # 得到包覆此轮廓的最小正矩形        # x,y为包覆此轮廓的最小正矩形的左上角的坐标。        # w, h则为长宽,计算长宽的比值判断矩形。        # if 730 > x > 70 and 270 < y < 350:        cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 0, 255), 2)getContours(imgd)#图片拼接操作imga = np.hstack((img1,imgy))imgb = np.hstack((imgCanny2,ref))imgc = np.hstack((ref2,ref3))imgd = np.hstack((img4,img5))cv2.imshow("1", imga)cv2.imshow("2", imgb)cv2.imshow("3", imgc)cv2.imshow("4", imgd)cv2.imshow("8", res1)# 设置窗口显示时间,0为永远。单位是ms。cv2.waitKey(0)

两张图片二值化之后,值取一正一反,注意需要做两组。为什么两组?

c2d1bbfe643a72647aced0b3393ec8b6.png

第一次我们以左侧为原图,进行一次掩膜操作,右图作为mask。我们知道白色区域是我们希望保留的部分,覆盖之后,位置没有变的app轮廓被mask填充消失不见,那么得到下图的左侧部分。

但是我们发现一个问题,第2行和第4行app的位置变换没有被检测到。这是因为我们的原图app移动后的空缺处为黑色,而mask对应的位置即使有黑色轮廓也与背景色融合。无法被检测出来。因此我们需要进行一次反向取值。

1cc6473b2b7d8abd395d6d15e5cff119.png

第二次操作反向取值之后我们得到上图的右侧部分。

                 d1acf1653761d91ed9d2a357ec2c2ff9.png

那么在两次操作之后我们对得到的结果进行一次加运算得到下图。我们可以看到在右上角的位置有片白色区域,那就是4g图标处的差异也被检测出来了。这意味着我们不仅可以检测到位置变换,还可以检测到图形的变换。也就是说如果位置不动,仅对调app的位置,那么logo和app名称的变化也是可以检测到的。

fc298b1866a067c19c68c2e287b0bae3.png

我们对上图进行一次膨胀操作,以便程序可以更轻松的捕捉到我们的轮廓。在捕捉到轮廓后,我们对进行描边,并加上最小外接正矩形。

227bb9224301cab5f089d688e334769a.png

最终结果:

8e78065536a6119d422be00e50a08956.png

我们完成了位置检测(app位置的移动)和图形检查(4g图标的不同)。希望这篇文章对你理解opencv里的mask有帮助。

其他素材:

c7f1947d877c21ec9346d1846e51c986.png

这里因为不需要关注细节处理,我们把膨胀操作去掉。在不同素材的情况下,我们灵活运用。

f98308b591be5e7da96129ef9386b662.gif ❂ END

 opencv的掩膜操作,与运算和加运算在一起碰撞出了怎样的火花?

5f92fa4570ba26586ca5640b08711c86.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值