用OpenCV识别有噪声背景的不完美形状

用OpenCV识别有噪声背景的不完美形状,opencv,Opencv,我试图在嘈杂的环境中识别水下的矩形。我实现了Canny来查找边,并使用cv2.circle绘制了找到的边。从这里,我试图识别图像中不完美的矩形(覆盖框架顶部的长矩形下方的黑色矩形) 我尝试了多种解决方案,包括阈值、模糊和调整图像大小以检测矩形。下面是仅绘制已识别边的基本代码 import numpy as np import cv2 import imutils img_text = 'img5.png' img = cv2.imread(img_text) original = img.c

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

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

import numpy as np
import cv2
import imutils

img_text = 'img5.png'
img = cv2.imread(img_text)
original = img.copy()

min_value = 50
max_value = 100

# draw image and return coordinates of drawn pixels
image = cv2.Canny(img, min_value, max_value)
indices = np.where(image != 0)
coordinates = zip(indices[1], indices[0])

for point in coordinates:
    cv2.circle(original, point, 1, (0, 0, 255), -1)

cv2.imshow('original', original)
cv2.waitKey(0)
cv2.destroyAllWindows()
其中输出显示以下内容:


从这里,我希望能够单独检测矩形,并在输出的顶部绘制另一个绿色矩形,但我还没有找到一种方法来检测原始矩形本身。

对于您的特定图像,我在蓝色通道上通过简单的阈值处理获得了相当好的结果

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%(或某些百分比)的像素变暗。您可能需要进行连接组件分析以保持最大的blob


此外,我对connectedComponents的使用非常差且效率低下。同样,为了验证这个概念,我们匆忙编写了代码。

单独检测原始矩形
这是什么意思?我认为OP希望检测到那个黑色矩形,可能希望获得一个包围盒it@nathancy正确。()使用Canny,这些其他矩形被成功拾取。如何才能相应地调整阈值?如果我将范围从图像(…,80255,…)更改为图像(…,100255,…),我就能够拾取矩形。还有其他方法吗?还有,你用canny找到坐标是什么意思?感谢您的帮助您可以使用Canny edge detection,然后使用
findContours()
获得边界框坐标奇妙!谢谢你的时间和帮助。你能提供你为什么/如何想出这种方法的直觉吗?这与我在互联网上看到的完全不同。@CZP3我添加了一些算法的细节。如果我设法得到一些空闲时间,我也会更新它,这样会更好、更方便efficient@Paul92谢谢你的详细解释!!伟大的作品