我正在使用 Raspberry Pi 开发一个漫游器,它将清扫房间并捡起掉落在地上的物体。为了检测物体,我使用了在流动站操作开始时拍摄的参考图像,以及每 10 秒单击一次的图像(新图像)。为了确定图像帧是否发生变化,我在参考图像和新图像之间进行了图像减法。如果发现任何差异,它会在其周围绘制轮廓,如果轮廓面积大于某个阈值(警告步骤),则得出存在对象的结论。
我正在使用以下代码 -
import numpy as np
import cv2,time
img=cv2.imread("object1.jpg")
img1=cv2.imread("object2.jpg")
sub=cv2.subtract(img,img1)
gray=cv2.cvtColor(sub,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(3,3),0)
_, contours, _= cv2.findContours(blur,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=max(contours,key=cv2.contourArea)
print(cv2.contourArea(c))
if cv2.contourArea>20000:
print("Object detected !")
上面的代码仅使用 2 个图像来计算它们的差异并确定是否存在对象。请注意,我没有在这里发布我将在我的项目中使用的原始代码。
现在,上面的代码适用于非常受控的情况,例如,当图像背景非常恒定或其中不存在阴影时。但考虑到流动站将在房间内移动,即使框架中没有真实物体,照明变化也有可能触发错误的物体检测。这种差异可能是由于阴影效果的错误轮廓而引发的。
我想知道是否有其他方法可以在不进行前景/背景图像减法的情况下实现此对象检测。我还考虑过使用超声波传感器来检测物体的存在,但这不是一个非常可靠的选择。我更喜欢基于图像处理的解决方案。
谢谢 。
=================================================== =======================
EDIT 1 -
所以,我决定稍微改变一下算法。我对前景和背景图像都进行了阈值处理,然后在二进制图像之间执行absdiff,以获得任何帧变化(对象)。
代码如下——
import numpy as np
import cv2,time
img1=cv2.imread("back.jpeg")
blur1 = cv2.GaussianBlur(img1,(5,5),0)
gray1=cv2.cvtColor(blur1,cv2.COLOR_BGR2GRAY)
ret,thresh1 = cv2.threshold(gray1,65,255,cv2.THRESH_BINARY_INV)
img2=cv2.imread("front.jpeg")
blur2 = cv2.GaussianBlur(img2,(5,5),0)
gray2=cv2.cvtColor(blur2,cv2.COLOR_BGR2GRAY)
ret,thresh2 = cv2.threshold(gray2,65,255,cv2.THRESH_BINARY_INV)
diff=cv2.absdiff(thresh2,thresh1)
diff=cv2.bitwise_xor(diff,thresh1)
kernel = np.ones((2,2),np.uint8)
diff=cv2.erode(diff,kernel,iterations = 1)
diff=cv2.dilate(diff,kernel,iterations = 8)
_, contours, _= cv2.findContours(diff,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=max(contours,key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(diff,(x,y),(x+w,y+h),(125,125,125),2)
cv2.imshow("thresh",diff)
cv2.waitKey(0)
“absdiff”之后是 Erosion 和 Dilation 。之后,我找到最大的轮廓并确定是否存在物体。算法中使用的图像如下 -
背景图 -背景图 https://i.stack.imgur.com/3uRGM.jpg
前景图像 -前景图像 https://i.stack.imgur.com/fC8xG.jpg
前景阈值 -前景阈值图像 https://i.stack.imgur.com/OmW5k.png
背景阈值 -背景阈值图像 https://i.stack.imgur.com/ogQ3w.png
差异图像 -具有轮廓及其边界的最终图像。 https://i.stack.imgur.com/iYA9r.png
正如您所看到的,检测工作正常。我几乎没有用来测试算法的其他前景图像。他们给出了令人满意的结果。我想知道是否有其他方法可以以更高的效率达到相同的结果。
PS-所有前景图像都是在闪光灯打开的情况下拍摄的。我尝试过关闭闪光灯,但图像中似乎存在很多噪点。
=================================================== ===========
EDIT 2-
使用其他图片的算法的性能 -
注意:- 背景图像保持不变。
- 对象 1 -前景图像 1 https://i.stack.imgur.com/pzupl.jpg
- 对象 1 检测 -前景图像 1 结果 https://i.stack.imgur.com/3KMxm.png