我正在尝试在嘈杂的环境中识别水下矩形。我实现了Canny来查找边缘,并使用cv2.circle绘制了找到的边缘。从这里开始,我试图识别图像中不完美的矩形(覆盖框架顶部的长矩形下方的黑色矩形)
我尝试了多种解决方案,包括阈值,模糊和调整图像大小以检测矩形。下面是仅绘制识别出的边缘的准系统代码。
export GOPATH="$HOME/workspace/go"
输出显示以下内容:
{{3}}
从这里开始,我希望能够分别检测矩形,并在输出的顶部以绿色绘制另一个矩形,但是我一直无法找到一种方法来单独检测原始矩形。
答案 0 :(得分:2)
对于您的特定图片,我在蓝色通道上进行了简单的阈值处理就获得了很好的结果。
image = cv2.imread("test.png")
t, img = cv2.threshold(image[:,:,0], 80, 255, cv2.THRESH_BINARY)
为了适应阈值,我提出了一种简单的方法来改变阈值,直到获得一个组件为止。我还实现了矩形图:
def find_square(image):
markers = 0
threshold = 10
while np.amax(markers) == 0:
threshold += 5
t, img = cv2.threshold(image[:,:,0], threshold, 255, cv2.THRESH_BINARY_INV)
_, markers = cv2.connectedComponents(img)
kernel = np.ones((5,5),np.uint8)
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
img = cv2.morphologyEx(img, cv2.MORPH_DILATE, kernel)
nonzero = cv2.findNonZero(img)
x, y, w, h = cv2.boundingRect(nonzero)
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow("image", image)
以及提供的示例图片上的结果:
此方法背后的想法是基于以下事实:大多数信息位于蓝色通道中。如果将通道中的图像分开,则会在蓝色通道中看到暗正方形具有最佳对比度。这也是该通道上最暗的区域,这就是阈值起作用的原因。问题仍然在于阈值设置。基于以上直觉,我们正在寻找可以提出某些结果的最低阈值(并希望它将是平方)。我要做的就是简单地逐渐增加阈值,直到出现问题为止。
然后,我应用了一些形态学运算以消除阈值后可能出现的其他小点,并使正方形看起来更大(正方形的边缘更亮,因此无法捕获整个正方形)。然后就是绘制矩形的问题。
通过对直方图进行一些统计分析,可以使代码更好(和更有效)。只需计算阈值,以使5%(或某些百分比)的像素更暗。您可能需要进行连接的组件分析,以保持最大的斑点。
此外,我对connectedComponents的使用非常糟糕且效率低下。同样,急于编写代码来证明这一概念。