比较两个不同的图像并找出差异

发布于 2025-01-10 04:52:17 字数 733 浏览 0 评论 0原文

我有一个网络摄像头,可以拍摄混凝土板的照片。现在我想检查平板上是否有物体。对象可以是任何东西,因此不能在类中枚举。不幸的是,我无法直接将网络摄像头图像与混凝土板上没有物体的图像进行比较,因为相机的图像在 x 和 y 方向上的移动可能很小,而且照明也不总是相同。所以我不能使用cv2.substract。 我更喜欢前景和背景减法,其中背景只是我的混凝土板,前景是物体。但由于对象不会移动而是静止在平板上,因此我也无法使用 cv2.createBackgroundSubtractorMOG2() 。

图片如下所示:

没有任何物体的混凝土拍打:

在此处输入图像描述

与对象的耳光:

在此处输入图像描述在此处输入图像描述

I have a webcam which takes pictures of a concrete slab. Now I want to check if there are objects on the slab or not. The objects could be anything and accordingly cannot be enumerated in a class. Unfortunately I cannot compare the webcam image directly with an image without objects on the concrete slab, because the image of the camera could shift minimally in x and y direction and the lighting is also not always the same. So I cannot use cv2.substract.
I would prefer a foreground and background substract, where the background is just my concrete slab and the foreground is then the objects. But since the objects don´t move but lie still on the slab, I can´t use cv2.createBackgroundSubtractorMOG2() either.

The Pictures look like this:

The Concrete slap without any objects:

enter image description here

The slap with Objects:

enter image description hereenter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独夜无伴 2025-01-17 04:52:17

在 Python/OpenCV 中,您可以进行除法归一化以使照明均匀并使背景变白。然后做减法。然后使用形态学来清理小区域。然后找到轮廓并丢弃由于除法归一化和形态学之后留下的噪声造成的任何小区域。

以下是如何进行除法标准化。

输入 1:

在此处输入图像描述

输入 2:

在此处输入图像描述

import cv2
import numpy as np

# load image
img1 = cv2.imread("img1.jpg")
img2 = cv2.imread("img2.jpg")

# convert to grayscale
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

# blur
blur1 = cv2.GaussianBlur(gray1, (0,0), sigmaX=13, sigmaY=13)
blur2 = cv2.GaussianBlur(gray2, (0,0), sigmaX=13, sigmaY=13)

# divide
divide1 = cv2.divide(gray1, blur1, scale=255)
divide2 = cv2.divide(gray2, blur2, scale=255)

# threshold
thresh1 = cv2.threshold(divide1, 200, 255, cv2.THRESH_BINARY)[1]
thresh2 = cv2.threshold(divide2, 200, 255, cv2.THRESH_BINARY)[1]

# morphology
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
morph1 = cv2.morphologyEx(thresh1, cv2.MORPH_OPEN, kernel)
morph2 = cv2.morphologyEx(thresh2, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
morph1 = cv2.morphologyEx(morph1, cv2.MORPH_CLOSE, kernel)
morph2 = cv2.morphologyEx(morph2, cv2.MORPH_CLOSE, kernel)


# write result to disk
cv2.imwrite("img1_division_normalize.jpg", divide1)
cv2.imwrite("img2_division_normalize.jpg", divide2)
cv2.imwrite("img1_division_morph1.jpg", morph1)
cv2.imwrite("img1_division_morph2.jpg", morph2)


# display it
cv2.imshow("img1_norm", divide1)
cv2.imshow("img2_norm", divide2)
cv2.imshow("img1_thresh", thresh1)
cv2.imshow("img2_thresh", thresh2)
cv2.imshow("img1_morph", morph1)
cv2.imshow("img2_morph", morph2)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像 1 标准化:

在此处输入图像描述

图像 2 标准化:

在此处输入图像描述

对图像 1 进行阈值处理和形态学清理:

在此处输入图像描述

对图像 2 进行阈值处理和形态学清理:

在此处输入图像描述

在本例中,图像1 变成全白。所以它(和减法)并不是真正需要的。您只需要找到第二个图像结果的轮廓,并在必要时按面积丢弃微小区域。其余的都是你的对象。

In Python/OpenCV, you could do division normalization to even out the illumination and make the background white. Then do your subtraction. Then use morphology to clean up small regions. Then find contours and discard any small regions that are due to noise left after the division normalization and morphology.

Here is how to do division normalization.

Input 1:

enter image description here

Input 2:

enter image description here

import cv2
import numpy as np

# load image
img1 = cv2.imread("img1.jpg")
img2 = cv2.imread("img2.jpg")

# convert to grayscale
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

# blur
blur1 = cv2.GaussianBlur(gray1, (0,0), sigmaX=13, sigmaY=13)
blur2 = cv2.GaussianBlur(gray2, (0,0), sigmaX=13, sigmaY=13)

# divide
divide1 = cv2.divide(gray1, blur1, scale=255)
divide2 = cv2.divide(gray2, blur2, scale=255)

# threshold
thresh1 = cv2.threshold(divide1, 200, 255, cv2.THRESH_BINARY)[1]
thresh2 = cv2.threshold(divide2, 200, 255, cv2.THRESH_BINARY)[1]

# morphology
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
morph1 = cv2.morphologyEx(thresh1, cv2.MORPH_OPEN, kernel)
morph2 = cv2.morphologyEx(thresh2, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
morph1 = cv2.morphologyEx(morph1, cv2.MORPH_CLOSE, kernel)
morph2 = cv2.morphologyEx(morph2, cv2.MORPH_CLOSE, kernel)


# write result to disk
cv2.imwrite("img1_division_normalize.jpg", divide1)
cv2.imwrite("img2_division_normalize.jpg", divide2)
cv2.imwrite("img1_division_morph1.jpg", morph1)
cv2.imwrite("img1_division_morph2.jpg", morph2)


# display it
cv2.imshow("img1_norm", divide1)
cv2.imshow("img2_norm", divide2)
cv2.imshow("img1_thresh", thresh1)
cv2.imshow("img2_thresh", thresh2)
cv2.imshow("img1_morph", morph1)
cv2.imshow("img2_morph", morph2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Image 1 Normalized:

enter image description here

Image 2 Normalized:

enter image description here

Image 1 thresholded and morphology cleaned:

enter image description here

Image 2 thresholded and morphology cleaned:

enter image description here

In this case, Image 1 becomes completely white. So it (and subtraction) is not really needed. You just need to find contours for the second image result and if necessary discard tiny regions by area. The rest are your objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文