我正在开发一款使用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 !")上面的代码只使用两个图像来计算它们的差异,并确定是否存在一个对象,.Please注意,我还没有在这里发布我将在我的项目中使用的原始代码。
现在,上面的代码可以很好地工作在非常受控的情况下,比如说,当图像背景非常恒定或者没有阴影存在的时候。但是考虑到漫游者将会在房间里移动,而且灯光的变化很可能会触发一个虚假的物体检测,即使在框架中没有真正的物体。这种差异可能是由于阴影效应造成的虚假轮廓而触发的。
我想知道,在不做前景/背景图像减法的情况下,是否还有其他方法来实现这一目标检测。我还考虑过使用超声波传感器来检测物体的存在,但这不是一个非常可靠的选择。我更喜欢基于图像处理的解决方案。
谢谢你。
==========================================================================
编辑1 -
所以,我决定稍微改变一下算法。我对前景图像和背景图像都进行了阈值处理,然后在二值图像之间执行缺位,以获得任何帧更改(对象)。守则如下-
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)“缺席”之后是侵蚀和膨胀。在此之后,我找到最大的轮廓,并确定是否有一个对象。该算法所使用的图像如下:
正如你所看到的,检测工作正常。我没有其他的前景图像,我用它来测试算法。他们给出了令人满意的结果,.I想知道,是否还有其他方法能以更好的效率达到同样的效果。
PS-所有前景图像已采取与闪光灯。我试过用Flash关闭,但是图像中似乎存在很多噪音。
=============================================================
编辑2-
用其他图片表演阿尔戈-
注:-背景图像保持不变。
发布于 2018-01-06 17:35:43
我怀疑这个问题是否像你在问题中所描述的那么简单,当我们在现实世界中移动时,它会变得非常复杂。
但是无论如何,假设您的小对象只存在于房间中,那么您可以通过识别所捕获的二进制图像中的连接组件来识别它们,并根据它们的相对像素大小选择它们。
下面是相同的Python实现:
img = cv2.imread('D:/Image/objects.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# binarize the image
ret, bw = cv2.threshold(gray, 128, 255,
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# find connected components
connectivity = 4
nb_components, output, stats, centroids =
cv2.connectedComponentsWithStats(bw, connectivity, cv2.CV_32S)
sizes = stats[1:, -1]; nb_components = nb_components - 1
min_size = 250 #threshhold value for objects in scene
img2 = np.zeros((img.shape), np.uint8)
for i in range(0, nb_components+1):
# use if sizes[i] >= min_size: to identify your objects
color = np.random.randint(255,size=3)
# draw the bounding rectangele around each object
cv2.rectangle(img2, (stats[i][0],stats[i][1]),(stats[i][0]+stats[i][2],stats[i][1]+stats[i][3]), (0,255,0), 2)
img2[output == i + 1] = color包含物体的图像:

使用连接组件标签检测到的对象:

发布于 2018-01-10 07:35:03
您可以考虑的另一种方法是从运动中使用结构,重构环境/点云,而地板上的点簇属于您的对象。还可以将其与背景减法结合起来,以消除错误检测,如阴影一样,对该方法造成问题。
https://stackoverflow.com/questions/48129595
复制相似问题