2022-11-11 来源:华纳网 责任编辑:谷雨老师 人气:
核心提示:本课内容: 大家好,欢迎来到谷雨课堂 大家好, 本节我们来学习比较图片的相似度, 进而得到两张图片是否相似, 以下是本节的全部源代码, 源代码中有详细的说明, #coding:utf-8 #No.36 视觉检测之判断两张图片相似度 import cv2 import numpy as np # 灰度

本课内容:

大家好,欢迎来到谷雨课堂

 

大家好,

本节我们来学习比较图片的相似度,

进而得到两张图片是否相似,

 

 

 

以下是本节的全部源代码,    
源代码中有详细的说明,

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
#coding:utf-8#No.36 视觉检测之判断两张图片相似度import cv2import numpy as np

# 灰度直方图作 比较def classify_gray_hist(image1,image2,size = (256,256)):    # 计算直方图,参数放入方括号    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])

    # 计算直方图的重合度    degree = 0    for i in range(len(hist1)):        if hist1[i] != hist2[i]:            degree = degree + (1 - abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i]))        else:            degree = degree + 1

    degree = degree/len(hist1)

    return degree



# 计算单通道的直方图的相似值def calculate(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    for i in range(len(hist1)):        if hist1[i] != hist2[i]:            degree = degree + (1 - abs(hist1[i]-hist2[i])/max(hist1[i],hist2[i]))        else:            degree = degree + 1

    degree = degree/len(hist1)    return degree



# 通过得到每个通道的直方图来计算相似度def classify_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

    for im1,im2 in zip(sub_image1,sub_image2):        sub_data += calculate(im1,im2)

    sub_data = sub_data/3

    return sub_data



# 平均哈希算法计算def classify_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)    return Hamming_distance(hash1,hash2)


# 感知哈希算法def classify_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)

    return Hamming_distance(hash1,hash2)



# 输入灰度图,返回hashdef getHash(image):    avreage = np.mean(image)

    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



# 计算汉明距离# 汉明距离是使用在数据传输差错控制编码里面的,汉明距离是一个概念,它表示两个(相同长度)字符串对应位置的不同字符的数量,我们以d(x,y)表示两个字x,y之间的汉明距离。对两个字符串进行异或运算,并统计结果为1的个数,那么这个数就是汉明距离。# 汉明距离越小,则代表相似度越高。汉明距离为0,即代表两张图片完全一样def Hamming_distance(hash1,hash2):    num = 0    for index in range(len(hash1)):        if hash1[index] != hash2[index]:            num += 1

    return num





###########################img1 = cv2.imread('A1.jpg')cv2.imshow('img1',img1)

img2 = cv2.imread('A3.jpg')cv2.imshow('img2',img2)

sim1 = classify_gray_hist(img1,img2)sim2 = classify_hist_with_split(img1,img2)sim3 = classify_aHash(img1,img2)sim4 = classify_pHash(img1,img2)

print("灰度直方图算法:" , sim1)print("所有通道直方图算法:" , sim2)print("平均哈希算法:" , sim3)print("感知哈希算法:" , sim4)

cv2.waitKey(0)

 

扩展阅读:

汉明距离
汉明距离是使用在数据传输差错控制编码里面的,汉明距离是一个概念,它表示两个(相同长度)字符串对应位置的不同字符的数量,我们以d(x,y)表示两个字x,y之间的汉明距离。对两个字符串进行异或运算,并统计结果为1的个数,那么这个数就是汉明距离。

完整的源代码可以登录【华纳网】下载。

 

https://www.worldwarner.com/




 





免责声明:本文仅代表作者个人观点,与华纳网无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。