Python 比较俩张图片差异

对比俩张图片差异,可以用均方误差(MSE)与结构相似性指数(SSIM)函数。(Mean Squared Error vs. Structural Similarity Measure)

使用此方法,我们能够轻松确定两个图像是相同的还是由于轻微的图像操作,压缩伪像或有目的的篡改而有所不同。

尽管MSE的计算速度要快得多,但它的主要缺点是(1)全局应用,(2)仅估计图像的感知错误。
另一方面,SSIM虽然速度较慢,但​​可以通过比较图像的局部区域而不是全局图像来感知图像的结构信息的变化。 那么您应该使用哪种方法?
一般来说,SSIM会为您带来更好的结果,但会降低性能。 但是我认为,准确性的提高是值得的。

MSE的值为0表示完全相似。大于1的值表示相似度较小,MSE的值随着像素强度之间的平均差增加而将继续增长。MSE值域在[0,…)
SSIM的值为1表示完全相似。值越小表示相似性越差。SSIM的值域在[-1,1]之间。

MSE与SSIM的方法比较俩张图片的前提是俩张图片的大小是一样的。
大小不一样的,可以学习cv.resize(),放大缩小到同一大小后进行比较。

1. MSE 均方误差介绍

MSE公式
MSE核心是逐个像素差的平方和,除以像素的个数。
MSE的实现非常简单,但是将其用于相似性时,我们可能会遇到问题。主要的一点是,像素强度之间的较大距离并不一定意味着图像的内容有很大不同。

为了纠正与MSE相关的一些图像比较问题,我们使用了Wang等人开发的结构相似性指数函数。

二、结构相似性指数

结构相似性指数SSIM方法显然比MSE方法更复杂,但是要点是SSIM试图对图像的结构信息中感知到的变化建模,而MSE实际上是在评估感知到的错误。两者之间有细微的差别,但结果却是惊人的。
MSE只考虑感知到的变化,而SSIM则考虑到了图像结构的变化(如公式中对于图像中N x N窗口的(x,y)位置,x和y方向上像素强度的平均值,x和y方向上强度的方差以及协方差。 ),是一种更健壮的方法。

# import the necessary packages
from skimage.metrics import structural_similarity as ssim
import matplotlib.pyplot as plt
import numpy as np
import cv2


def mse(imageA, imageB):
    # 均方误差方法用 python实现
    # 计算俩张图片的像素差的平方和的平均值
    # 俩张图必须有相同的 分辨率维度
    err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
    err /= float(imageA.shape[0] * imageA.shape[1])

    # return the MSE, the lower the error, the more "similar"
    # the two images are
    return err


def compare_images(imageA, imageB, title):
    # 计算俩张图片的均方误差 及 结构相似性指数
    m = mse(imageA, imageB)
    s = ssim(imageA, imageB)
    # 设置图片的名称标头
    fig = plt.figure(title)
    plt.suptitle("MSE: %.2f, SSIM: %.2f" % (m, s))
    # 展示第一张图
    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.show()


def main():
    # 加载图片 —— 初始,对比,ps操作过的
    original = cv2.imread("D:/pyimagesearch/images/origin.jpg")
    contrast = cv2.imread("D:/pyimagesearch/images/contrast.jpg")
    shopped = cv2.imread("D:/pyimagesearch/images/photoshopped.jpg")
    # convert the images to grayscale
    original = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
    contrast = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY)
    shopped = cv2.cvtColor(shopped, cv2.COLOR_BGR2GRAY)

    # 初始化图表
    fig = plt.figure("Images")
    images = ("Original", original), ("Contrast", contrast), ("Photoshopped", 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.show()
    # 分别比较图片
    compare_images(original, original, "Original vs. Original")
    compare_images(original, contrast, "Original vs. Contrast")
    compare_images(original, shopped, "Original vs. Photoshopped")


if __name__ == "__main__":
    main()

结果图如下:
在这里插入图片描述与原图相比 MSE: 0,SSIM:1 无限相似
在这里插入图片描述与contrast对比图,显然不够像
在这里插入图片描述与photoshop操作过加了前缀图的要比 contrast相似些。
在这里插入图片描述
参考:How-To: Python Compare Two Images

猜你喜欢

转载自blog.csdn.net/qq_40985985/article/details/105556785