【问题标题】:Efficient contours of a non-binary image非二值图像的有效轮廓
【发布时间】:2021-04-25 19:59:16
【问题描述】:

我有这张图片:

我想得到每个唯一(非零)值的轮廓,所以基本上这个输出:

[array([[1, 1],
        [3, 2],
        [3, 1]], dtype=int32),
 array([[4, 2],
        [4, 3],
        [5, 3],
        [5, 2]], dtype=int32),
 array([[2, 4],
        [3, 4]], dtype=int32)]

我可以通过将图像转换为二进制掩码然后使用cv2findContours 函数来实现这一点,它可以得到我想要的输出。

import numpy as np
import cv2

img = np.array([
    [0,0,0,0,0,0,0],
    [0,1,1,1,0,0,0],
    [0,0,1,1,2,2,0],
    [0,0,0,0,2,2,0],
    [0,0,3,3,0,0,0]
])

contour_list = []

for level in [l for l in np.unique(img) if l != 0]:
    mask = (img == level).astype(np.uint8)
    contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]
    contours[0] = cv2.approxPolyDP(contours[0], 0.5, True)
    contours_xy = contours[0][:, 0]
    contour_list.append(contours_xy)


contour_list

但是,对于具有许多独特级别的大型图像,这种方法速度很慢。有没有办法提高这个功能的速度(没有多处理)?我觉得我忽略了一些功能。

【问题讨论】:

  • 从我的角度来看,您的方法是可行的方法 - 特别是因为您必须处理相互接触的轮廓。如果您不需要稍后的轮廓列表中的“级别信息”,也许您可​​以预处理您的输入图像,例如将所有轮廓设置为相同级别,而无需触及另一个轮廓。但是,我不确定,与您的方法相比,这是否节省了如此多的处理时间。
  • 调整原始图像的大小,执行此过程,然后缩放生成的轮廓以适合原始图像。

标签: python-3.x opencv mask contour opencv-python


【解决方案1】:

调整原始图像的大小,执行此过程,然后缩放生成的轮廓以适合原始图像。

import cv2
import numpy as np

img = cv2.imread('images/multi-level-color.png',0)
img_r = cv2.resize(img,(int(img.shape[1]*0.1),int(img.shape[0]*0.1)))

cv2.imshow('img_r',img_r)
cv2.waitKey(0)

contour_list = []
contour_list_r = []

for level in [l for l in np.unique(img) if l != 0]:
    #mask = (img == level).astype(np.uint8)

    contours = cv2.findContours(img_r, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]
    contours[0] = cv2.approxPolyDP(contours[0], 0.5, True)
    contours_xy = contours[0][:, 0]
    contours_xy_r = contours[0][:, 0]*10

    contour_list.append(contours_xy)
    contour_list_r.append(contours_xy_r)


print("resized 0.1",contour_list[0])

print("resized 10",contour_list_r[0])

原图:

要处理的调整大小的图像:

输出:

调整大小 0.1

[[11 10]
 [11 20]
 [20 20]
 [21 21]
 [21 31]
 [42 31]
 [43 32]
 [43 41]
 [42 42]
 [21 42]
 [21 52]
 [42 52]
 [42 42]
 [43 41]
 [63 41]
 [63 21]
 [43 21]
 [42 20]
 [42 10]]

大小调整为 10

[[110 100]
 [110 200]
 [200 200]
 [210 210]
 [210 310]
 [420 310]
 [430 320]
 [430 410]
 [420 420]
 [210 420]
 [210 520]
 [420 520]
 [420 420]
 [430 410]
 [630 410]
 [630 210]
 [430 210]
 [420 200]
 [420 100]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2011-08-18
    • 2016-07-11
    • 1970-01-01
    • 2021-01-05
    相关资源
    最近更新 更多