11

我想提取图像的轮廓,表示为一系列点坐标。

Canny能够生成仅包含图像边缘的二进制图像。然后,我试图用它findContours来提取轮廓。但是,结果并不好。

对于每个边缘,我经常得到 2 条线,就像它被认为是一个非常薄的区域一样。我想简化我的轮廓,以便我可以将它们绘制为单线。或者也许使用直接产生正确结果的不同功能提取它们会更好。

我查看了 OpenCV 的文档,但找不到任何有用的东西,但我想我不是第一个遇到类似问题的人。有什么我可以使用的功能或方法吗?

这是我到目前为止编写的 Python 代码:

def main():
    img = cv2.imread("lena-mono.png", 0)

    if img is None:
        raise Exception("Error while loading the image")

    canny_img = cv2.Canny(img, 80, 150)

    contours, hierarchy = cv2.findContours(canny_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    contours_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

    scale = 10
    contours_img = cv2.resize(contours_img, (0, 0), fx=scale, fy=scale)

    for cnt in contours:
        color = np.random.randint(0, 255, (3)).tolist()
        cv2.drawContours(contours_img,[cnt*scale], 0, color, 1)

    cv2.imwrite("canny.png", canny_img)
    cv2.imwrite("contours.png", contours_img)

比例因子用于突出轮廓的双线。以下是图片的链接:

  • 莉娜灰度
  • 提取的边缘Canny
  • 轮廓:10 倍变焦,您可以看到findContours

任何建议将不胜感激。

4

1 回答 1

8

如果我理解正确,那么您的问题与寻找参数 (霍夫变换)意义上的线无关。

相反,这是findContours为单条线返回多个轮廓的方法的问题。

这是因为 Canny 是一个边缘检测器 - 这意味着它与出现在线条两侧的图像强度梯度相匹配。

因此,您的问题更类似于:“如何将低级边缘特征转换为单线?”,或者也许:“如何导航轮廓层次结构以检测单线?”

这是一个相当普遍的话题 - 这是之前的一篇文章,它提出了一个解决方案:

OpenCV 将 Canny 边缘转换为轮廓

于 2014-08-06T08:44:58.857 回答