image-processing - 如何找到两个图像之间的所有共享区域

标签 image-processing

我一直在尝试寻找能够自动找到两幅图像之间所有共享区域的东西,明确不是基于像素匹配或差异,而且我在公平之后基本上什么都想不出来有点搜索。

假设我有以下两张图片,在本例中为网站截图。第一个“基线”:

enter image description here

第二个非常相似,但修改了一些 CSS,因此整个 block 都被移动了。没有文本内容变化,没有框尺寸变化,只是一些元素重新定位:

enter image description here

在这种情况下(但实际上在所有其他情况下,要比较两张图像,其中一张是另一张的派生图像)它们的像素差异对于查看发生了什么变化实际上是无用的:

enter image description here

事实上,即使我们应用一些简单的差异夸大,结果仍然相当无用,因为我们仍在查看像素差异,而不是基于更改,所以我们不会(以任何方式)查看对视觉信息的实际修改:

enter image description here

所以这就像比较两本书,然后根据我们可以找到的 n 值的多少来确定这两本书是不同的 book1.letters[n] != book2.letters [n]...

因此,我正在寻找一种计算相似区域的方法,显示两幅图像的哪些部分编码相同的信息,但不一定在相同的边界框中。

比如上面两张图,几乎所有的数据都是一样的,只是有些地方搬了个地方。唯一真正的区别是有神秘的空白。

具有相似区域的颜色编码:

enter image description here

和通信:

enter image description here

我找不到一个工具来执行此操作,我什至找不到允许使用 opencv 或类似技术实现此操作的教程。也许我在寻找错误的术语,也许实际上没有人为此编写过图像比较工具(这似乎令人难以置信?),所以冒着偏离主题的风险:我 searched and researched尽我所能,在这里。如果我需要它作为可以作为常规(开源)工具链的一部分运行以进行 QA/测试的工具,我有什么选择? (所以:不是一些昂贵的插件到同样昂贵的商业软件)。

最佳答案

这是对初始区域聚类的建议。

首先我们将两张图片相减以找出不同的区域。然后我们将其大小调整为更小的规模,以加快速度并更轻松地聚类。

enter image description here

然后我们运行形态学关闭操作将所有附近的对象聚集在一起。

enter image description here

对结果进行阈值处理以获得强信号

enter image description here

运行连通分量分析以获取所有边界框。

enter image description here

然后检查所有框的交集并合并它们。在我的例子中,我只是在实体模式下重新绘制所有边界框并重新分析组件以获得区域

enter image description here

一旦有了这个,我们就可以在第二张图像上运行相同的过程,并使用简单的互相关匹配方法或任何其他奇特的匹配方法对提取的每个区域进行交叉匹配。在这种情况下,区域之间的简单宽度和高度匹配也可以。

这是我编写的代码。希望对您有所帮助。

import cv2
import numpy as np


# Function to fill all the bounding box
def fill_rects(image, stats):

    for i,stat in enumerate(stats):
        if i > 0:
            p1 = (stat[0],stat[1])
            p2 = (stat[0] + stat[2],stat[1] + stat[3])
            cv2.rectangle(image,p1,p2,255,-1)


# Load image file
img1 = cv2.imread('img1.jpg',0)
img2 = cv2.imread('img2.jpg',0)

# Subtract the 2 image to get the difference region
img3 = cv2.subtract(img1,img2)

# Make it smaller to speed up everything and easier to cluster
small_img = cv2.resize(img3,(0,0),fx = 0.25, fy = 0.25)


# Morphological close process to cluster nearby objects
fat_img = cv2.dilate(small_img, None,iterations = 3)
fat_img = cv2.erode(fat_img, None,iterations = 3)

fat_img = cv2.dilate(fat_img, None,iterations = 3)
fat_img = cv2.erode(fat_img, None,iterations = 3)

# Threshold strong signals
_, bin_img = cv2.threshold(fat_img,20,255,cv2.THRESH_BINARY)

# Analyse connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_img)

# Cluster all the intersected bounding box together
rsmall, csmall = np.shape(small_img)
new_img1 = np.zeros((rsmall, csmall), dtype=np.uint8)

fill_rects(new_img1,stats)


# Analyse New connected components to get final regions
num_labels_new, labels_new, stats_new, centroids_new = cv2.connectedComponentsWithStats(new_img1)


labels_disp = np.uint8(200*labels/np.max(labels)) + 50
labels_disp2 = np.uint8(200*labels_new/np.max(labels_new)) + 50



cv2.imshow('diff',img3)
cv2.imshow('small_img',small_img)
cv2.imshow('fat_img',fat_img)
cv2.imshow('bin_img',bin_img)
cv2.imshow("labels",labels_disp)
cv2.imshow("labels_disp2",labels_disp2)
cv2.waitKey(0)

关于image-processing - 如何找到两个图像之间的所有共享区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53640752/

相关文章:

java - 在java中存储图像的最有效方法

ios - 通知服务扩展 - 有关在推送通知上显示图像的问题

image-processing - 开源机器视觉库

opencv - 用opencv突出地板上白色胶带的图像处理技巧

python - 棕褐色过滤器反转

python - 如何将文件夹下的所有bytes文件转换为图片

matlab - 直方图之间的 Kullback-Leibler (KL) 距离 - matlab

algorithm - 如何提取三个主要掌纹

用于查找一组中最相似图像的图像比较算法

python - PIL 的 Image.convert() 函数如何使用模式 'P'