天天看點

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

滑稽研究所

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

opencv找圖檔中的不同

哈喽,大家好呀,我是滑稽君。本期我們想要識别下面圖檔中的不同之處,并标記出來。下圖中除了比較明顯的app的位置變化之外,4g信号的使用情況也不同(箭頭一明一暗)。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同
jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

兩個圖檔比較的先決條件必須處于同一環境,如我們截取定點監控攝像頭的錄像,在不同時間任意截取兩張圖檔比較都是滿足條件的。因為它拍攝的是同一地點,變化的隻有行人和車輛。我們的素材也是在同一螢幕,不同情況下截取。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

視訊講解:

我們先看源代碼,然後跟着不同階段的圖檔處理結果來過一遍思路。

源代碼:

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)
           

兩張圖檔二值化之後,值取一正一反,注意需要做兩組。為什麼兩組?

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

第一次我們以左側為原圖,進行一次掩膜操作,右圖作為mask。我們知道白色區域是我們希望保留的部分,覆寫之後,位置沒有變的app輪廓被mask填充消失不見,那麼得到下圖的左側部分。

但是我們發現一個問題,第2行和第4行app的位置變換沒有被檢測到。這是因為我們的原圖app移動後的空缺處為黑色,而mask對應的位置即使有黑色輪廓也與背景色融合。無法被檢測出來。是以我們需要進行一次反向取值。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

第二次操作反向取值之後我們得到上圖的右側部分。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

那麼在兩次操作之後我們對得到的結果進行一次加運算得到下圖。我們可以看到在右上角的位置有片白色區域,那就是4g圖示處的差異也被檢測出來了。這意味着我們不僅可以檢測到位置變換,還可以檢測到圖形的變換。也就是說如果位置不動,僅對調app的位置,那麼logo和app名稱的變化也是可以檢測到的。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

我們對上圖進行一次膨脹操作,以便程式可以更輕松的捕捉到我們的輪廓。在捕捉到輪廓後,我們對進行描邊,并加上最小外接正矩形。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

最終結果:

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

我們完成了位置檢測(app位置的移動)和圖形檢查(4g圖示的不同)。希望這篇文章對你了解opencv裡的mask有幫助。

其他素材:

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

這裡因為不需要關注細節處理,我們把膨脹操作去掉。在不同素材的情況下,我們靈活運用。

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

❂ END

 opencv的掩膜操作,與運算和加運算在一起碰撞出了怎樣的火花?

jetson nano opencv 打開 CSI攝像頭_opencv找圖檔中的不同

繼續閱讀