opencv-python 如何用白色填充特定区域?
我正在尝试使用 cv2.findContours() 中的轮廓制作蒙版。 但无法找到填充这两个特定区域的方法。
(cv2.drawContours(thickness = -1) 没有像我预期的那样工作。)
示例:
答案 0 :(得分:2)
您可以构建一个轮廓层次树并迭代该树,直到达到内部轮廓。
在您的情况下,层次结构是:
我们可以使用以下阶段:
代码如下:
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.