您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在python中比较url中的图像和文件系统中的图像

在python中比较url中的图像和文件系统中的图像

这个问题的标题表明你有两个确切的图像要比较,而且 做得很琐碎。现在,如果你有相似的图像要比较 解释了为什么您没有找到完全满意的答案:没有度量 适用于给出预期结果的每个问题(注意 预期结果因应用而异)。问题之一是 很难——在没有共识的意义上——比较图像 有多个波段,比如彩色图像。为了解决这个问题,我会考虑 在每个频带中应用给定的度量,该度量的结果将 是最小的结果值。这是假设度量具有良好的 范围,如[0,1],此范围内的最大值表示图像 相同(按给定的度量)。相反,最小值意味着 图像完全不同。 所以,我要做的就是给你两个指标。其中之一就是西米一个我 将调用为NRMSE(均方误差根的标准化)。我 选择第二种方法是因为它是一种非常简单的方法 可能就够解决你的问题了。 让我们从例子开始。图像的顺序是:f=原始 PNG格式的图像,g1=JPEG,质量为“f”的50%(使用“convert f-quality”制作 50 g),g2=JPEG 1%的“f”,h=“Lighted”g2质量。

Results (rounded):

在某种程度上,这两个指标都能很好地处理修改,但“SSIM”显示出了它的优势 一个更明智的方法是,当图像实际上是真实的时,报告较低的相似性 视觉上清晰,当图像 视觉上非常相似。下一个示例考虑彩色图像(f=原始) 图像,g=JPEG,质量为5%)。

因此,您需要确定您喜欢的度量标准和阈值它的价值。现在,指标。我所谓的NRMSE只是1-[RMSE/(maxval)-‘minval’)]。其中“maxval”是两个图像的最大强度 和“minval”分别相同。RMSE由MSE的平方根:sqrt[(和(A-B)**2)/| A |],其中| A |表示数字 这样,RMSE给出的最大值就是“maxval”。如果要进一步了解图像中MSE的含义,请参阅例如<https://ece.uwaterloo.ca/~z70wang/publications/SPM09.pdf>. 这个度量SSIM(Structural SIMilarity)更为复杂,您可以找到细节在前面包含的链接中。要方便地应用度量,请考虑 以下代码

import numpy
from scipy.signal import fftconvolve

def ssim(im1, im2, window, k=(0.01, 0.03), l=255):
    """See https://ece.uwaterloo.ca/~z70wang/research/ssim/"""
    # Check if the window is smaller than the images.
    for a, b in zip(window.shape, im1.shape):
        if a > b:
            return None, None
    # Values in k must be positive according to the base implementation.
    for ki in k:
        if ki < 0:
            return None, None

    c1 = (k[0] * l) ** 2
    c2 = (k[1] * l) ** 2
    window = window/numpy.sum(window)

    mu1 = fftconvolve(im1, window, mode='valid')
    mu2 = fftconvolve(im2, window, mode='valid')
    mu1_sq = mu1 * mu1
    mu2_sq = mu2 * mu2
    mu1_mu2 = mu1 * mu2
    sigma1_sq = fftconvolve(im1 * im1, window, mode='valid') - mu1_sq
    sigma2_sq = fftconvolve(im2 * im2, window, mode='valid') - mu2_sq
    sigma12 = fftconvolve(im1 * im2, window, mode='valid') - mu1_mu2

    if c1 > 0 and c2 > 0:
        num = (2 * mu1_mu2 + c1) * (2 * sigma12 + c2)
        den = (mu1_sq + mu2_sq + c1) * (sigma1_sq + sigma2_sq + c2)
        ssim_map = num / den
    else:
        num1 = 2 * mu1_mu2 + c1
        num2 = 2 * sigma12 + c2
        den1 = mu1_sq + mu2_sq + c1
        den2 = sigma1_sq + sigma2_sq + c2
        ssim_map = numpy.ones(numpy.shape(mu1))
        index = (den1 * den2) > 0
        ssim_map[index] = (num1[index] * num2[index]) / (den1[index] * den2[index])
        index = (den1 != 0) & (den2 == 0)
        ssim_map[index] = num1[index] / den1[index]

    mssim = ssim_map.mean()
    return mssim, ssim_map


def nrmse(im1, im2):
    a, b = im1.shape
    rmse = numpy.sqrt(numpy.sum((im2 - im1) ** 2) / float(a * b))
    max_val = max(numpy.max(im1), numpy.max(im2))
    min_val = min(numpy.min(im1), numpy.min(im2))
    return 1 - (rmse / (max_val - min_val))


if __name__ == "__main__":
    import sys
    from scipy.signal import gaussian
    from PIL import Image

    img1 = Image.open(sys.argv[1])
    img2 = Image.open(sys.argv[2])

    if img1.size != img2.size:
        print "Error: images size differ"
        raise SystemExit

    # Create a 2d gaussian for the window parameter
    win = numpy.array([gaussian(11, 1.5)])
    win2d = win * (win.T)

    num_metrics = 2
    sim_index = [2 for _ in xrange(num_metrics)]
    for band1, band2 in zip(img1.split(), img2.split()):
        b1 = numpy.asarray(band1, dtype=numpy.double)
        b2 = numpy.asarray(band2, dtype=numpy.double)
        # SSIM
        res, smap = ssim(b1, b2, win2d)

        m = [res, nrmse(b1, b2)]
        for i in xrange(num_metrics):
            sim_index[i] = min(m[i], sim_index[i])

    print "Result:", sim_index

请注意,当给定的“window”较大时,“ssim”拒绝比较图像 比他们好。“window”通常非常小,认值为11x11,因此如果 图像比那个小,没有太多的“结构”(从名字上来说) 度量)进行比较,您应该使用其他度量(如 函数“nrmse”)。可能有更好的方法来实现“ssim”,因为 在Matlab中,这个运行得更快。

python 2022/1/1 18:30:46 有397人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶