【问题标题】:fill areas with color in opencv-python在opencv-python中用颜色填充区域
【发布时间】:2021-06-23 05:44:59
【问题描述】:

如何在opencv-python中用白色填充特定区域?

我正在尝试使用 cv2.findContours() 中的轮廓制作一个蒙版。 但是找不到填充这两个特定区域的方法。

(cv2.drawContours(thickness = -1) 没有按我的预期工作。)

示例:

发件人:

收件人:

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    您可以构建轮廓层次结构树并迭代树,直到到达内部轮廓。

    请参阅:Contours Hierarchy

    在您的情况下,层次结构是:

    • 圆的外部。
    • 圆的内部(内部标记为单独的轮廓)。
    • 内轮廓大,小轮廓少。
      我们要填充小轮廓而不是大轮廓。

    我们可以使用以下阶段:

    • 查找轮廓和层次结构,使用 RETR_TREE 在轮廓内创建轮廓树。
    • 找到面积最大的轮廓(假设圆是最大的轮廓)- 父轮廓。
    • 找到父轮廓的子轮廓的子轮廓。
    • 迭代兄弟姐妹,找到面积最大的兄弟姐妹(我们需要忽略它)。
    • 再次迭代兄弟姐妹并填充所有兄弟姐妹的轮廓,除了最大的轮廓。

    代码如下:

    import numpy as np
    import cv2
    
    # Read input image
    img = cv2.imread('input.png', cv2.IMREAD_GRAYSCALE)
    
    # Apperanly there is a white rectangle around the image - crop the inner area.
    img = img[4:-4, 4:-4]
    
    
    # Find contours and hierarchy, use RETR_TREE for creating a tree of contours within contours
    cnts, hiers = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:]  # [-2:] indexing takes return value before last (due to OpenCV compatibility issues).
    
    img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)  # Convert image to BGR for testing - fill contours with green color.
    
    # https://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html
    # Hierarchy Representation in OpenCV
    # Each contour has its own information regarding what hierarchy it is, who is its child, who is its parent etc. 
    # OpenCV represents it as an array of four values : [Next, Previous, First_Child, Parent]
    hiers = hiers[0]  # Remove redundant dimension of hiers.
    
    # Find contour with the maximum area (assume the circle is the largest contour).
    c = max(cnts, key=cv2.contourArea)
    
    parent_idx = cnts.index(c)
    
    parent_hier = hiers[parent_idx]  # Get the first outer contour - assume there is only one in our case.
    parent_idx = parent_hier[2]  # Index of the first child.
    parent_hier = hiers[parent_idx] # Ooops - the inner contour is the inner part of the circle - need one more inner hierarchy
    
    child_idx = parent_hier[2]  # Index of the first child
    
    # Iterate all childes and find the contour with the maximum area - we need to ignore it.
    max_area = 0
    while child_idx != -1:
        child_hier = hiers[child_idx]  # Next child in hierarchy
        c = cnts[child_idx]  # Get the contour with the same index
        area = cv2.contourArea(c)
        max_area = max(area, max_area)
        child_idx = child_hier[0]  # Get index of next contour in the same hierarchy of the child.
    
    
    child_idx = parent_hier[2]  # Index of the first child
    
    # Iterate all childes (there are supposed to be three "large" childes and few small childes in our case).
    while child_idx != -1:
        child_hier = hiers[child_idx]  # Next child in hierarchy
        c = cnts[child_idx]  # Get the contour with the same index
    
        if cv2.contourArea(c) < max_area:
            # Fill the contour with green color
            cv2.drawContours(img, [c], -1, (0, 255, 0), -1)
    
        child_idx = child_hier[0]  # Get index of next contour in the same hierarchy of the child.
    

    结果:

    【讨论】:

      猜你喜欢
      • 2020-11-13
      • 2012-10-13
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多