【问题标题】:OpenCV, cv2.approxPolyDP() Draws double lines on closed contourOpenCV, cv2.approxPolyDP() 在闭合轮廓上绘制双线
【发布时间】:2020-06-24 12:12:36
【问题描述】:

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

图片 1 - 面具

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

图像 2 - 轮廓

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

图像 3 - 多边形

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

查看我的代码:

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")

【问题讨论】:

    标签: python opencv polygon mask opencv-contour


    【解决方案1】:

    问题来源是Canny edges检测:

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

    您可以通过应用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")
    

    结果:

    【讨论】:

      【解决方案2】:

      opencv findcontour 建议根据 opencv-tutorials 组合 cv2.canny,使用阈值图像代替它会影响准确性。也许尝试形态学

      【讨论】:

        猜你喜欢
        • 2017-05-25
        • 2021-09-07
        • 2016-10-21
        • 2023-03-18
        • 2014-09-28
        • 1970-01-01
        • 2021-01-17
        • 1970-01-01
        相关资源
        最近更新 更多