如何用OpenCV的findContours和drawContours获取无空心单线条轮廓?
解决方案
要实现只填充飞机最外层轮廓、不保留内部空心区域的效果,核心是只提取图像的最外层轮廓,用cv2.RETR_EXTERNAL轮廓检索模式就能直接解决问题,具体步骤和代码如下:
操作步骤
- 读取图像并转灰度图,按你的逻辑完成二值化处理;
- 用
cv2.RETR_EXTERNAL查找轮廓——这个模式只会返回最外层轮廓,自动忽略所有内部嵌套的小轮廓(比如窗户、机翼缝隙); - 直接填充提取到的最外层轮廓即可。
完整代码
import cv2 import numpy as np # 读取原始图像 img = cv2.imread('plane.png') # 转为灰度图 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理:亮度>=120设为白色,否则设为黑色 gray[(gray >= 120)] = 255 gray[(gray < 120)] = 0 cv2.imwrite('plane_gray.png', gray) # 仅提取最外层轮廓 contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 创建空白画布 filled_img = np.zeros(img.shape, dtype=np.uint8) # 填充最外层轮廓(thickness=-1表示填充内部) cv2.drawContours(filled_img, contours, -1, (255, 255, 255), -1) # 保存结果 cv2.imwrite('plane_filled_contour.png', filled_img)
问题原因说明
- 你之前用
cv2.RETR_LIST时,会返回所有层级的轮廓(包括内部小轮廓),填充时会把这些区域也填上,导致出现多余填充块; cv2.RETR_CCOMP需要手动筛选轮廓层级,操作不当容易导致轮廓断裂;cv2.RETR_EXTERNAL是最适配需求的方式,直接过滤掉所有内部轮廓,只保留最外层的飞机主体轮廓。
内容的提问来源于stack exchange,提问作者Hao Huang
相关产品推荐
相关产品推荐

