Ann*_*eta 7 python opencv image image-processing computer-vision
我有两张图片,并想让它们之间的区别显而易见。我想为两个图像添加颜色,以便用户可以在一两秒钟内清楚地发现所有差异。
例如,这是两张图片,但有一些区别:
leftImage.jpg:
rightImage.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)
Run Code Online (Sandbox Code Playgroud)
diff.png:
diffOverImage1.png
diffOverImage2.png
当前代码存在问题: 计算出的蒙版显示了一些差异,但不是全部(例如,请参见右上角的细小片段,或蓝色包装袋上的绳子)。这些差异在计算出的蒙版中仅非常轻微地显示出来,但是它们应该像其他差异一样清楚地显示为红色。
输入: 2张图像,有些不同。
预期输出: 3张图像:两个输入图像,但差异突出显示(以可配置的颜色清楚突出显示),第三张图像仅包含差异(遮罩)。
fmw*_*w42 11
如果您愿意使用 Imagemagick,那么您可以使用它的比较工具。由于您的图像是 JPG,因此它们会因每个图像的压缩而显示差异。所以我添加了 -fuzz 15% 以允许 15% 的差异容差而不显示。结果将在图像不同的地方显示红色(默认情况下)。但是颜色是可以改变的。
Linux 附带 Imagemagick。也有适用于 Mac OSX 和 Windows 的版本。
还有 Python Wand,它使用 Imagemagick。
compare -metric rmse -fuzz 25% left.jpg right.jpg diff.png
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用较低的模糊值并使用形态学处理去除噪声并填充一点。
使用转换并首先复制左侧图像并将其变白。然后再次复制左边的图像并用红色填充它。然后复制左侧图像并使用较低的模糊值 10% 与右侧进行差异操作。这将在图像中留下更多噪声,但可以更好地表示真实区域。所以我使用形态平滑来去除噪音。最后,我使用最后一张图像作为蒙版,在变白的左图像上合成红色。
convert left.jpg \
\( -clone 0 -fill white -colorize 50% \) \
\( -clone 0 -fill red -colorize 100 \) \
\( -clone 0 right.jpg -compose difference -composite -threshold 10% -morphology smooth diamond:1 \) \
-delete 0 \
-compose over -composite \
result.png
Run Code Online (Sandbox Code Playgroud)
为了可视化两个图像之间的差异,我们可以采用定量方法,使用图像质量评估中引入的结构相似性指数(SSIM)来确定图像之间的确切差异:从错误可见性到结构相似性。scikit-image库中已经实现了此方法以进行图像处理。您可以安装scikit-image
使用pip install scikit-image
。
使用compare_ssim()
scikit-image中的函数,它返回score
和差异图像diff
。的score
表示两个输入图像之间的结构相似指数和其值更接近的范围[-1,1]之间可降至一个表示更高的相似性。但是,由于您只对两个图像的区别感兴趣,因此diff
我们将重点关注图像。具体地,diff
图像包含实际图像差异,其中较暗的区域具有更大的视差。较大的差异区域以黑色突出显示,而较小的差异以灰色突出显示。
嘈杂的灰色区域可能是由于.jpg有损压缩所致。如果使用无损压缩图像格式,我们将获得更清晰的结果。比较两个图像后的SSIM得分显示它们非常相似。
图像相似度0.9198863419190031
现在我们通过diff
图像进行过滤,因为我们只想查找图像之间的较大差异。我们遍历每个轮廓,使用最小阈值区域进行过滤以消除灰色噪声,并使用边框突出显示差异。这是结果。
为了可视化确切的差异,我们将轮廓填充到蒙版和原始图像上。
from skimage.measure import compare_ssim
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) = compare_ssim(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)
Run Code Online (Sandbox Code Playgroud)
快速识别两个图像之间差异的一种好方法是使用动画GIF,如下所示:
描述了该过程,并在此处提供了代码。它很容易适应Python。照原样,它使用ImageMagick,它已安装在大多数Linux发行版中,并且可用于macOS和Windows。
仅供参考,我在终端中使用了以下命令:
flicker_cmp -o result.gif -r x400 a.jpg b.jpg
Run Code Online (Sandbox Code Playgroud)
小智 5
假设在 image1 中点 image1[x,y] = [10,10,200]。在不同的矩阵中,不同的[x,y] = [0,0,255]。“+”计算后,新值是[10,10,455],这将不起作用,因为R值超过255。
我建议你可以试试
image1[mask != 255] = [0, 0, 255]
image2[mask != 255] = [0, 0, 255]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1779 次 |
最近记录: |