numpy数组的轮廓检测

Contour detection of a numpy array

我是计算机视觉领域的新手,我目前正在 python 上处理 0 和 1 的 numpy 数组,如下所示:

我试图找到由等于 1 的单元格形成的形状的轮廓,结果应该是这样的:

我希望能够按照特定顺序(例如逆时针)获得以绿色突出显示的每个元素的位置。 我尝试按照我在网上找到的一些示例在 python 中使用 OpenCV 的 findContours 函数,但没有成功:

# Import
import numpy as np
import cv2
# Find contours
tableau_poche = np.array([[1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [1., 1., 1., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.]])
tableau_poche = np.int8(tableau_poche)
contours, hierarchy = cv2.findContours(tableau_poche, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

我收到以下消息:

error: OpenCV(4.0.1) C:\ci\opencv-suite_1573470242804\work\modules\imgproc\src\thresh.cpp:1492: error: (-210:Unsupported format or combination of formats) in function 'cv::threshold'

实际上,我不知道我是否应该使用这个 OpenCV 函数(也许“matplotlib.pyplot.contour()”函数也可以解决我的问题......)或者是否可以使用它在我拥有的 numpy 数组上。在不久的将来,我可能会对 OpenCV 在我的 numpy 数组上的 convexityDefects 函数感兴趣。

您遇到了类型问题。此 OpenCV 函数仅适用于无符号整数 uint8。您的数组使用有符号整数 int8.

只需替换:
tableau_poche = np.int8(tableau_poche)
通过
tableau_poche = tableau_poche.astype(np.uint8)

并且 findContour() 将起作用。

正如评论中指出的那样,您可以通过更改 findContour() 的属性来获得您想要的(或非常接近)。通过使用 cv2.CHAIN_APPROX_NONE 而不是 cv2.CHAIN_APPROX_SIMPLE,它将为您提供轮廓的所有点。但是,对于距离为 1 的任何像素,它在垂直、水平 和对角线上 工作。因此它不是您问题的 100%,因为它“削减”了角落。 有关选项 ContourApproximationModes

的更多信息,请参阅此处的文档