1. 程式人生 > >相似圖片搜尋原理

相似圖片搜尋原理

給定一張圖片,怎樣在網際網路上找出和它近似的圖片?

可以使用Google的相似圖片搜尋功能,匹配程度相當高。

那麼,計算機是採用怎樣的技術判定兩張圖片的相似程度的呢?方法有很多。

在這裡,我們從圖片的輪廓和色彩兩方面入手,做一個簡單的演算法實現,重在原理呈現。

輪廓篇

  圖片的輪廓是判斷圖片相似性的最主要影響因素,那麼怎樣確定圖片的主要輪廓呢?實際上,若將圖片轉化為黑白圖後再觀察就容易的多,黑白交界處就是所謂輪廓。

如需得到黑白圖,首先排除色相干擾,將RGB轉化為灰度,生成灰度值矩陣。

但是灰度值中包含的噪音較多,因此最好再做一次離散餘弦變換,並只保留其中的低頻部分,這樣可以提高不少精確度。經過變換後得到的依然是一個灰度值矩陣

那麼哪些畫素點轉化為黑點,哪些轉化為白點呢?我們需要確定一個閾值,比閾值大的轉化為白點,比閾值小的轉化為黑點。它必須保證閾值以上的灰度值分佈要儘可能地緊密,閾值以下的灰度值分佈也要儘可能地緊密,同時閾值以上值的總體分佈和閾值以下值的總體分佈兩者之間要儘可能疏遠,這樣才能使輪廓精確。

這時,我們將DCT後的灰度值矩陣中的每個數字與閾值做比較大小,便得到了一個0-1特徵矩陣。

用平均值做閾值其實是一種不精確的方法,有一種比較好的方法叫做Otsu’s method

再從特徵矩陣轉化到雜湊碼,這個就很簡單了。

如果我們把待比較的圖片壓縮到相同的尺寸,同時保證組合生成雜湊碼的順序相同,則得到的雜湊碼即為輪廓指紋,兩者的海明距離越小則兩張圖片輪廓構成越相似

色彩篇

  色彩是圖片的重要特徵,我們可以把圖片中不同顏色的畫素點總數統計出來,作為相似搜尋的判據。上述資訊若轉化為直方圖就很直觀。  

每種顏色都是由紅綠藍按照不同的比例混合而成的,一共有256^3種顏色,但是這個資料量太大。我們可以將256分成4段:0-6364-127128-191192-255,這樣所有的顏色被歸類到4^3=64種。準備一個大小為64map容器,64種顏色各自對應一個鍵,這樣就可以統計了。最後,我們可以依次取出map中的值,按正比例轉化到0-F的十六進位制數,再串聯起來就得到了64位雜湊碼。

如果把待比較的圖片壓縮到相同的尺寸,再使map中的鍵排列保持一致,則得到的雜湊碼即為色彩指紋,兩者的海明距離越小則兩張圖片色彩構成越相似

    用Java實現後進行了比較簡單的測試,發現這兩個方法綜合起來用,對縮放和一些“淡妝”濾鏡的識別度比較好,因此可以勝任簡單的原圖-縮圖和原圖-PS圖互相查詢。同時,誤差也是存在的。我個人的觀點,在壓縮圖片的那一部分,變形導致損失的資訊較大,乃是誤差的根源。

    經過旋轉處理的原圖和裁剪掉外圍的原圖,都被判定為和原圖相差很大。這就暴露了魯棒性上的不足。我認為在原理不變的前提下,此一類原圖變形問題是可以通過修正原有演算法在一定程度上解決的。

    而面對用google搜圖得到的近似圖(事實上肉眼也證實確實是近似圖),這個演算法就真的不夠用了。我想要達到接近肉眼的識別能力,一個僅僅在訊號資料層面進行處理的演算法是不夠的。