Python OpenCV背景减法以改进检测
我能够检测到传送带上的鸡蛋,但问题是,如果传送带上没有鸡蛋,算法仍然可以找到对象 在传送带上检测到鸡蛋: 如果皮带上没有鸡蛋: 为了减少错误检测,我正在检查半径和面积:Python OpenCV背景减法以改进检测,python,opencv,computer-vision,Python,Opencv,Computer Vision,我能够检测到传送带上的鸡蛋,但问题是,如果传送带上没有鸡蛋,算法仍然可以找到对象 在传送带上检测到鸡蛋: 如果皮带上没有鸡蛋: 为了减少错误检测,我正在检查半径和面积: if (radius < 100 and radius > 20): .... if area > 2200 and area < 8800: .... 获取背景图像有两个基本选项: 在某些设置/校准过程中,提前获取特定传送带的背景图像 使用数据本身导出背景,为此必须删除对象(鸡
if (radius < 100 and radius > 20):
....
if area > 2200 and area < 8800:
....
获取背景图像有两个基本选项:
第二个选项可以通过获取每个像素随时间变化的平均值或中值来实现。考虑到大多数情况下,每个像素都显示背景,因此在没有对象的情况下,您可以对场景进行合理的估计。您也可以上传背景图像吗?你在减去哪个?我猜问题在于照明,背景图像可能不均匀,因此当照明稍微改变时会产生阴影等,它会检测到它们,因为蛋壳背景就是皮带本身。你的猜测似乎是正确的,但如果我能从图像中删除皮带,我想我只能检测鸡蛋。提供你的代码,没有它我们就不知道你做错了什么。我添加了检测代码。你正在使用大津阈值选择。这意味着无论有没有鸡蛋,你都会找到前景。您最好改用固定阈值。鸡蛋总是白色的吗?或者你也需要处理棕色的鸡蛋?这些可能与输送机的对比度较小,从而使固定阈值不太可靠。
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
th, bw = cv2.threshold(hsv[:, :, 2], 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
morph = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel)
dist = cv2.distanceTransform(morph, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
borderSize = 75
distborder = cv2.copyMakeBorder(dist, borderSize, borderSize, borderSize, borderSize,
cv2.BORDER_CONSTANT | cv2.BORDER_ISOLATED, 0)
gap = 10
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2*(borderSize-gap)+1, 2*(borderSize-gap)+1))
kernel2 = cv2.copyMakeBorder(kernel2, gap, gap, gap, gap,
cv2.BORDER_CONSTANT | cv2.BORDER_ISOLATED, 0)
distTempl = cv2.distanceTransform(kernel2, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
nxcor = cv2.matchTemplate(distborder, distTempl, cv2.TM_CCOEFF_NORMED)
mn, mx, _, _ = cv2.minMaxLoc(nxcor)
th, peaks = cv2.threshold(nxcor, mx*0.5, 255, cv2.THRESH_BINARY)
peaks8u = cv2.convertScaleAbs(peaks)
#fgmask = self.fgbg.apply(peaks8u)
_,contours, hierarchy = cv2.findContours(peaks8u, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
peaks8u = cv2.convertScaleAbs(peaks) # to use as mask
for cnt in contours:
try:
if len(cnt) >= 5:
(x, y), radius = cv2.minEnclosingCircle(cnt)
radius = int(radius)
#print("radius: ", radius)
if (radius < 100 and radius > 20):
ellipse = cv2.fitEllipse(cnt)
(center , axis, angle) = ellipse
cx,cy = int(center[0]),int(center[1])
ax1,ax2 = int(axis[0])-2,int(axis[1])-2
orientation = int(angle)
area = cv2.contourArea(cnt)
if area > 2200 and area < 8800:
cv2.ellipse(frame, (cx,cy), (ax1,ax2), orientation, 0, 360, (255,0,0), 2)
#cv2.circle(frame, (cx,cy), 1, (0, 255, 0), 15)
cv2.putText(frame,str(int(area)),(cx,cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, 0, 1, cv2.LINE_AA)