使用python对比图片相似度

感知哈希算法

import cv2 as cv
import numpy as np
from PIL import Image

def compare_img_p_hash(img1, img2):

    hash_img1 = get_img_p_hash(img1)
    hash_img2 = get_img_p_hash(img2)
    print(ham_dist(hash_img1, hash_img2))


def get_img_p_hash(img):
    """
    Get the pHash value of the image, pHash : Perceptual hash algorithm(感知哈希算法)
​
    :param img: img in MAT format(img = cv2.imread(image))
    :return: pHash value
    """
    hash_len = 32

    # GET Gray image
    gray_img = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
    # Resize image, use the different way to get the best result
    resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_AREA)
    # resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_LANCZOS4)
    # resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_LINEAR)
    # resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_NEAREST)
    # resize_gray_img = cv.resize(gray_img, (hash_len, hash_len), cv.INTER_CUBIC)
    # Change the int of image to float, for better DCT
    h, w = resize_gray_img.shape[:2]
    vis0 = np.zeros((h, w), np.float32)
    vis0[:h, :w] = resize_gray_img
    # DCT: Discrete cosine transform(离散余弦变换)
    vis1 = cv.dct(cv.dct(vis0))
    vis1.resize(hash_len, hash_len)
    img_list = vis1.flatten()
    # Calculate the avg value
    avg = sum(img_list) * 1. / len(img_list)
    avg_list = []
    for i in img_list:
        if i < avg:
            tmp = '0'
        else:
            tmp = '1'
        avg_list.append(tmp)
    # Calculate the hash value
    p_hash_str = ''
    for x in range(0, hash_len * hash_len, 4):
        p_hash_str += '%x' % int(''.join(avg_list[x:x + 4]), 2)
        return p_hash_str
def ham_dist(x, y):
    """
    Get the hamming distance of two values.
        hamming distance(汉明距)
    :param x:
    :param y:
    :return: the hamming distance
    """
    assert len(x) == len(y)
    return sum([ch1 != ch2 for ch1, ch2 in zip(x, y)])
if __name__=="__main__":
    img1 = Image.open('C:/Users/86176/OneDrive/dies/3.png')
    img2 = Image.open("C:/Users/86176/OneDrive/dies/4.png")
    img1 = np.asarray(img1)
    img2 = np.asarray(img2)
    compare_img_p_hash(img1, img2)

在这里插入图片描述

直方图算法

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

from PIL import Image

def create_rgb_hist(image):
    """"创建 RGB 三通道直方图(直方图矩阵)"""
    h, w, c = image.shape
    # 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
    # 16*16*16的意思为三通道每通道有16个bins
    rgbhist = np.zeros([16 * 16 * 16, 1], np.float32)
    bsize = 256 / 16
    for row in range(h):
        for col in range(w):
            b = image[row, col, 0]
            g = image[row, col, 1]
            r = image[row, col, 2]
            # 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
            index = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
            # 该处形成的矩阵即为直方图矩阵
            rgbhist[int(index), 0] += 1
            plt.ylim([0, 10000])
            plt.grid(color='r', linestyle='--', linewidth=0.5, alpha=0.3)
            return rgbhist


def hist_compare(image1, image2):
    """直方图比较函数"""
    # 创建第一幅图的rgb三通道直方图(直方图矩阵)
    hist1 = create_rgb_hist(image1)
    # 创建第二幅图的rgb三通道直方图(直方图矩阵)
    hist2 = create_rgb_hist(image2)
    # 进行三种方式的直方图比较
    match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
    match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
    match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
    print("巴氏距离:%s, 相关性:%s, 卡方:%s" % (match1, match2, match3))
if __name__ == "__main__":
    img1 = Image.open('C:/Users/86176/OneDrive/dies/8.png')
    img2 = Image.open("C:/Users/86176/OneDrive/dies/9.png")
    img1 = np.asarray(img1)
    img2 = np.asarray(img2)

    plt.plot(create_rgb_hist(img2))
    hist_compare(img1, img2)

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枭玉龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值