我有这个 python 代码,据说可以填充图像的轮廓,但其中包含的孔没有填充。这就是我想要的:
但这就是我得到的:
我已经尝试指定轮廓层次结构来填充 cv2,但我无法得到我想要的结果。
这是我试过的:
import numpy as np
import cv2
# Load the PNG image
img = cv2.imread('slice.png')
# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Threshold the image to create a binary image
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
# Find the contours in the binary image
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Create a blank image with the same dimensions as the original image
filled_img = np.zeros(img.shape[:2], dtype=np.uint8)
# Iterate over the contours and their hierarchies
for i, contour in enumerate(contours):
# Check if the contour has a parent
if hierarchy[0][i][3] == -1:
# If the contour doesn't have a parent, fill it with pixel value 255
cv2.drawContours(filled_img, [contour], -1, 255, cv2.FILLED)
# Display the result
cv2.imshow('Original Image', img)
cv2.imshow('Filled Regions', filled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
我尝试修改“if hierarchy[0][i][3] == -1:”部分的 -1、0、1 值,但它要么填充较小的孔,要么填充整个较大的轮廓就像我发布的第一张照片。
问题是
cv2.drawContours
填充了封闭轮廓的整个内部,不管是否有内部轮廓。
我们可以从白色轮廓开始,用黑色填充没有孩子的轮廓,而不是用白色填充轮廓。
假设我们知道内部应该是黑色的,我们可以应用以下阶段:
代码示例:
import numpy as np
import cv2
# Load the PNG image
img = cv2.imread('slice.png')
# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Threshold the image to create a binary image
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
# Find the outer contours in the binary image (using cv2.RETR_EXTERNAL)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Create a blank image with the same dimensions as the original image
filled_img = np.zeros(img.shape[:2], dtype=np.uint8)
# Fill the outer contour with white color
cv2.drawContours(filled_img, contours, -1, 255, cv2.FILLED)
# Find contours with hierarchy, this time use cv2.RETR_TREE
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Iterate over the contours and their hierarchies
for i, contour in enumerate(contours):
# Check if the contour has a parent
if hierarchy[0][i][2] < 0:
# If contour has no child, fill the contour with black color
cv2.drawContours(filled_img, [contour], -1, 0, cv2.FILLED)
# Display the result
cv2.imshow('Original Image', img)
cv2.imshow('Filled Regions', filled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果
filled_img
:注:
如果我们不知道最内层轮廓的颜色,我们可以在黑色背景上绘制白色轮廓,并将结果用作遮罩 - 使用遮罩复制输入图像的原始内容。