轉載請註明出處python
在重複圖識別領域,對於識別肉眼相同圖片,感知哈希效果是很魯棒的。上一篇文章 【PHash】更懂人眼的感知哈希 介紹的PHash識別效果很好,可是它有一個缺點,只關注低頻信息,並無關注圖片的空間信息,極端狀況就可能出現徹底不一樣的兩張圖片,phash值很近。而WHash利用小波變換不只重點關注低頻信息,同時也關注圖片的空間信息。算法
def whash(image, hash_size = 8): #check assert hash_size & (hash_size-1) == 0, "hash_size is not power of 2" image_scale = max(2**int(numpy.log2(min(image.size))), hash_size) ll_max_level = int(numpy.log2(image_scale)) level = int(numpy.log2(hash_size)) assert level <= ll_max_level, "hash_size in a wrong range" #預處理 image = image.convert("L").resize((image_scale, image_scale), Image.ANTIALIAS) pixels = numpy.asarray(image) / 255. # 小波變換,haar coeffs = pywt.wavedec2(pixels, 'haar', level = ll_max_level) # 去掉最低頻 coeffs[0] *= 0 # 小波逆變換 dwt_low = pywt.waverec2(coeffs[:level+1], 'haar') #二值化,中值 med = numpy.median(dwt_low) diff = dwt_low > med return diff
WHash算法其實也比較簡單,主要利用了小波變換獲取低頻信息,主要就是下面3步:.net
其中預處理就是縮放+轉灰度圖,而二值化跟PHash同樣,都是利用中值看成基準值。
這裏的重點在於小波變換,下面簡單直觀的給你們看下小波變換到底是什麼?3d
在圖片上進行小波變換,能夠把圖片的低頻跟高頻信息拆分,以下所示:
code
其中,A是低頻信息,H是水平高頻信息,V是垂直高頻信息、D是對角高頻信息。blog
在實際運用,並非只進行一次低頻高頻拆分,會進行屢次,以下圖所示:
在WHash這裏,咱們只是拿最右邊那張圖片,左上角1/4信息進行二值化,其餘信息都是拋棄的。
在WHash裏面,小波變換並非單純的拿到了圖片的低頻信息,並且還保存了自己圖片的空間信息,因此它實際使用過程當中,比PHash魯棒一些。固然若是PHash對只對低頻部分進行DCT逆變換,而後再進行二值化,也是能夠考慮上空間信息的,跟WHash同樣的道理。圖片