汉明距离表示两个(相同长度)字符串对应位置的不同字符的数量。用于编码,简单来说,判断两个序列是否相似,则判断是否有不同的位数。举例:
A = [0, 0, 1, 0]
B = [0, 1, 1, 0]
AB 有一位不同,汉明距离为 1。
又比如:
A = [3,1,4,1,5,9]
B = [2,7,1,8,2,8]
每个对应位置上的元素都完全不一样,汉明距离为 6。
在实际实施算法时,有三种哈希算法,用于判断图像近似度:A,D 和 P
A 指的是平均:average
D 指的是差异:diff
P 是指感知:perceptual
最推荐的是 D 也就是差异哈希,A 仅计算平均值,误差很大。P 虽然更精确但是计算速度过慢。D 由于算的是差值,因此是基于渐变的实现。
R 是 red,G 是 green,B 是 blue,分别代表 rgb 图像中的三原色
浮点算法:
整数方法:
移位:
平均值方法:
仅取绿色方法方法:
from skimage import transform
import cv2
#aHash方法计算图片的指纹数据
img=cv2.imread('/Users/myname/Desktop/test/d.jpg')#读入图片
length = 8
height = 8
sum = 0.0
k = 0
grey = []
## 修改图像大小
dst=transform.resize(img, (length, height))
for i in range(length):
for j in range(height):
(b,g,r) = dst[i,j]
# 计算灰度值
grey.append(r*0.3+g*0.59+b*0.11)#浮点灰度值计算
sum+=grey[k]
k=k+1
average = sum/(length*height)#算出平均的灰度数据
fingerprint = []
for i in range(length*height):
if grey[i] > average:
fingerprint.append(1)#如果灰度数据大于平均值,填入元素1,否则填入元素0
else:
fingerprint.append(0)
print(fingerprint)
基于渐变实现的差异算法,速度快。
from skimage import transform,data
import matplotlib.pyplot as plt
from skimage import io
import cv2
img=cv2.imread('/Users/myname/Desktop/test/d.jpg')#读入图片
length = 9
height = 8
sum = 0.0
k = 0
grey = []
dst=transform.resize(img, (length, height))
#灰度图转化
for i in range(length):
for j in range(height):
(b,g,r) = dst[i,j]
grey.append(r*0.3+g*0.59+b*0.11)#浮点灰度值计算
sum+=grey[k]
k=k+1
## 获取每行的差值,为64位
differ = []
for i in range(length-1):#i 8
for j in range(height):#j 8
differ.append(grey[j*8+i+1]-grey[j*8+i])
#获取01值
fingerprint = []
for i in range((length-1)*height):#8*8
if differ[i] > 0:
fingerprint.append(1)
else:
fingerprint.append(0)
#print(fingerprint)
对图像生成一个字符串代表他的“指纹”。通过比对“指纹”来比较图像的相似性。
缩小时建议 32*32,方便 DCT 计算:
import cv2
from skimage import transform
import numpy as np
#利用phash计算图像指纹
img=cv2.imread('/Users/myname/Desktop/test/d.jpg')#读入图片
length = 32
s_length = 8
dst=transform.resize(img, (length, length))
#print(type(dst))
#all 代表全图,建议32*32
matrix_all_grey = [[0 for i in range(length)] for i in range(length)]
#small 代表最低频率,8*8大小
matrix_small_grey = [[0 for i in range(s_length)] for i in range(s_length)]
## 灰度图转化
k = 0
for i in range(length):
for j in range(length):
(b,g,r) = dst[i,j]
matrix_all_grey[i][j] = ( b + g + r )/3
## 缩小
fft_matrix_grey = np.fft.fft(matrix_all_grey)
for i in range(s_length):
for j in range(s_length):
matrix_small_grey[i][j] = fft_matrix_grey[i][j]
## 计算平均
sum_pixel = 0
for i in range(s_length):
for j in range(s_length):
sum_pixel += matrix_small_grey[i][j]
average = sum_pixel / (s_length*s_length)
bite = []
#赋予01值
for i in range(s_length):
for j in range(s_length):
if matrix_small_grey[i][j] > average :
bite.append(1)
else:
bite.append(0)
print(bite)