当前位置: 首页 > 知识库问答 >
问题:

用OpenCV Python实现两幅图像差异的检测和可视化

邬飞捷
2023-03-14

我有两个图像,想让它明显的差异在哪里。我想添加颜色的两个图像,这样用户可以清楚地发现所有的差异在一两秒钟内。

例如,以下是两个有一些不同之处的图像:

jpg:

我目前的方法使差异明显,是创建一个蒙版(两个图像之间的差异),把它涂成红色,然后把它添加到图像中。目标是用强烈的红色清晰地标记所有的差异。下面是我当前的代码

import cv2

# load images
image1 = cv2.imread("leftImage.jpg")
image2 = cv2.imread("rightImage.jpg")

# compute difference
difference = cv2.subtract(image1, image2)

# color the mask red
Conv_hsv_Gray = cv2.cvtColor(difference, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(Conv_hsv_Gray, 0, 255,cv2.THRESH_BINARY_INV |cv2.THRESH_OTSU)
difference[mask != 255] = [0, 0, 255]

# add the red mask to the images to make the differences obvious
image1[mask != 255] = [0, 0, 255]
image2[mask != 255] = [0, 0, 255]

# store images
cv2.imwrite('diffOverImage1.png', image1)
cv2.imwrite('diffOverImage2.png', image1)
cv2.imwrite('diff.png', difference)

diff.png:

DiffoverImage1.PNG

共有1个答案

师建德
2023-03-14

为了可视化两幅图像之间的差异,我们可以利用图像质量评价中引入的结构相似度指数(SSIM)来定量地确定图像之间的准确差异:从误差可见性到结构相似度。该方法已经在用于图像处理的scikit-image库中实现。您可以使用PIP安装scikit-image安装scikit-image

使用scikit-image中的structural_simality()函数,它返回score和差异图像diffscore表示两个输入图像之间的结构相似性指数,可以在[-1,1]范围内,其值更接近一,表示更高的相似性。但是由于您只对这两个图像的不同之处感兴趣,所以我们将重点关注diff图像。具体地说,diff图像包含实际的图像差异,较暗的区域具有更大的差异。较大的差异区域用黑色突出,而较小的差异用灰色突出。

灰色噪声区域可能是由于。jpg有损压缩。如果我们使用无损压缩图像格式,我们将获得更干净的结果。两幅图像比较后的SSIM评分显示它们非常相似。

图像相似度0.9198863419190031

现在我们通过diff图像进行过滤,因为我们只想找出图像之间的巨大差异。我们迭代每个轮廓,用一个最小阈值区域滤波去除灰度噪声,并用一个包围盒突出差异。结果是这样的。

为了显示确切的差异,我们将轮廓填充到蒙版和原始图像上。

from skimage.metrics import structural_similarity
import cv2
import numpy as np

before = cv2.imread('left.jpg')
after = cv2.imread('right.jpg')

# Convert images to grayscale
before_gray = cv2.cvtColor(before, cv2.COLOR_BGR2GRAY)
after_gray = cv2.cvtColor(after, cv2.COLOR_BGR2GRAY)

# Compute SSIM between two images
(score, diff) = structural_similarity(before_gray, after_gray, full=True)
print("Image similarity", score)

# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1] 
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")

# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

mask = np.zeros(before.shape, dtype='uint8')
filled_after = after.copy()

for c in contours:
    area = cv2.contourArea(c)
    if area > 40:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(before, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.rectangle(after, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.drawContours(mask, [c], 0, (0,255,0), -1)
        cv2.drawContours(filled_after, [c], 0, (0,255,0), -1)

cv2.imshow('before', before)
cv2.imshow('after', after)
cv2.imshow('diff',diff)
cv2.imshow('mask',mask)
cv2.imshow('filled after',filled_after)
cv2.waitKey(0)

 类似资料:
  • 我正在编写一个应用程序,它需要监听麦克风并给我一个实时的振幅和音调输出。我已经找到了如何进行音高识别的方法。我对fft做了很多研究。找到了Android库TarsosDSP wich,使听音高变得非常简单: 我还研究了如何使用内置android进行振幅检测。GetMaxAmplific()方法。 但我的问题是,我一辈子都不知道如何同时做这两件事。问题是你显然可以运行多个麦克风实例。就像你试图在不同

  • 下面是我的解决方案,但我不清楚“删除”的情况下代码应该是什么样子 删除字符的代码应该是什么样子的? 更新-添加了更多的示例 下面是Dmitry和Ingen答案的比较:https://dotnetfiddle.net/mjqdao

  • 我正在尝试学习opencv,但它非常混乱。有人能知道imagedepth和图像中通道数之间的区别吗。假设图像深度为8,通道R、G、B的数量为3。那么,这意味着什么,我很难可视化三维结构

  • 如何创建一个可以包含多个图像并包含圆形边框的视图?以下是一些最终产品的样本。 图像将从url下载,如示例所示,视图中可能包含一到四个图像。

  • 问题内容: 我正在尝试匹配两个图像的直方图(在MATLAB中,这是可以做到的) 使用 ). 标准Python库中是否有可用的等效函数?我已经 查看了OpenCV、scipy和numpy,但没有看到任何类似的功能。 问题答案: 我以前写过一个答案 这里解释如何做 图像直方图的分段线性插值 高光/中音/阴影的特定比率。 相同的基本原则是[直方图]的基础 匹配两人之间 图像。基本上,你要计算出你的源和目

  • 我有两种纹理。一个是jpg,一个是PNG。我已经渲染了一个立方体,我想使用jpg图像作为背景在立方体的每一个面,然后在这个背景上有png。我尝试了,但我可以通过png看到背景,我不希望这样。有没有什么功能可以为我做到这一点? 片段着色器: 是png,是JPG。

  • 嗨,我想实现,就像,我想把它放在列表中,这样每个元素都可以被刷, 在这里,和在向右滑动时将不可见,view1将像视图分页一样可见。 我尝试使用,但它在滑动时不显示隐藏视图。 为了实现这一点,我想使用源代码,viewpager.java基本上是,但是我不能将view Group添加到listview中。我尝试了swipeListView,但也没有帮助。 谁能帮助我如何实现它呢