python+opencv如何正确地比较图像(通过直方图)?

2024-06-25 23:00:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一堆图片(来自M.C.Escher收藏),我想做的第一步是通过比较把它们组合起来(你知道,有些图片有不同的分辨率/形状等等)。在

我写了一个非常残酷的剧本: *阅读文件 *计算它们的直方图 *比较一下

但是比较的质量确实很低,比如有完全不同的匹配文件

看看我到目前为止写的:

准备直方图

files_hist = {}

for i, f in enumerate(files):
    try:
        frame = cv2.imread(f)
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        hist = cv2.calcHist([frame],[0],None,[4096],[0,4096])
        cv2.normalize(hist, hist, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)

        files_hist[f] = hist
    except Exception as e:
        print('ERROR:', f, e)

比较直方图

^{pr2}$

现在,例如,我得到了这两个文件的匹配:

m.c.埃舍尔244(1933).jpg m._c._escher_244_(1933).jpg

以及

m.c.埃舍尔208(1931).jpg m._c._escher_208_(1931).jpg

使用上面的代码,它们的相关性是0.9996699595530539(因此它们实际上是相同的:()

我做错什么了?如何改进代码以避免这种错误匹配?在

谢谢!在


Tags: 文件代码for质量分辨率图片files直方图
1条回答
网友
1楼 · 发布于 2024-06-25 23:00:55

直方图不是比较图像的好方法,例如,在黑白图像中,如果它们具有相同数量的黑色像素,则直方图将是相同的,而不管图像中的像素分布如何(这就是为什么您提到的图像被分类为几乎相等的)。在

有更好的方法来量化图像之间的差异,this post提到了一个好的选择:

  • 将两个图像作为数组加载(scipy.misc.imread公司)然后计算一个元素(逐像素)的差值。计算差值的范数。在

编辑:

回答一些问题:

I take the zero norm per-pixel is going to be 0.0-1.0 value, with values close to 0.0 meaning "images are the same", correct?

接近0.0的值表示像素相同。要将图像作为一个整体进行比较,需要对所有像素求和。如果求和值接近0.0,则表示图像几乎相同。在

what if the 2 image sizes are different?

那是个好主意。要计算范数差,图像必须具有相同的大小。我看到了两种方法:

  • 第一种方法是将一个图像调整为另一个图像的形状,问题是这会导致图像失真。

  • 第二种方法是用0填充较小的图像,直到大小匹配为止。

obs:如果你在像素上求和,你会得到一个介于0和图像中像素数之间的值。如果要比较多个图像,这可能会令人困惑。例如,假设您比较图像A和B,它们的形状都是50x50(因此,图像有2500个像素);接近2500的值表示图像完全不同。现在假设您正在比较图像C和D,它们的形状都是1000x1000,在本例中,像2500这样的值意味着图像相似。为了克服这个问题,您可以将像素级和除以图像中的像素数,这将产生一个介于0.0和1.0之间的值,0.0表示图像相同,1.0表示它们完全不同。在

yeah here's the error i received when comparing 2 images with different size diff = image1 - image2 ValueError: operands could not be broadcast together with shapes (850,534) (663,650)

这是因为图像有不同的形状。调整大小或填充可以避免此错误(如上所述)。在

相关问题 更多 >