感知哈希算法
import cv2 as cv
import numpy as np
from PIL import Image
def compare_img_p_hash(img1, img2):
hash_img1 = get_img_p_hash(img1)
hash_img2 = get_img_p_hash(img2)
print(ham_dist(hash_img1, hash_img2))
def get_img_p_hash(img):
"""
Get the pHash value of the image, pHash : Perceptual hash algorithm(感知哈希算法)
:param img: img in MAT format(img = cv2.imread(image))
:return: pHash value
"""
hash_len = 32
# GET Gray image
gray_img = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
# Resize image, use the different way to get the best result
resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_AREA)
# resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_LANCZOS4)
# resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_LINEAR)
# resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_NEAREST)
# resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_CUBIC)
# Change the int of image to float, for better DCT
h, w = resize_gray_img.shape[:2]
vis0 = np.zeros((h, w), np.float32)
vis0[:h, :w] = resize_gray_img
# DCT: Discrete cosine transform(离散余弦变换)
vis1 = cv.dct(cv.dct(vis0))
vis1.resize(hash_len, hash_len)
img_list = vis1.flatten()
# Calculate the avg value
avg = sum(img_list) * 1. / len(img_list)
avg_list = []
for i in img_list:
if i < avg:
tmp = '0'
else:
tmp = '1'
avg_list.append(tmp)
# Calculate the hash value
p_hash_str = ''
for x in range(0, hash_len * hash_len, 4):
p_hash_str += '%x' % int(''.join(avg_list[x:x + 4]), 2)
return p_hash_str
def ham_dist(x, y):
"""
Get the hamming distance of two values.
hamming distance(汉明距)
:param x:
:param y:
:return: the hamming distance
"""
assert len(x) == len(y)
return sum([ch1 != ch2 for ch1, ch2 in zip(x, y)])
if __name__=="__main__":
img1 = Image.open('C:/Users/86176/OneDrive/dies/3.png')
img2 = Image.open("C:/Users/86176/OneDrive/dies/4.png")
img1 = np.asarray(img1)
img2 = np.asarray(img2)
compare_img_p_hash(img1, img2)
直方图算法
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
def create_rgb_hist(image):
""""创建 RGB 三通道直方图(直方图矩阵)"""
h, w, c = image.shape
# 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
# 16*16*16的意思为三通道每通道有16个bins
rgbhist = np.zeros([16 * 16 * 16, 1], np.float32)
bsize = 256 / 16
for row in range(h):
for col in range(w):
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
# 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
index = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
# 该处形成的矩阵即为直方图矩阵
rgbhist[int(index), 0] += 1
plt.ylim([0, 10000])
plt.grid(color='r', linestyle='--', linewidth=0.5, alpha=0.3)
return rgbhist
def hist_compare(image1, image2):
"""直方图比较函数"""
# 创建第一幅图的rgb三通道直方图(直方图矩阵)
hist1 = create_rgb_hist(image1)
# 创建第二幅图的rgb三通道直方图(直方图矩阵)
hist2 = create_rgb_hist(image2)
# 进行三种方式的直方图比较
match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
print("巴氏距离:%s, 相关性:%s, 卡方:%s" % (match1, match2, match3))
if __name__ == "__main__":
img1 = Image.open('C:/Users/86176/OneDrive/dies/8.png')
img2 = Image.open("C:/Users/86176/OneDrive/dies/9.png")
img1 = np.asarray(img1)
img2 = np.asarray(img2)
plt.plot(create_rgb_hist(img2))
hist_compare(img1, img2)