3

Open CV 将注册多边形轮廓的内部和外部轮廓。

使用下面的测试代码运行

import cv2
import numpy as np

def extract_contours():
    path = 'test.png'
    blank = np.zeros((184,184,3), np.uint8)
    blank[:] = (255,255,255)
    raw = cv2.imread(path, cv2.IMREAD_UNCHANGED)
    raw = 255-raw
    img = cv2.cvtColor(raw, cv2.COLOR_BGR2GRAY)
    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    print(len(contours))
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 400: 
            approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True), True)
            cv2.drawContours(blank, [approx], 0, (0, 0, 255), 1)

    cv2.imwrite('contours.png', blank)

extract_contours()

在图像上

空心正方形

将在外边缘和内边缘上产生两组轮廓,如图所示

双轮廓

有没有什么快速的方法可以将两组轮廓折叠成一个轮廓,最好是两者的平均值?总的来说,我对 CV2 和计算机视觉还很陌生,所以我不知道很多技巧。我宁愿不使用RETR_EXTERNAL,因为我不想错过任何嵌套的形状。

4

1 回答 1

2

您可以使用hierarchy您定义的变量(在调用该cv2.findContours方法时)来确定轮廓是在轮廓的外部还是内部:

import cv2
import numpy as np

def extract_contours():
    path = 'test.png'
    blank = np.zeros((184, 184, 3), np.uint8)
    blank[:] = (255, 255, 255)
    raw = cv2.imread(path, cv2.IMREAD_UNCHANGED)
    raw = 255 - raw
    img = cv2.cvtColor(raw, cv2.COLOR_BGR2GRAY)
    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    for cnt, hrc in zip(contours, hierarchy[0]):
        area = cv2.contourArea(cnt)
        if area > 400: 
            approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True), True)
            if hrc[2] < 0:
                cv2.drawContours(blank, [approx], 0, (0, 0, 255), 1)
            elif hrc[3] < 0:
                cv2.drawContours(blank, [approx], 0, (0, 255, 0), 1)

    cv2.imwrite('contours.png', blank)

extract_contours()

结果图像:

在此处输入图像描述

在外部和内部轮廓之间绘制轮廓:

import cv2
import numpy as np

def extract_contours():
    path = 'test.png'
    blank = np.zeros((184, 184, 3), np.uint8)
    blank[:] = (255, 255, 255)
    raw = cv2.imread(path, cv2.IMREAD_UNCHANGED)
    raw = 255 - raw
    img = cv2.cvtColor(raw, cv2.COLOR_BGR2GRAY)
    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    exte = None
    inte = None
    for cnt, hrc in zip(contours, hierarchy[0]):
        area = cv2.contourArea(cnt)
        if area > 400: 
            approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True), True)
            if hrc[2] < 0:
                exte = approx.squeeze()
            elif hrc[3] < 0:
                inte = approx.squeeze()
    exte = exte[np.lexsort(exte.T)]
    inte = inte[np.lexsort(inte.T)]
    box = cv2.convexHull((exte[exte[:, 0].argsort()] + inte[inte[:, 0].argsort()]) // 2)
    cv2.drawContours(blank, [box], -1, (0, 0, 255), 1)
    cv2.imwrite('contours.png', blank)

extract_contours()

结果图像:

在此处输入图像描述

于 2021-09-30T00:32:38.713 回答