本文的代碼可在微信公衆號「01二進制」後臺回覆「檢測圖像類似度」得到。html
最近在作一個海量圖片檢索的項目,能夠簡單的理解爲「以圖搜圖」,這個功能一開始是搜索引擎帶火的,可是後來在電商領域變得很是實用。在製做這個圖片檢索的項目前,筆者搜索了一些資料,現在項目臨近結尾,便在這裏作一些簡單的分享。本文先介紹圖像檢索最基礎的一部分知識——利用 Python 檢測圖像類似度。算法
提到檢測「某某」的類似度相信不少人第一想法就是將須要比較的東西構建成兩個向量,而後利用餘弦類似度來比較兩個向量之間的距離,這種方法應用很普遍,例如比較兩個用戶興趣的類似度、比較兩個文本之間的類似度。可是這個方法在比較圖片類似度的時候用到的並很少,緣由我以後再說,這裏先來介紹下另外兩個概念——圖像指紋和漢明距離。微信
圖像指紋和人的指紋同樣,是身份的象徵,而圖像指紋簡單點來說,**就是將圖像按照必定的哈希算法,通過運算後得出的一組二進制數字。**以下圖所示:函數
在給定的輸入的圖像中,咱們可使用一個散列函數, 並基於圖像視覺上的外觀計算它的「圖像散列」值,類似的頭像,它的散列值應該也是類似的。構建圖像指紋的算法被稱爲感知哈希算法(Perceptual Hash Algorithm)。學習
經過上述對圖像指紋的描述咱們知道了能夠利用感知哈希算法將圖片轉換成某種字符串,而比較字符串有一種名爲漢明距離的表示方法。如下定義摘自維基百科:搜索引擎
在信息論中,兩個等長字符串之間的漢明距離(英語:Hamming distance)是兩個字符串對應位置的不一樣字符的個數。換句話說,它就是將一個字符串變換成另一個字符串所須要替換的字符個數。cdn
一般用漢明距離來衡量兩張圖片的差別,漢明距離越小,則表明類似度越高。漢明距離爲0,即表明兩張圖片徹底同樣。htm
經常使用的感知哈希算法有三個,分別是平均哈希算法(aHash)、感知哈希算法(pHash)、差別值哈希算法(dHash)。至於這三種哈希算法的介紹和比較不少博客都有寫,並且不少庫都支持直接計算哈希值,調用一下相關函數就能夠了。這裏就很少說了,推薦一篇文章👉 《圖像類似度中的Hash算法》blog
代碼可在微信公衆號「01二進制」後臺回覆「檢測圖像類似度」得到索引
三種哈希算法的實現代碼以下:
固然,你也能夠選擇安裝 ImageHash 庫,而後調用相應的hash函數來實現計算。
因此看到這對於比較兩張圖片的類似度咱們就有了一個簡單的想法了,只要經過感知哈希算法得到圖像的圖像指紋,而後比較兩個哈希值之間的漢明距離就能夠了。
詳細的步驟,阮一峯介紹了一個簡單的圖片搜索原理,可分爲下面幾步:
這種方法對於尋找 如出一轍 的圖片是有效的,可是搜索「類似圖片」的效果不好,也不能局部搜索,所以一般應用在 「檢測圖片是否侵權」 上。如今諸如谷歌識圖、百度識圖幾乎都是採用深度學習的方式進行類似性檢索,這個下篇文章介紹。
最後咱們來討論下爲何不使用餘弦類似度來檢測圖片的類似度。開篇咱們就說過若是須要用餘弦類似度來衡量類似性,咱們須要先構造兩個向量。一般狀況下咱們會將圖片轉化爲像素向量(基於像素點灰度值的頻次),從而計算兩個圖片的類似度,這種作法其實就是計算兩個圖片的直方圖的類似度,然而這樣就只保留了像素的頻次信息,丟掉了像素的位置信息,信息損失太大,只在某些場景下適用。用餘弦類似度表示圖片類似度的代碼一樣能夠微信公衆號「01二進制」後臺回覆「檢測圖像類似度」得到。
本文介紹的方法都是經過非深度學習的手段來檢測圖像的類似度,雖然理解起來都很容易,可是每種方法都有侷限性。想要製做一個圖像檢索系統雖然第一步都是比較圖像的類似度,但現現在大多數都是經過深度學習的方法提取出圖像特徵,而後再進行比較,準確率大大提高。以後我將會講述如何經過深度學習抽取圖像特徵的方式來比較圖片的類似度。
因爲能力有限,在整理描述的過程當中不免會有些錯誤,若有建議,能夠留言區批評指正🙏