【发布时间】:2020-04-21 06:01:11
【问题描述】:
我正在尝试检测这张图片中的管道数。为此,我使用 OpenCV 和基于 Python 的检测。基于对类似问题的现有答案,我能够提出以下步骤
- 打开图片
- 过滤它
- 应用边缘检测
- 使用轮廓
- 检查计数
当我们手动计算时,管道的总数为 ~909 给或取 4。
应用过滤器后
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('images/input-rectpipe-1.jpg')
blur_hor = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((11,1,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
blur_vert = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((1,11,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
mask = ((img[:,:,0]>blur_hor*1.2) | (img[:,:,0]>blur_vert*1.2)).astype(np.uint8)*255
我得到了这个蒙版图像
就它显示的可见矩形的数量而言,这看起来相当准确。但是,当我尝试计数并在图片顶部绘制边界框时,它也会选择很多不需要的区域。对于圆,HoughCircles 有一种定义最大和最小半径的方法。矩形是否有类似的东西可以提高准确性。此外,我愿意接受有关此问题的替代方法的建议。
ret,thresh = cv2.threshold(mask,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)
count = 0
for i in range(len(contours)):
count = count+1
x,y,w,h = cv2.boundingRect(contours[i])
rect = cv2.minAreaRect(contours[i])
area = cv2.contourArea(contours[i])
box = cv2.boxPoints(rect)
ratio = w/h
M = cv2.moments(contours[i])
if M["m00"] == 0.0:
cX = int(M["m10"] / 1 )
cY = int(M["m01"] / 1 )
if M["m00"] != 0.0:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
if (area > 50 and area < 220 and hierarchy[0][i][2] < 0 and (ratio > .5 and ratio < 2)):
#cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.circle(img, (cX, cY), 1, (255, 255, 255), -1)
count = count + 1
print(count)
cv2.imshow("m",mask)
cv2.imshow("f",img)
cv2.waitKey(0)
更新 基于第二个答案,我已将 c++ 代码转换为 python 代码并获得了更接近的结果,但仍然遗漏了一些明显的矩形。
【问题讨论】:
-
在你的疯狂图像上,进行扩张操作。然后只检测内部轮廓(第一级)。
-
你能提供你的蒙版图片为 png 吗?
-
我已经用 png 版本更新了问题
-
您对应该检测多少个管道有基本的了解吗?
-
您可以尝试的一件事是调整阈值步骤以改善缺失的检测。查看 Otsu 的阈值或自适应阈值。但是,您当前的解决方案可能是您使用传统图像处理技术所能获得的最佳解决方案。否则,您可以研究深度/机器学习
标签: python opencv image-processing computer-vision object-detection