背景

WHash算法

  • WHash算法如下:
    【WHash】更有空间感的感知哈希-LMLPHP
    下面附上源代码,代码很短,也可以先忽略:
  • python源码如下:
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步:

  • 图片预处理(resize,转灰度图)
  • 小波变换
  • 二值化

其中预处理就是缩放+转灰度图,而二值化跟PHash一样,都是利用中值当作基准值。
这里的重点在于小波变换,下面简单直观的给大家看下小波变换究竟是什么?

直观理解小波变换

在图片上进行小波变换,可以把图片的低频跟高频信息拆分,如下所示:
【WHash】更有空间感的感知哈希-LMLPHP

其中,A是低频信息,H是水平高频信息,V是垂直高频信息、D是对角高频信息。

在实际运用,并不是只进行一次低频高频拆分,会进行多次,如下图所示:
【WHash】更有空间感的感知哈希-LMLPHP
在WHash这里,我们只是拿最右边那张图片,左上角1/4信息进行二值化,其他信息都是抛弃的。
在WHash里面,小波变换并不是单纯的拿到了图片的低频信息,而且还保存了本身图片的空间信息,所以它实际使用过程中,比PHash鲁棒一些。当然如果PHash对只对低频部分进行DCT逆变换,然后再进行二值化,也是可以考虑上空间信息的,跟WHash一样的道理。

12-12 17:40