1.像素方差
1.1缩放图片
1.2灰度处理
1.3计算图像每行的平均值
1.4计算方差
1.5比较方差
代码中先使用yolov模型对图片进行了目标检测,提取出检测部分的图像,然后在对图像做相似度处理。
import cv2 as cv import matplotlib.pyplot as plt from yolo.yolo import yolo_detect def detect(data): x,y,w,h=yolo_detect(data) image=cv.imread(data,cv.IMREAD_UNCHANGED) print(x,y,w,h) img=image[x:x+w,y:y+h] return img def imgavg(img): sidelength=30 #缩放 img=cv.resize(img,(sidelength,sidelength),interpolation=cv.INTER_CUBIC) #灰度化 gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) #每行平均值 avglist=[] for i in range(sidelength): avg=sum(gray[i])/len(gray[i]) avglist.append(avg) return avglist def variance(avglist): avg=sum(avglist)/len(avglist) s=0 for i in avglist: s+=(i-avg)*(i-avg)/len(avglist) return s data1='data/car1.jpg' image1=cv.imread(data1,cv.IMREAD_UNCHANGED) data2='data/car2.jpg' image2=cv.imread(data2,cv.IMREAD_UNCHANGED) img1=detect(data1) img2=detect(data2) avg1=imgavg(img1) avg2=imgavg(img2) print("两图片方差:%s"%(abs(variance(avg1)-variance(avg2)))) x=range(30) plt.figure("兰博基尼") plt.subplot(2,2,1) plt.imshow(image1) plt.subplot(2,2,2) plt.plot(x,avg1,marker="*",label="$car1$") plt.plot(x,avg2,marker="*",label="$car2$") plt.legend() plt.subplot(2,2,3) plt.imshow(image2) plt.legend() plt.show()
2.哈希值计算
2.1平均值哈希
2.1.1图片缩放成8*8
image=cv.resize(img,(8,8),interpolation=cv.INTER_CUBIC) • 1
2.1.2灰度化图像G
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) • 1
2.1.3计算整个灰度图像的像素平均值avg
s=0 for i in range(8): for j in range(8): s=s+gray[i,j] avg=s/64
2.1.4计算hash图像H
得到图片的hash值后,一行行展开,得到一个二进制数,将二进制数转化为十六进制数,比较两张图片的十六七进制数的汉明距离,通常认为汉明距离小于10的一组图片为相似图片。
汉明距离:两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数
hash_str='' for i in range(8): for j in range(8): if gray[i,j]>=avg: hash_str+=hash_str+'1' else: hash_str+=hash_str+'0' result = '' for i in range(0, 64, 4): result += ''.join('%x' % int(hash_str[i: i + 4], 2)) # print("hash值:",result) return result
2.2感知哈希
2.2.1图片缩放32*32
image=cv.resize(img,(32,32),interpolation=cv.INTER_CUBIC)
2.2.2灰度化图像G1
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
2.2.3计算得到图像G的离散余弦变换的图像G 2
h, w = img.shape[:2] vis0 = np.zeros((h, w), np.float32) vis0[:h, :w] = image # DCT二维变换 # 离散余弦变换,得到dct系数矩阵 img_dct = cv.dct(cv.dct(vis0))
2.2.4取G 2 左上角8*8子图像G 3 ,计算这个图像中所有像素的平均值,假设其值为a
img_dct.resize(8, 8) # 把list变成一维list img_list = np.array().flatten(img_dct.tolist()) #均值计算 avg=cv.mean(img_list)
2.2.5计算hash图像H
得到图片的hash值后,一行行展开,得到一个二进制数,将二进制数转化为十六进制数,比较两张图片的十六七进制数的汉明距离,通常认为汉明距离小于10的一组图片为相似图片。
汉明距离:两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数
avg_list = ['0' if i < avg else '1' for i in img_list] return ''.join(['%x' % int(''.join(avg_list[x:x + 4]), 2) for x in range(0, 64, 4)])
2.3差异值哈希
2.3.1缩放图片9*8
image = cv.resize(image, (9, 8), interpolation=cv2.INTER_CUBIC)
2.3.2灰度化
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) • 1
2.3.3差异值计算
当前行像素值与前一行像素值比较,如果大于前一行值,则H ( i , j ) = 1 H(i,j)=1H(i,j)=1,,反之为0 从第二到第九行共8行,又因为矩阵有8列,所以得到一个8x8差分矩阵G GG
dhash_str = '' for i in range(8): for j in range(8): if gray[i, j] > gray[i, j + 1]: dhash_str = dhash_str + '1' else: dhash_str = dhash_str + '0'
2.3.4计算hash图像H
同上一样
result = '' for i in range(0, 64, 4): result += ''.join('%x' % int(dhash_str[i: i + 4], 2)) # print("hash值",result) return result
2.3汉明距离计算
def campHash(hash1, hash2): n = 0 # hash长度不同返回-1,此时不能比较 if len(hash1) != len(hash2): return -1 # 如果hash长度相同遍历长度 for i in range(len(hash1)): if hash1[i] != hash2[i]: n = n + 1 return n
3.余弦距离计算
把图像看成是一个矩阵向量,通过计算矩阵之间的余弦距离来表达两张图片的相似度。
4.直方图计算
通过cv2.calcHist()计算图像的直方图
通过cv2.compareHist()来比较以下两张图之间的相似度
import matplotlib.pyplot as plt import cv2 import numpy as py img = cv2.imread("data/car1.jpg") img1 = cv2.imread("data/car2.jpg") # 计算图img的直方图 H1 = cv2.calcHist([img], [1], None, [256],[0,256]) H1 = cv2.normalize(H1, H1, 0, 1, cv2.NORM_MINMAX, -1) # 对图片进行归一化处理 # 计算图img2的直方图 H2 = cv2.calcHist([img1], [1], None, [256],[0,256]) H2 = cv2.normalize(H2, H2, 0, 1, cv2.NORM_MINMAX, -1) # 利用compareHist()进行比较相似度 similarity = cv2.compareHist(H1, H2,0) print(similarity) # img和img1直方图展示 H=[H1,H2] for i in range(2): plt.subplot(2,1,1+i) plt.plot(H[i]) plt.show()
相似度:
0.14550932178252954