说明
1、缩小图片:缩小到9*8,这样它就有72个像素点。
2、转换成灰度图。
3、计算差异值:dHash算法在相邻像素之间工作,因此每行9个像素之间产生8个不同的差异,总共8行,产生64个差异值。
4、获取指纹:如果左像素比右像素亮,记录为1,否则为0。
5、最后对比两张图片的指纹,获得汉明距离。
实例
#-*-coding:utf-8-*- #利用python实现多种方法来实现图像识别 importcv2 importnumpyasnp frommatplotlibimportpyplotasplt #最简单的以灰度直方图作为相似比较的实现 defclassify_gray_hist(image1,image2,size=(256,256)): #先计算直方图 #几个参数必须用方括号括起来 #这里直接用灰度图计算直方图,所以是使用第一个通道, #也可以进行通道分离后,得到多个通道的直方图 #bins取为16 image1=cv2.resize(image1,size) image2=cv2.resize(image2,size) hist1=cv2.calcHist([image1],[0],None,[256],[0.0,255.0]) hist2=cv2.calcHist([image2],[0],None,[256],[0.0,255.0]) #可以比较下直方图 plt.plot(range(256),hist1,'r') plt.plot(range(256),hist2,'b') plt.show() #计算直方图的重合度 degree=0 foriinrange(len(hist1)): ifhist1[i]!=hist2[i]: degree=degree+(1-abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i])) else: degree=degree+1 degree=degree/len(hist1) returndegree #计算单通道的直方图的相似值 defcalculate(image1,image2): hist1=cv2.calcHist([image1],[0],None,[256],[0.0,255.0]) hist2=cv2.calcHist([image2],[0],None,[256],[0.0,255.0]) #计算直方图的重合度 degree=0 foriinrange(len(hist1)): ifhist1[i]!=hist2[i]: degree=degree+(1-abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i])) else: degree=degree+1 degree=degree/len(hist1) returndegree #通过得到每个通道的直方图来计算相似度 defclassify_hist_with_split(image1,image2,size=(256,256)): #将图像resize后,分离为三个通道,再计算每个通道的相似值 image1=cv2.resize(image1,size) image2=cv2.resize(image2,size) sub_image1=cv2.split(image1) sub_image2=cv2.split(image2) sub_data=0 forim1,im2inzip(sub_image1,sub_image2): sub_data+=calculate(im1,im2) sub_data=sub_data/3 returnsub_data #平均哈希算法计算 defclassify_aHash(image1,image2): image1=cv2.resize(image1,(8,8)) image2=cv2.resize(image2,(8,8)) gray1=cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY) gray2=cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY) hash1=getHash(gray1) hash2=getHash(gray2) returnHamming_distance(hash1,hash2) defclassify_pHash(image1,image2): image1=cv2.resize(image1,(32,32)) image2=cv2.resize(image2,(32,32)) gray1=cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY) gray2=cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY) #将灰度图转为浮点型,再进行dct变换 dct1=cv2.dct(np.float32(gray1)) dct2=cv2.dct(np.float32(gray2)) #取左上角的8*8,这些代表图片的最低频率 #这个操作等价于c++中利用opencv实现的掩码操作 #在python中进行掩码操作,可以直接这样取出图像矩阵的某一部分 dct1_roi=dct1[0:8,0:8] dct2_roi=dct2[0:8,0:8] hash1=getHash(dct1_roi) hash2=getHash(dct2_roi) returnHamming_distance(hash1,hash2) #输入灰度图,返回hash defgetHash(image): avreage=np.mean(image) hash=[] foriinrange(image.shape[0]): forjinrange(image.shape[1]): ifimage[i,j]>avreage: hash.append(1) else: hash.append(0) returnhash #计算汉明距离 defHamming_distance(hash1,hash2): num=0 forindexinrange(len(hash1)): ifhash1[index]!=hash2[index]: num+=1 returnnum if__name__=='__main__': img1=cv2.imread('10.jpg') cv2.imshow('img1',img1) img2=cv2.imread('11.jpg') cv2.imshow('img2',img2) degree=classify_gray_hist(img1,img2) #degree=classify_hist_with_split(img1,img2) #degree=classify_aHash(img1,img2) #degree=classify_pHash(img1,img2) printdegree cv2.waitKey(0)
以上就是Python dHash算法的使用,希望对大家有所帮助。
本文教程操作环境:windows7系统、Python 3.9.1,DELL G3电脑。
下一篇