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

在python中比较url中的图像和文件系统中的图像,第1张

在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):

  • NRMSE(f, g1) = 0.96
  • NRMSE(f, g2) = 0.88
  • NRMSE(f, h) = 0.63
  • SSIM(f, g1) = 0.98
  • SSIM(f, g2) = 0.81
  • SSIM(f, h) = 0.55

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

  • NRMSE(f, g) = 0.92
  • SSIM(f, g) = 0.61

因此,您需要确定您喜欢的度量标准和阈值它的价值。现在,指标。我所谓的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 numpyfrom scipy.signal import fftconvolvedef 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_mapdef 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中,这个运行得更快。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5645069.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存