Wat*_*Lab 4 python opencv image image-processing computer-vision
我正在开发一个射击模拟器项目,我必须从图像中检测弹孔。我试图区分两个图像,以便我可以检测图像之间的新漏洞,但它没有按预期工作。在两幅图像之间,由于摄像机帧之间的轻微移动,之前的弹孔有微小的变化。
我的第一张图片在这里
之前.png

第二个在这里
后.png

我尝试使用这段代码来检查差异
import cv2
import numpy as np
before = cv2.imread("before.png") after = cv2.imread("after.png")
result = after - before
cv2.imwrite("result.png", result)
Run Code Online (Sandbox Code Playgroud)
我在 result.png 中得到的结果如下图所示
结果.png

但这不是我所期望的,我只想检测新的孔,但它显示与前一个图像的一些像素的差异。我期待的结果是
预期.png

请帮我弄清楚,这样它只能检测到较大的差异。
提前致谢。
任何新想法都会受到赞赏。
为了找到两个图像之间的差异,您可以利用图像质量评估:从错误可见性到结构相似性中介绍的结构相似性指数(SSIM) 。该方法已在scikit-image库中实现用于图像处理。您可以使用.scikit-imagepip install scikit-image
使用skimage.metrics.structural_similarity()scikit-image 中的函数,它返回一个score和一个差异图像diff。表示score两个输入图像之间的结构相似性指数,可以落在范围 [-1,1] 之间,值越接近表示相似性越高。但由于您只对两个图像的不同之处感兴趣,因此diff您正在寻找的图像。该diff图像包含两个图像之间的实际图像差异。
接下来,我们使用最大cv2.findContours()轮廓来查找所有轮廓并过滤。最大的轮廓应代表新检测到的差异,因为细微的差异应小于添加的项目符号。
这是两幅图像之间检测到的最大差异
这是两个图像之间的实际差异。请注意如何捕获所有差异,但由于新的子弹很可能是最大的轮廓,因此我们可以过滤掉相机帧之间的所有其他轻微移动。
注意:如果我们假设新子弹在图像中具有最大的轮廓,则此方法效果很好diff。如果最新的孔较小,您可能必须遮盖现有区域,并且新图像中的任何新轮廓都将是新孔(假设图像将是带有白孔的均匀黑色背景)。
from skimage.metrics import structural_similarity
import cv2
# Load images
image1 = cv2.imread('1.png')
image2 = cv2.imread('2.png')
# Convert to grayscale
image1_gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2_gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# Compute SSIM between the two images
(score, diff) = structural_similarity(image1_gray, image2_gray, full=True)
# 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] image1 we can use it with OpenCV
diff = (diff * 255).astype("uint8")
print("Image Similarity: {:.4f}%".format(score * 100))
# 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]
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
result = image2.copy()
# The largest contour should be the new detected difference
if len(contour_sizes) > 0:
largest_contour = max(contour_sizes, key=lambda x: x[0])[1]
x,y,w,h = cv2.boundingRect(largest_contour)
cv2.rectangle(result, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.imshow('result', result)
cv2.imshow('diff', diff)
cv2.waitKey()
Run Code Online (Sandbox Code Playgroud)
这是具有不同输入图像的另一个示例。SSIM 非常适合检测图像之间的差异
| 归档时间: |
|
| 查看次数: |
5811 次 |
| 最近记录: |