pHash与NumPy数组互转方法及旋转/翻转图像哈希匹配优化方案咨询
pHash与NumPy数组互转方法及旋转/翻转图像哈希匹配优化方案咨询
我来帮你解答这两个问题,结合实际代码和实践经验给出方案:
一、pHash与NumPy数组的互转方法
imagehash库的Hash对象可以很方便地和NumPy数组互相转换,具体代码如下:
1. 将pHash转换为NumPy数组
首先计算图像的pHash,然后直接转换为数组并重塑为8x8的矩阵(因为默认pHash是64位,对应8x8的特征矩阵):
import imagehash from PIL import Image import numpy as np # 计算原始图像的pHash img = Image.open("your_image.jpg") original_phash = imagehash.phash(img) # 转换为8x8的NumPy数组 hash_array = np.array(original_phash).reshape(8, 8)
2. 将NumPy数组转回pHash
把处理后的数组展平为二进制字符串,再转换为整数,最后构建回Hash对象:
# 展平数组并转为二进制字符串 flattened_bits = hash_array.flatten() binary_str = ''.join(str(bit) for bit in flattened_bits) # 转回pHash对象 recovered_phash = imagehash.Hash(int(binary_str, 2), size=8)
这样就能完成两者的互转,之后你就可以用np.flip、np.rot90等函数对数组进行翻转/旋转变换了。
二、搜索旋转/翻转图像的更优方案
除了你提到的哈希数组变换思路,还有几种更高效的实践方案:
预计算变换哈希并批量存储:
对于每个图像,预先计算原始、水平翻转、垂直翻转、旋转90°/180°/270°这6种常见变换对应的pHash,将这些哈希和原图像关联存储。搜索时直接匹配目标哈希与这些预计算的哈希,这样查询速度极快,唯一的代价是增加少量存储(每个图像多存5个64位整数,几乎可以忽略)。直接在哈希层面生成变换后的哈希:
如果你不想预存,也可以实时从原始哈希生成变换后的哈希。比如:# 生成水平翻转后的哈希 flipped_array = np.flip(hash_array, axis=1) flipped_phash = imagehash.Hash(int(''.join(str(bit) for bit in flipped_array.flatten()), 2), size=8) # 生成旋转90°后的哈希 rotated_array = np.rot90(hash_array) rotated_phash = imagehash.Hash(int(''.join(str(bit) for bit in rotated_array.flatten()), 2), size=8)这种方式比重新加载图像并计算哈希快得多,因为只需要处理8x8的小矩阵。
使用旋转鲁棒性更强的哈希算法:
如果你希望从根源上减少变换后的哈希差异,可以考虑使用imagehash.dhash(差异哈希),它对小角度旋转和翻转的鲁棒性比pHash更好;或者自己实现基于圆形区域的感知哈希,这类哈希天生具备旋转不变性。
备注:内容来源于stack exchange,提问作者Übend
相关产品推荐
相关产品推荐

