Image similarity recognition algorithm aHash | dHash | PHash


aHash\pHash\dHash is a commonly used image similarity recognition algorithm with simple principle and easy implementation.

aHash algorithm

The essence of the Hash algorithm for image similarity recognition is to Hash the image to generate a set of binary numbers, and then find similar images by comparing the hash value distance of different images. aHash is called the average hash algorithm in Chinese . As the name suggests, the average pixel value will be used in the conversion process.

Fundamental

  1. Downsize. Doing this will remove the details of the picture and only retain information such as structure, light and shade. The purpose is to unify the size of the picture and ensure that subsequent pictures have hash values ​​of the same length to facilitate distance calculations.
  2. Grayscale processing. Convert all images to uniform grayscale values
  3. Calculate the pixel mean. Calculate the grayscale average of pixels
  4. Hash value calculation. Compare the grayscale of each pixel with the average value. If it is greater than or equal to the average, it will be recorded as 1, if it is less than the average, it will be recorded as 0, thus generating a binary array
  5. Pair images and calculate Hamming distance . The closer the distance, the more similar they are. When the picture is reduced to 8X8, a group of pictures with a Hamming distance less than 10 is generally considered to be similar pictures.

Advantages and Disadvantages

Advantages: Fast
Disadvantages: Poor accuracy, sensitive to the mean

python implementation

from PIL import Image
import os 
import numpy as np

# 均值哈希算法
def aHash(image):
	image_new = image
	# 计算均值
	avreage = np.mean(image_new)
	hash = []
	for i in range(image.shape[0]):
		for j in range(image.shape[1]):
			if image[i.j] > avreage:
				hash.append(1)
			else:
				hash.append(0)
	return hash

# 计算汉明距离
def Hamming_distance(hash1,hash2):
	num = 0
	for index in range(len(hash1)):
		if hash1[index] != hash2[index]:
			num += 1
	return num

if __name__  == '__main__':
	image1 = Image.open("image1.png")
	image2 = Image.open("image2.png")
	# 缩小尺寸并灰度化
	image1 = np.array(image1.resize((8,8),image.ANTIALIAS).convert('L'),'f')
	image2 = np.array(image2.resize((8,8),image.ANTIALIAS).convert('L'),'f')
	hash1 = aHash(image1)
	hash2 = aHash(image2)
	dist = Hamming_distance(hash1,hash2)
	# 将汉明距离转化为相似度
	similarity = 1 - dist * 1.0 /64
	print('dist is ' + '%d' % dist)
	print('similarity is ' + '%d' % similarity)

dHash algorithm

dHash is called differential hashing algorithm in Chinese. When hashing a picture, the final hash sequence is obtained by comparing the sizes of the left and right pixels.

Fundamental

  1. Downsize. Reduce the image to 9X8 size, now there are 72 pixels on the photo
  2. Grayscale processing
  3. Calculate the difference value and obtain the final hash value (the main difference from aHash). Compare the left and right pixels of each row. If the pixel on the left is brighter than the pixel on the right (the pixel value on the left is greater than the pixel value on the right), it is recorded as 1, otherwise it is 0. Because there are 9 elements in each row, 8 values ​​can be obtained by comparing the left and right two at one time, so a total of 64 values ​​can be obtained from 8 rows of pixels, so the hash value at this time is a 0-1 sequence with a length of 64.
  4. Image pairing, calculating Hamming distance

Advantages and Disadvantages

Faster and better judgment effect than aHash

python code implementation

from PIL import Image
import os 
import numpy as np
import time
# 差异哈希算法
def dHash(image):
	image_new = image
	# 计算平均值
	avreage = np.mean(image_new)
	hash = []
	# 每行前一个像素大于后一个像素为1 相反为0 生成哈希
	for i in range(8):
		for j in range(8):
			if image[i,j] > image[i , j+1]:
				hash.append(1)
			else:
				hash.append(0)
	return hash

# 计算汉明距离
def Hamming_distance(hash1,hash2):
	num = 0
	for index in range(len(hash1)):
		if hash1[index] != hash2[index]:
			num += 1
	return num

if __name__ == '__main__':
	image1 = Image.open('image1.png')
	image2 = Image.open('image2.png')
	start = time.time()
	image1 = np.array(image1.resize((9,8),Image.ANTIALIAS).convert('L'),'f')
	image2 = np.array(image2.resize((9,8),Image.ANTIALIAS).convert('L'),'f')
	hash1 = dHash(image1)
	hash2 = dHash(image2)
	dist = Hamming_distance(hash1,hash2)
	end = time.time()
	# 将距离转换为相似度
	similarity = 1 - dist * 1.0 / 64
	print('dist is '+ '%d' % dist)
	print('similarity is '+'%d'%similarity)
	print('time is ' + '%f'%(end-start))
	

Guess you like

Origin blog.csdn.net/shengweiit/article/details/132979550