【发布时间】:2017-05-11 17:34:27
【问题描述】:
我有一个盒子,前面是透明的,我将相机放在前面的透明面板上以捕捉内部的图像,大多数时候盒子是空的,但假设有人在这个盒子里放了一个物体,那么我必须从捕获的图像中提取这个对象。
(我的真正目的是识别盒子内的物体,但第一步是提取物体,然后提取特征以生成训练模型,目前我只专注于从图像中提取物体)
我是 OpenCV 新手,将它与 Python 一起使用,我发现很少有 OpenCV 函数可以帮助我。
- GrabCut,这对我来说非常有效,我可以只提取 对象,前提是,我在对象上标记矩形,但作为 对象可以在框内的任何位置,因此无法绘制 对象的确切大小矩形,如果有办法请给我建议。
- 图像的差异,因为我有空腔框图像并且当 对象存在,我可以使用 cv2.absdiff 函数来计算 图像之间的差异,但这在大多数情况下都无法正常工作 在这种情况下,因为它使用逐像素差异计算,以及 由于这个结果很奇怪,加上光照条件的变化 让事情变得困难。
- 背景减法,我读了几篇关于这个的帖子,看起来这是 我需要什么,但我得到的例子是视频,我没有 了解如何让它只处理两张图片,一张是空框,另一张是对象。
背景减法的代码如下,即使它在短距离上也不能正常工作
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
fgbg2 = cv2.createBackgroundSubtractorKNN()
while True:
ret, frame = cap.read()
cv2.namedWindow('Real', cv2.WINDOW_NORMAL)
cv2.namedWindow('MOG2', cv2.WINDOW_NORMAL)
cv2.namedWindow('KNN', cv2.WINDOW_NORMAL)
cv2.namedWindow('MOG2_ERODE', cv2.WINDOW_NORMAL)
cv2.namedWindow('KNN_ERODE', cv2.WINDOW_NORMAL)
cv2.imshow('Real', frame)
fgmask = fgbg.apply(frame)
fgmask2 = fgbg2.apply(frame)
kernel = np.ones((3,3), np.uint8)
fgmask_erode = cv2.erode(fgmask,kernel,iterations = 1)
fgmask2_erode = cv2.erode(fgmask2,kernel,iterations = 1)
cv2.imshow('MOG2',fgmask)
cv2.imshow('KNN',fgmask2)
cv2.imshow('MOG2_ERODE',fgmask_erode)
cv2.imshow('KNN_ERODE',fgmask2_erode)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
任何人都可以在这个主题上提供帮助,以及如何修改上面的代码以仅使用两个图像,当我尝试时我得到空白图像。提前致谢
来自相机的示例图像如下: (我使用的是 8MP 相机,所以图像尺寸很大,我缩小了尺寸,然后在这里上传)
【问题讨论】:
-
为了提高 GrabCut 的性能,执行边缘检测以获取框的边缘。获得后,您可以拟合一个矩形,然后执行 GrabCut
-
如果您不提供图像,您希望人们如何帮助您完成图像处理任务?
-
@JeruLuke:谢谢,我刚刚更新了一些示例图片,并会尝试您的建议。
-
@m3h0w:我刚刚更新了三张图片,一张是空盒子,另外两张是两个午餐盒。
-
@xpress_embedo 所以您主要询问图像差异和背景减法,然后您接受使用边缘的答案? Jeru Luke 的解决方案既酷又有趣,但它真的回答了您的问题并提供了您需要的可靠性吗?
标签: python opencv image-processing