Python中除OpenCV的cv2.drawContours外填充轮廓的替代方法有哪些
非OpenCV的Python轮廓内部填充实现方案
你可以使用PIL(Pillow)、scikit-image库实现完全等效的轮廓内部填充效果,具体实现方案如下:
1. 基于Pillow的实现
使用Pillow的ImageDraw.polygon方法即可完成单轮廓内部填充,仅需要提前把OpenCV格式的轮廓转换为坐标元组列表:
from PIL import Image, ImageDraw import numpy as np # 入参:a_contour为OpenCV输出的标准轮廓(格式为(N,1,2)的numpy数组) # 转换轮廓为(x,y)元组列表 contour_points = [tuple(pt[0]) for pt in a_contour] # 初始化和原mask同尺寸的单通道图像,背景值为0 pil_mask = Image.new('L', (mask.shape[1], mask.shape[0]), 0) # 执行填充 draw_handler = ImageDraw.Draw(pil_mask) draw_handler.polygon(contour_points, fill=255) # 转换回numpy数组格式 filled_mask = np.array(pil_mask)
相关注意事项:
- 若轮廓存在内部孔洞,可按「外轮廓顺时针排序、内轮廓逆时针排序」的规则拼接所有坐标点后调用
polygon,即可自动排除孔洞区域 - 填充多轮廓只需要循环调用
polygon方法即可,和OpenCV多轮廓填充逻辑一致
2. 基于scikit-image的实现
使用scikit-image的draw.polygon接口生成填充区域的坐标索引,直接对mask对应位置赋值即可:
from skimage import draw import numpy as np # 拆分轮廓的行、列坐标(skimage坐标顺序为(行, 列)) y_coords = a_contour[:, 0, 1] x_coords = a_contour[:, 0, 0] # 生成填充区域的索引 rr, cc = draw.polygon(y_coords, x_coords, shape=mask.shape) # 赋值填充 filled_mask = np.zeros_like(mask) filled_mask[rr, cc] = 255
相关注意事项:
- 处理带孔洞轮廓时,可先完成外轮廓填充,再调用
draw.polygon获取孔洞区域索引,赋值为背景值即可 - 若需要更高性能的多轮廓填充,可批量生成所有轮廓的索引后一次性完成赋值
以上两种方案的输出结果和你当前使用的cv2.drawContours(mask, [a_contour], -1, 255, -1)完全一致,常规图像尺寸下性能无明显差异。
内容的提问来源于stack exchange,提问作者azal
相关产品推荐
相关产品推荐

