import math import unittest # 正则化图像 def regularizeImage(img, size = (32, 32)): return img.resize(size).convert('L') # 获得图像像素矩阵 def getMatrix(img): matrix = [] size = img.size for i in range(size[1]): pixel = [] for j in range(size[0]): pixel.append(img.getpixel((j, i))) matrix.append(pixel) return matrix # 计算系数矩阵 def getCoefficient(length): matrix = [] sqr = 1.0 / math.sqrt(length) value = [] for i in range(length): value.append(sqr) matrix.append(value) for i in range(1, length): value = [] for j in range(0, length): value.append(math.sqrt(2.0 / length) * math.cos(i * math.pi * (j + 0.5) / length)) matrix.append(value) return matrix # 计算矩阵转秩 def getTranspose(matrix): new_matrix = [] for i in range(len(matrix)): value = [] for j in range(len(matrix[i])): value.append(matrix[j][i]) new_matrix.append(value) return new_matrix # 计算矩阵乘法 def getMultiply(matrix1, matrix2): new_matrix = [] for i in range(len(matrix1)): value = [] for j in range(len(matrix2[i])): ans = 0.0 for h in range(len(matrix1[i])): ans += matrix1[i][h] * matrix2[h][j] value.append(ans) new_matrix.append(value) return new_matrix # 计算DCT def DCT(matrix): length = len(matrix) A = getCoefficient(length) AT = getTranspose(A) temp = getMultiply(A, matrix) DCT_matrix = getMultiply(matrix, AT) return DCT_matrix # 计算左上角8*8并转化为list def submatrix_list(matrix, size = (8, 8)): value = [] for i in range(size[0]): for j in range(size[1]): value.append(matrix[i][j]) return value # 计算hash值 def getHashCode(sub_list): length = len(sub_list) mean = sum(sub_list) / length result = [] for i in sub_list: if i > mean: result.append(1) else: result.append(0) return result # 比较hash值 def compHashCode(hc1, hc2): cnt = 0 for i, j in zip(hc1, hc2): if i == j: cnt += 1 return cnt # 计算感知哈希算法相似度 def calpHashSimilarity(img1, img2): img1 = regularizeImage(img1) img2 = regularizeImage(img2) matrix1 = getMatrix(img1) matrix2 = getMatrix(img2) DCT1 = DCT(matrix1) DCT2 = DCT(matrix2) sub_list1 = submatrix_list(DCT1) sub_list2 = submatrix_list(DCT2) hc1 = getHashCode(sub_list1) hc2 = getHashCode(sub_list2) return compHashCode(hc1, hc2) # 单元测试 class TestpHash(unittest.TestCase): def test_getHashCode(self): self.assertEqual(getHashCode([1, 2, 3]), [0, 0, 1]) if __name__ == '__main__': unittest.main() __all__ = ['calpHashSimilarity']