5

我正在使用ImageHash库来生成图像的感知散列。该库声称能够生成不同大小的散列(64、128、256),但我不知道如何获得 128 散列。

哈希大小由库重新缩放时的图像大小决定,例如:

def average_hash(image, hash_size=8):
    image = image.convert("L").resize((hash_size, hash_size), Image.ANTIALIAS)

这里的默认值为 8(8x8 图像 = 64 像素 -> 灰度 -> 64 位)。

但是,如何创建 128 位哈希?

第二件事,pHash 的默认大小是 32,正如这里所解释的,但稍后将仅计算左上角 8x8 部分的 DCT,因此再次为 64 位。DCT 通过以下方式计算scipy.fftpack

def phash(image, hash_size=32):
    image = image.convert("L").resize((hash_size, hash_size), Image.ANTIALIAS)
    pixels = numpy.array(image.getdata(), dtype=numpy.float).reshape((hash_size, hash_size))
    dct = scipy.fftpack.dct(pixels)
    dctlowfreq = dct[:8, 1:9]
    avg = dctlowfreq.mean()
    diff = dctlowfreq > avg
    return ImageHash(diff)

如何更改哈希大小?
无论使用哪个值,计算都将始终基于左上角的 8x8,因此始终为 64!

发生的奇怪事情是,如果我从 8 大小的 pHash 开始(从头调整图像大小),我得到了 56 位的最终哈希(即计算 7x8 图像的哈希:我不明白为什么这发生在DCT计算中——但我真的知道一点。

4

1 回答 1

0

看起来这是库中的一个错误,此后已被修复。phash 的当前实现如下所示:

def phash(image, hash_size=8, highfreq_factor=4):
    """
    Perceptual Hash computation.
    Implementation follows http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
    @image must be a PIL instance.
    """
    if hash_size < 2:
        raise ValueError("Hash size must be greater than or equal to 2")

    import scipy.fftpack
    img_size = hash_size * highfreq_factor
    image = image.convert("L").resize((img_size, img_size), Image.ANTIALIAS)
    pixels = numpy.asarray(image)
    dct = scipy.fftpack.dct(scipy.fftpack.dct(pixels, axis=0), axis=1)
    dctlowfreq = dct[:hash_size, :hash_size]
    med = numpy.median(dctlowfreq)
    diff = dctlowfreq > med
    return ImageHash(diff)

您会注意到这正确地使用了hash_size而不是硬编码的值。

于 2019-06-25T04:24:49.057 回答