使用Opencv构建一个简单的图像相似检测器(MSE、SSIM)
介紹
? ? ? ?作為人類(lèi),我們通常非常善于發(fā)現(xiàn)圖像中的差異。例如,常見(jiàn)的游戲——兩張圖像找不同?,F(xiàn)在讓我們玩下這個(gè)游戲吧,首先讓我們看看上面的圖像,三十秒內(nèi)看看是否能夠從中找出有什么不同的地方。
? ? ? ?答案:水果、冰淇淋和飲料的顏色發(fā)生了明顯改變,窗簾、太陽(yáng)也發(fā)生了改變,這是不是很簡(jiǎn)單呢?如果有補(bǔ)充的答案,請(qǐng)?jiān)诹粞蕴幗o出哦!
? ? ? ?這類(lèi)問(wèn)題對(duì)于人類(lèi)來(lái)說(shuō)看起來(lái)是一件輕而易舉的事情,但是,對(duì)于計(jì)算機(jī)來(lái)說(shuō),這可不是一件容易的事兒。這是由于計(jì)算機(jī)只能從我們訓(xùn)練它的模型中學(xué)習(xí),才最終具有這類(lèi)能力。目前有很多很好的模型可以對(duì)批量圖像進(jìn)行分類(lèi),比如TensorFlow和Keras等開(kāi)源工具。
? ? ? ?借助于這類(lèi)開(kāi)源工具庫(kù),計(jì)算機(jī)視覺(jué)領(lǐng)域的研究得以高發(fā)展?,F(xiàn)在我們也可以借助于這類(lèi)工具箱創(chuàng)建非常復(fù)雜的模型以及解決比較復(fù)雜的問(wèn)題,例如kaggle:Animals-10,該數(shù)據(jù)集包含數(shù)十種不同類(lèi)型動(dòng)物的圖像以及非動(dòng)物圖像。所要做的就是創(chuàng)建一個(gè)模型來(lái)預(yù)測(cè)圖片是哪種類(lèi)型的動(dòng)物。
MSE和SSIM
? ? ? ?然而,上述任務(wù)較為簡(jiǎn)單,比如常見(jiàn)的手寫(xiě)體數(shù)字識(shí)別MNIST等,一般也都能取得很高的精度。在這里,我想增加一點(diǎn)難度,創(chuàng)建一個(gè)圖像分類(lèi)器,以分辨出兩個(gè)圖像的相似程度。并且,不依賴(lài)任何復(fù)雜的工具庫(kù),如TensorFlow、Keras等。本文采用傳統(tǒng)的機(jī)器學(xué)習(xí)方法,這里從中選取兩種方法,用于查找圖像是否與另一個(gè)圖像相似。這兩種方法分別為均方誤差(MSE)、結(jié)構(gòu)相似度指數(shù)(SSIM)。
MSE
SSIM
? ? ? ?上述公式看起來(lái)非常復(fù)雜,但不要害怕。借助于NumPy,可以相當(dāng)容易地計(jì)算出MSE;另外,由于SSIM是Sci-Kit圖像庫(kù)的內(nèi)置方法的一部分,因此也可以很容易地計(jì)算出SSIM。
? ? ? ?在進(jìn)行編碼之前,這里先對(duì)這兩種方法予以簡(jiǎn)單的說(shuō)明。MSE將計(jì)算正在比較的兩個(gè)圖像的每個(gè)像素之間的均方誤差。而SSIM做的事情與MSE恰好相反,尋找像素值的相似之處。?也就是,如果兩個(gè)圖像中的像素排列相似或具有相似的像素密度值。MSE方法遇到的一個(gè)的問(wèn)題是其結(jié)果往往具有任意大的值,因此很難給出標(biāo)準(zhǔn)的評(píng)判標(biāo)準(zhǔn)。一般而言,MSE越高,表明兩張圖像的相似程度越低。如果圖像之間的MSE值是隨機(jī)值,則很難說(shuō)明二者是否相似。另一方面,SSIM將所有內(nèi)容歸一化到-1~1的范圍內(nèi)(很難得到小于0的分?jǐn)?shù))。得分為1表示二者非常相似,得分為-1表示二者非常不同?;诖?#xff0c;SSIM相較于MSE而言是一個(gè)更好的衡量指標(biāo)。
實(shí)現(xiàn)
? ? ? ?現(xiàn)在使用代碼實(shí)現(xiàn)上述想法:
加載必要的庫(kù):
? ? ? ?本文使用常見(jiàn)的圖像處理工具箱OpenCV實(shí)現(xiàn)圖像的讀取和編輯。如果你對(duì)其它圖像處理工具箱熟悉,你也可以使用自己熟悉的工具箱完成此類(lèi)操作,比如matplotlibden。
編寫(xiě)MSE公式:
? ? ? ?使用Numpy操作起來(lái)很簡(jiǎn)單吧!
? ? ? ?由于SSIM已經(jīng)通過(guò)skimage導(dǎo)入,因此無(wú)需進(jìn)行手動(dòng)編碼。現(xiàn)在創(chuàng)建一個(gè)比較函數(shù),該函數(shù)的輸入為兩個(gè)圖像,分別計(jì)算二者的MSE和SSIM,并展示計(jì)算結(jié)果。
? ? ? ?下面的三個(gè)步驟可以使用for循環(huán)一次完成,但是為了更容易地理解,這里不使用for循環(huán)編寫(xiě)代碼,將其分解為三個(gè)部分:
? ? ? ?首先,加載保存在目錄中的圖像。其次,必須確保它們的大小相同,否則會(huì)出現(xiàn)尺寸不匹配的錯(cuò)誤。問(wèn)題是對(duì)其進(jìn)行尺寸變換操作會(huì)導(dǎo)致圖像失真,所以在找到比較合適的尺寸數(shù)字之前,可以嘗試快速搜索方法,尺寸大小按照一定的規(guī)律設(shè)置,不斷實(shí)驗(yàn)以找到最終比較合適的尺寸。接下來(lái)我們?cè)賹?shí)現(xiàn)一個(gè)功能,以便于看到測(cè)試圖像是什么樣子的。
? ? ? ?現(xiàn)在通過(guò)比較兩個(gè)一樣的圖像來(lái)測(cè)試并查看MSE和SSIM是否正常工作。如果它有效,那么我們應(yīng)該得到MSE值為0和SSIM值為1的結(jié)果。
? ? ? ?從中可以看到,代碼正確,結(jié)果與猜想的一致!
? ? ? ?現(xiàn)在計(jì)算機(jī)就可以判斷比較的兩張圖像是否相同了。為簡(jiǎn)單起見(jiàn),我將三張狗的圖像與自己以及三張貓的圖像進(jìn)行比較。
三只不同的狗比較
三只不同的貓比較
? ? ? ?下面看看兩種算法的性能比較。正如所看到的那樣,MSE的值變化很大,因此該值很難說(shuō)明其表達(dá)的意思是什么。但從SSIM的結(jié)果看出,可以看到狗2和狗3相對(duì)于其他狗的圖像最為相似。從視覺(jué)上來(lái)講,我同意這個(gè)結(jié)果,因?yàn)閮芍还返亩浞浅O?。但我還會(huì)認(rèn)為狗1和狗3會(huì)有更高的SSIM值,因?yàn)槎叩淖藙?shì)也很相似。實(shí)際上,在圖像沒(méi)有進(jìn)行灰度處理之前,狗2和狗3在鼻子區(qū)域周?chē)蓄?lèi)似的白色毛皮,而狗1沒(méi)有。這很可能是狗2和3具有比狗1更高的SSIM值的原因。對(duì)于貓來(lái)說(shuō),這就有點(diǎn)困難。貓1和貓2具有相似的形狀,并且圖像是從相似的距離拍攝的,但貓2和貓3具有相似的皮毛顏色。
? ? ? ?這里我想進(jìn)行的測(cè)試只有兩個(gè):一個(gè)是狗和貓的相似性,第二個(gè)是每個(gè)動(dòng)物與原始源代碼附帶的門(mén)圖的相似性。
? ? ? ?正如所預(yù)料的那樣,狗和貓是相似的,這點(diǎn)與與無(wú)生命的物體相比呈鮮明的對(duì)比,如侏羅紀(jì)公園入口門(mén)。狗和貓對(duì)門(mén)的圖像具有較高的SSIM值,唯一原因在于圖像都經(jīng)過(guò)了尺寸縮放和灰度處理。
? ? ? ?在調(diào)整圖像大小和重新配置時(shí),OpenCV并不是最好的。一般而言,TensorFlow是最好的,TensorFlow也最適合批量圖像。
? ? ? ?之后,我也將使用TensorFlow處理kaggle Animal-10數(shù)據(jù)集,來(lái)實(shí)現(xiàn)一個(gè)完整的圖像分類(lèi)器。
作者信息
Iftekher Mamun, 機(jī)器學(xué)習(xí)
本文由阿里云云棲社區(qū)組織翻譯。
文章原標(biāo)題《Image Classification using SSIM
Simple Image Classifier with OpenCV》,譯者:海棠,審校:Uncle_LLD。
文章簡(jiǎn)譯,更為詳細(xì)的內(nèi)容,請(qǐng)查看原文。
總結(jié)
以上是生活随笔為你收集整理的使用Opencv构建一个简单的图像相似检测器(MSE、SSIM)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ELK logstash 配置自定义字段
- 下一篇: 小猴子吃桃子