使用OpenCV识别带有嘈杂背景的不完美形状

时间:2019-06-19 19:11:41

标签: opencv

我正在尝试在嘈杂的环境中识别水下矩形。我实现了Canny来查找边缘,并使用cv2.circle绘制了找到的边缘。从这里开始,我试图识别图像中不完美的矩形(覆盖框架顶部的长矩形下方的黑色矩形)

rectangle

我尝试了多种解决方案,包括阈值,模糊和调整图像大小以检测矩形。下面是仅绘制识别出的边缘的准系统代码。

export GOPATH="$HOME/workspace/go"

输出显示以下内容:

{{3}}

从这里开始,我希望能够分别检测矩形,并在输出的顶部以绿色绘制另一个矩形,但是我一直无法找到一种方法来单独检测原始矩形。

1 个答案:

答案 0 :(得分:2)

对于您的特定图片,我在蓝色通道上进行了简单的阈值处理就获得了很好的结果。

image = cv2.imread("test.png")
t, img = cv2.threshold(image[:,:,0], 80, 255, cv2.THRESH_BINARY)

enter image description here


为了适应阈值,我提出了一种简单的方法来改变阈值,直到获得一个组件为止。我还实现了矩形图:

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)

以及提供的示例图片上的结果:

enter image description here enter image description here enter image description here

此方法背后的想法是基于以下事实:大多数信息位于蓝色通道中。如果将通道中的图像分开,则会在蓝色通道中看到暗正方形具有最佳对比度。这也是该通道上最暗的区域,这就是阈值起作用的原因。问题仍然在于阈值设置。基于以上直觉,我们正在寻找可以提出某些结果的最低阈值(并希望它将是平方)。我要做的就是简单地逐渐增加阈值,直到出现问题为止。

然后,我应用了一些形态学运算以消除阈值后可能出现的其他小点,并使正方形看起来更大(正方形的边缘更亮,因此无法捕获整个正方形)。然后就是绘制矩形的问题。

通过对直方图进行一些统计分析,可以使代码更好(和更有效)。只需计算阈值,以使5%(或某些百分比)的像素更暗。您可能需要进行连接的组件分析,以保持最大的斑点。

此外,我对connectedComponents的使用非常糟糕且效率低下。同样,急于编写代码来证明这一概念。