python - OpenCV, cv2.approxPolyDP() 在闭合轮廓上绘制双线

标签 python opencv polygon mask contour

我想用这个蒙版创建一些多边形:

图片 1 - 面具 Mask

所以我用 openCV findcontours() 创建了这些轮廓:

图片 2 - 轮廓

Contours

创建多边形时,我得到这些多边形:

图 3 - 多边形 Polygons

如您所见,一些多边形是使用双线绘制的。我该如何防止这种情况?

查看我的代码:

import glob
from PIL import Image
import cv2
import numpy as np


# Let's load
image = cv2.imread(path + "BigOneEnhanced.tif") 

# Grayscale 
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 

# Find Canny edges 
edged = cv2.Canny(gray, 30, 200) 

# Finding Contours 
contours, hierarchy = cv2.findContours(edged,  
    cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1) 

canvas = np.zeros(image.shape, np.uint8)

# creating polygons from contours

polygonelist = []

for cnt in contours:

    # define contour approx
    perimeter = cv2.arcLength(cnt,True)
    epsilon = 0.005*cv2.arcLength(cnt,True)
    approx = cv2.approxPolyDP(cnt,epsilon,True)


    polygonelist.append(approx)

cv2.drawContours(canvas, polygonelist, -1, (255, 255, 255), 3)


imgB = Image.fromarray(canvas)
imgB.save(path + "TEST4.png")

最佳答案

问题来源是Canny边缘检测:

应用边缘检测后,每个原始轮廓都会得到两个轮廓 - 一个在边缘外,一个在边缘内(以及其他奇怪的东西)。

您可以通过应用 findContours 而不使用 Canny 来解决它。

代码如下:

import glob
from PIL import Image
import cv2
import numpy as np

path = ''

# Let's load
#image = cv2.imread(path + "BigOneEnhanced.tif") 
image = cv2.imread("BigOneEnhanced.png") 

# Grayscale 
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 

# Apply threshold (just in case gray is not binary image).
ret, thresh_gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# Find Canny edges 
#edged = cv2.Canny(gray, 30, 200)

# Finding Contours cv2.CHAIN_APPROX_TC89_L1
#contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

contours, hierarchy = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

canvas = np.zeros(image.shape, np.uint8)

# creating polygons from contours
polygonelist = []

for cnt in contours:
    # define contour approx
    perimeter = cv2.arcLength(cnt, True)
    epsilon = 0.005*perimeter #0.005*cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, epsilon, True)

    polygonelist.append(approx)

cv2.drawContours(canvas, polygonelist, -1, (255, 255, 255), 3)

imgB = Image.fromarray(canvas)
imgB.save(path + "TEST4.png")

结果:
enter image description here

关于python - OpenCV, cv2.approxPolyDP() 在闭合轮廓上绘制双线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60654186/

相关文章:

python - 更改一系列数据框中元素的值python

python - 我的代码另一个错误

python - 如何单步执行 Ipython 中的 help() 文本?

python-3.x - Python OpenCV - 如何保存 5 channel 图像

iphone - 创建特定大小的 UIImage

python - 如何将列表中的元素组合到一个新的嵌套列表中?

Python - 将多个相同维度的二维数组合并为一个二维数组

android - 传递简历 :Mat from android to jni

java - 如何通过翻转数组来翻转多边形?

javascript - 绘制多边形