還在用肉眼找不同嗎?這個(gè)技術(shù)輕松搞定
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
本文轉(zhuǎn)自:AI算法與圖像處理
我想應(yīng)該很多人都玩過騰訊的這款游戲《大家來找茬》,想當(dāng)年不知道多少人用鼠標(biāo)對(duì)著美女圖一頓輸出,就是找不到哪里不一樣。
今天我們要用到圖像技術(shù)可以應(yīng)用到這個(gè)上面。

今天,我們將使用擴(kuò)展ssim(結(jié)構(gòu)相似性索引)方法,以便使用OpenCV和python可視化圖像之間的差異。具體來說,我們將在兩個(gè)輸入圖片的不同處繪制邊界框。
為了計(jì)算兩張圖片的不同,我們將使用結(jié)構(gòu)相似性索引(由wang等人首次提出)。在他們的2004年論文中,圖像質(zhì)量評(píng)估:從可視化誤差到結(jié)構(gòu)相似性。該方法已經(jīng)在scikit-image庫中應(yīng)用于圖像處理。
https://ece.uwaterloo.ca/~z70wang/publications/ssim.pdf
要去學(xué)習(xí)的技巧是我們?nèi)绾稳?zhǔn)確確定圖片不同點(diǎn)的坐標(biāo)位置(x,y)。
要實(shí)現(xiàn)這一點(diǎn),首先我們要確定系統(tǒng)已經(jīng)安裝好python、OpenCV、scikit-image和imutils。
你可以使用下面的OpenCV安裝教程學(xué)習(xí)如何在系統(tǒng)上配置和安裝python和OpenCV。
https://www.pyimagesearch.com/opencv-tutorials-resources-guides/
如果你還沒安裝或更新scikit-image包,你可以使用下面的操作:
pip3 install --upgrade scikit-image同樣的,如果你還為安裝或更新imutils,你可以使用下面的操作:
pip3 install --upgrade imutils現(xiàn)在我們的系統(tǒng)已經(jīng)準(zhǔn)備好了,可以繼續(xù)往下操作了。
思考:你能分辨出下面這兩幅圖片的區(qū)別嗎?

你可能會(huì)馬上注意到這個(gè)差異,或者說花費(fèi)一點(diǎn)時(shí)間。不管怎樣,這都說明了比較圖片的差異是一個(gè)重要的方面——有時(shí)圖片的差異是微小的——這將導(dǎo)致肉眼難以立刻發(fā)現(xiàn)這些差異(文章的后面會(huì)有一個(gè)這樣子的例子)。
為什么計(jì)算圖片的差異如此重要?
http://www1.icsi.berkeley.edu/~sadia/papers/phishzoo-icsc_final.pdf
# 導(dǎo)入必要的包from skimage.measure import compare_ssimimport argparseimport imutilsimport cv2# 構(gòu)造解析參數(shù)ap = argparse.ArgumentParser()ap.add_argument("-f","--first",required=True,help="first input image")ap.add_argument("-s","second",required=True,help="second")args = vars(ap.parse_args())
# 導(dǎo)入圖片imageA = cv2.imread(args["--first"])imageB = cv2.imread(args["--second"])# 把圖片轉(zhuǎn)換為灰度圖grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

然后我們將其轉(zhuǎn)為灰度圖(第6-7行)

接下來,開始計(jì)算兩會(huì)在那個(gè)圖片之間的結(jié)構(gòu)相似性索引(SSIM)
# 計(jì)算兩張圖片的結(jié)構(gòu)相似性索引# 確保差分圖片(score, diff) = compare_ssim(grayA, grayB, full=True)diff = (diff*255).astype("uint8")print("SSIM:{}".format(score))
在第3行中使用scikit-image中的compare_ssim函數(shù),我們計(jì)算得到一個(gè)score和差分圖片diff
現(xiàn)在,找到這些輪廓,這樣我們可以在被標(biāo)識(shí)為“不同”的區(qū)域畫出矩形。
# 閾值分割差分圖像,然后查找輪廓以獲得兩個(gè)輸入圖片的不同區(qū)域thresh = cv2.threshold(diff, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)
在第2-3行中,我們使用cv2.THRESH_BINARY_INV 和 cv2.THRESH_OTSU來閾值處理我們的差分圖片——這兩個(gè)設(shè)置使用豎線或符號(hào) “|” 來同時(shí)應(yīng)用。
https://docs.opencv.org/trunk/d7/d4d/tutorial_py_thresholding.html
中文版的:cv2.threshold參數(shù)詳細(xì)說明如下:
https://blog.csdn.net/sinat_21258931/article/details/61418681

# 遍歷輪廓for c in cnts:# 計(jì)算輪廓的邊界框,然后在兩張輸入圖片中代表圖片不同點(diǎn)的區(qū)域繪制邊界框(x, y, w, h) = cv2.boundingRect(c)cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), 2)cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), 2)# 顯示輸出圖片cv2.imshow("Original", imageA)cv2.imshow("Modified", imageB)cv2.imshow("Diff", diff)cv2.imshow("Thresh", thresh)cv2.waitKey(0)

python3 image_diff.py --first images/original_02.png --second images/modified_02.png如下圖所示,安全芯片和賬戶持有者的姓名都被刪除。

再嘗試另一個(gè)例子,一張支票。
python3 image_diff.py --first images/original_03.png --second images/modified_03.png
名字被刪除 支票編號(hào)被刪除 日期旁邊的符號(hào)被刪除 最后的名字被刪除
今天的文章,我們學(xué)習(xí)了如何使用OpenCV、python和scikit-image的結(jié)構(gòu)相似性所有(SSIM)來計(jì)算圖片的不同點(diǎn)?;趫D片的不同點(diǎn),我們也學(xué)習(xí)了如何標(biāo)記和可視化兩張圖片中的不同區(qū)域,后臺(tái)回復(fù)“找不同”獲取源碼和示例圖片
更多關(guān)于SSIM的內(nèi)容,可以參考https://www.pyimagesearch.com/2014/09/15/python-compare-two-images/和scikit-image的文檔https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.compare_ssim
https://www.pyimagesearch.com/2017/06/19/image-difference-with-opencv-and-python/
交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

