对比多张图片相似度(PYTHON)

可以使用图像处理软件或者编程语言进行相似度对比。常用的指标有:

    1. 均方误差(MSE):计算每个像素的差异,再求平均值。公式:MSE = 1/nΣ(i=1,n)(I1(i)-I2(i))^2,其中I1和I2是两张图片对应像素的灰度值,n是像素数量。MSE越小,表示图片越相似。

    2. 结构相似度指标(SSIM):考虑到人眼对于图像细节的敏感程度,比MSE更能反映图像的相似度。SSIM计算公式较为复杂,包含对于亮度、对比度、结构等因素的综合考虑。

    3. 归一化互相关(NCC):计算两张图片的互相关系数,越接近1则表示图片越相似。公式:NCC = Σ(i=1,n)(I1(i)-u1)*(I2(i)-u2) / sqrt(Σ(i=1,n)(I1(i)-u1)^2*Σ(i=1,n)(I2(i)-u2)^2),其中u1和u2是图片的均值。

    使用以上指标进行对比比较直观,但要注意的是,不同指标适用于不同类型的图片,具体选择应根据实际情况而定。

以下是代码实现(python):

# coding=utf-8

import cv2
from skimage.metrics import structural_similarity
import numpy as np
import matplotlib.pyplot as plt

"""
图片相似度
"""


# 方法一、均方误差(MSE)
def mse(imageA, imageB):
    """
    均方误差(MSE):计算每个像素的差异,再求平均值。
    公式:MSE = 1/nΣ(i=1,n)(I1(i)-I2(i))^2,
    其中I1和I2是两张图片对应像素的灰度值,n是像素数量。
    注意:两张图片必须有相同的维度,
    MSE越小,表示图片越相似
    @param imageA: 图片1
    @param imageB: 图片2
    @return: MSE越小,表示图片越相似
    """
    # print(imageA.astype("float"))
    # print(imageB.astype("float"))
    # 对应像素相减并将结果累加
    err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
    # 进行误差归一化
    err /= float(imageA.shape[0] * imageA.shape[1])
    # 返回结果,值越小,表示图片越相似
    return err


# 方法二、结构相似度指标(SSIM)
def ssim(imageA, imageB):
    """
    考虑到人眼对于图像细节的敏感程度,
    比MSE更能反映图像的相似度。
    SSIM计算公式较为复杂,包含对于亮度、对比度、结构等因素的综合考虑。
    @param imageA: 图片1
    @param imageB: 图片2
    @return: SSIM计算公式较为复杂包含对于亮度、对比度、结构等因素的综合考虑。
    """
    # ssim_val = cv2.SSIM(imageA, imageB)
    # ssim_val = structural_similarity(imageA, imageB, data_range=255, multichannel=True)
    ssim_val = structural_similarity(imageA, imageB, data_range=255, channel_axis=1)
    return ssim_val


# 方法三、归一化互相关(NCC)
def ncc(imageA, imageB):
    """
    归一化互相关(NCC):计算两张图片的互相关系数,越接近1则表示图片越相似。
    公式:NCC = Σ(i=1,n)(I1(i)-u1)*(I2(i)-u2) / sqrt(Σ(i=1,n)(I1(i)-u1)^2*Σ(i=1,n)(I2(i)-u2)^2),
    其中u1和u2是图片的均值。
    @param imageA: 图片1
    @param imageB: 图片2
    @return: ncc_val 越接近1则表示图片越相似
    """
    meanA = np.mean(imageA)
    meanB = np.mean(imageB)
    ncc_val = np.sum((imageA - meanA) * (imageB - meanB)) / (
                np.sqrt(np.sum((imageA - meanA) ** 2)) * np.sqrt(np.sum((imageB - meanB) ** 2)))
    return ncc_val


def compare_images(imageA, imageB, title):
    # 分别计算输入图片的MSE和SSIM指标值的大小
    m = mse(imageA, imageB)
    s = ssim(imageA, imageB)
    # 创建figure
    fig = plt.figure(title)
    plt.suptitle("MSE: %.2f, SSIM: %.2f" % (m, s))
    # plt.suptitle("MSE: %.2f, SSIM: %.2f" % (m, 1))
    # 显示第一张图片
    ax = fig.add_subplot(1, 2, 1)
    plt.imshow(imageA, cmap=plt.cm.gray)
    plt.axis("off")
    # 显示第二张图片
    ax = fig.add_subplot(1, 2, 2)
    plt.imshow(imageB, cmap=plt.cm.gray)
    plt.axis("off")
    plt.tight_layout()
    plt.show()


def test1():
    # # 读取图片
    original1 = cv2.imread("1.png")
    contrast1 = cv2.imread("2.png")
    shopped1 = cv2.imread("4.png")

    h1, w1 = cv2.imread("1.png", cv2.IMREAD_GRAYSCALE).shape

    original1 = cv2.resize(original1, (h1, w1))
    contrast1 = cv2.resize(contrast1, (h1, w1))
    shopped1 = cv2.resize(shopped1, (h1, w1))

    # 将彩色图转换为灰度图
    original = cv2.cvtColor(original1, cv2.COLOR_BGR2GRAY)
    contrast = cv2.cvtColor(contrast1, cv2.COLOR_BGR2GRAY)
    shopped = cv2.cvtColor(shopped1, cv2.COLOR_BGR2GRAY)

    # # 初始化figure对象
    # fig = plt.figure("Images")
    # images = ("Original", original), ("Enhance", contrast), ("Others", shopped)
    # # 遍历每张图片
    # for (i, (name, image)) in enumerate(images):
    #     # 显示图片
    #     ax = fig.add_subplot(1, 3, i + 1)
    #     ax.set_title(name)
    #     plt.imshow(image, cmap=plt.cm.gray)
    #     plt.axis("off")
    # plt.tight_layout()
    # plt.show()

    # 比较图片
    compare_images(original, original, "Original vs Original")
    compare_images(original, contrast, "Original vs Enhance")
    compare_images(original, shopped, "Original vs Others")


def test2():
    img1 = cv2.imread("2.png", cv2.IMREAD_GRAYSCALE)
    img2 = cv2.imread("4.png", cv2.IMREAD_GRAYSCALE)
    h1, w1 = img1.shape
    img1 = cv2.resize(img1, (h1, w1))
    img2 = cv2.resize(img2, (h1, w1))
    print('mse : ', mse(img1, img2))
    print('ssim : ', ssim(img1, img2))
    print('ncc : ', ncc(img1, img2))


if __name__ == '__main__':
    # test2()
    test1()

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年8月28日
下一篇 2023年8月28日

相关推荐