【OpenCV】Python图像处理之查找并绘制轮廓
本文旨在帮助掌握 OpenCV-Python 中图像轮廓的查找与绘制方法轮廓是图像中连续的、具有相同像素值的边界曲线是图像分割、目标检测、形状分析的核心工具。OpenCV 中通过cv2.findContours()查找轮廓cv2.drawContours()绘制轮廓核心流程是图像预处理二值化→ 查找轮廓 → 绘制轮廓下面会从原理、完整流程、API 详解、实战示例和高级应用逐步讲解内容贴合实际开发需求。一、轮廓的核心概念轮廓是二值图像中白色前景的边界黑色为背景因此查找轮廓前必须将图像转为二值图灰度→阈值分割 / 边缘检测轮廓与边缘的区别边缘是离散的像素点轮廓是连续的闭合曲线且轮廓只针对前景区域轮廓的层级图像中轮廓可能存在嵌套关系如大矩形内有小矩形OpenCV 会记录轮廓的父子层级关系便于筛选内外轮廓。二、核心 API 详解1. 查找轮廓cv2.findContours()函数原型OpenCV4 版本返回值简化为 2 个轮廓和层级contours, hierarchy cv2.findContours(image, mode, method)关键参数参数作用常用值image输入图像必须是二值图uint8 类型黑白建议对原二值图做复制函数会修改原图mode轮廓检索模式控制查找的轮廓范围和层级cv2.RETR_EXTERNAL仅检索最外层轮廓最常用cv2.RETR_LIST检索所有轮廓不建立层级cv2.RETR_CCOMP检索所有轮廓建立两层层级外 / 内cv2.RETR_TREE检索所有轮廓建立完整的树形层级method轮廓逼近方法压缩轮廓点减少冗余cv2.CHAIN_APPROX_NONE保存所有轮廓点精度最高数据量大cv2.CHAIN_APPROX_SIMPLE压缩水平 / 垂直 / 对角线仅保存端点如矩形只存 4 个角点最常用返回值contours轮廓列表每个轮廓是N×1×2的 NumPy 数组存储轮廓的 (x,y) 坐标点hierarchy层级数组形状为1×N×4每个轮廓对应 4 个值[next, prev, child, parent]分别表示「下一个轮廓、上一个轮廓、子轮廓、父轮廓」无对应轮廓时为 - 1。2. 绘制轮廓cv2.drawContours()函数原型img cv2.drawContours(image, contours, contourIdx, color, thicknessNone, lineTypeNone, hierarchyNone, maxLevelNone, offsetNone)关键参数参数作用常用值image绘制的目标图像建议用彩色图方便看轮廓直接修改原图可提前复制contours待绘制的轮廓列表即cv2.findContours()的返回值contourIdx绘制的轮廓索引-1绘制所有轮廓具体数字如 0、1绘制指定索引的轮廓color轮廓颜色BGR 格式如(0,255,0)绿色、(0,0,255)红色thickness轮廓线宽正数线宽如 2-1填充轮廓内部绘制实心形状maxLevel绘制的轮廓层级配合hierarchy使用0仅绘制当前轮廓1绘制当前 子轮廓三、查找并绘制轮廓的标准流程所有轮廓操作的基础是高质量的二值图预处理不到位会导致轮廓检测混乱标准步骤如下读取图像转为灰度图cv2.cvtColor()图像预处理可选去噪cv2.GaussianBlur()避免噪声被检测为轮廓二值化cv2.threshold()/cv2.adaptiveThreshold()将图像转为黑白突出前景可选形态学运算cv2.dilate()/cv2.erode()膨胀填充前景孔洞腐蚀去除微小噪声查找轮廓cv2.findContours()复制二值图避免被修改绘制轮廓cv2.drawContours()用彩色图绘制方便可视化显示 / 保存结果。基础实现代码最常用场景检测外轮廓并绘制import cv2 import numpy as np import matplotlib.pyplot as plt # 1. 读取图像并转灰度 img cv2.imread(shape.jpg) # 读取彩色图用于后续绘制轮廓 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imshow(Gray, gray) # 2. 预处理高斯去噪 二值化关键让前景和背景分离 blur cv2.GaussianBlur(gray, (3, 3), 0) # 去噪避免噪声干扰轮廓检测 # 二值化大于127设为255白前景小于设为0黑背景THRESH_BINARY_INV为反向 ret, binary cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY) cv2.imshow(Binary, binary) # 3. 查找轮廓仅找外轮廓压缩轮廓点最常用参数组合 # 注意传入binary的复制避免函数修改原二值图 contours, hierarchy cv2.findContours(binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) print(f检测到的轮廓数量{len(contours)}) # 4. 绘制轮廓在彩色原图的复制上绘制绿色线宽2绘制所有轮廓 img_contour img.copy() cv2.drawContours(img_contour, contours, -1, (0, 255, 0), 2) # 5. 显示结果 cv2.imshow(Contour, img_contour) cv2.waitKey(0) cv2.destroyAllWindows()四、关键优化形态学运算优化二值图如果二值图存在前景孔洞或微小噪声点会导致检测到多余轮廓或轮廓不闭合此时用形态学膨胀 / 闭运算优化# 二值化后添加形态学运算 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 闭运算膨胀→腐蚀填充前景内部的小孔洞 binary_close cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) # 膨胀让前景轮廓更连续可选根据图像调整 # binary_dilate cv2.dilate(binary_close, kernel, iterations1) # 再查找轮廓 contours, hierarchy cv2.findContours(binary_close.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)五、实战常见需求1. 绘制单个轮廓 填充轮廓内部img_contour img.copy() # 绘制第0个轮廓红色线宽3 cv2.drawContours(img_contour, contours, 0, (0, 0, 255), 3) # 绘制第1个轮廓蓝色填充内部thickness-1 cv2.drawContours(img_contour, contours, 1, (255, 0, 0), -1) cv2.imshow(Single Filled Contour, img_contour)2. 筛选轮廓按面积 / 周长实际开发中噪声会被检测为小轮廓可通过轮廓面积cv2.contourArea()或轮廓周长cv2.arcLength()筛选有效轮廓img_filter img.copy() valid_contours [] # 存储有效轮廓 for cnt in contours: # 计算轮廓面积 area cv2.contourArea(cnt) # 计算轮廓周长True表示轮廓闭合 perimeter cv2.arcLength(cnt, True) # 筛选面积大于100的轮廓阈值根据图像调整 if area 100: valid_contours.append(cnt) # 在轮廓旁绘制面积值 # 获取轮廓的外接矩形确定文字位置 x, y, w, h cv2.boundingRect(cnt) cv2.putText(img_filter, fArea:{int(area)}, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1) # 绘制筛选后的有效轮廓 cv2.drawContours(img_filter, valid_contours, -1, (0,255,0), 2) print(f筛选后的有效轮廓数量{len(valid_contours)}) cv2.imshow(Filtered Contour, img_filter)3. 绘制轮廓的外接矩形 / 外接圆目标定位轮廓的外接矩形 / 外接圆是目标定位的常用手段结合cv2.boundingRect()外接矩形、cv2.minEnclosingCircle()最小外接圆实现img_outer img.copy() for cnt in valid_contours: # 绘制外接矩形绿色 x, y, w, h cv2.boundingRect(cnt) cv2.rectangle(img_outer, (x,y), (xw,yh), (0,255,0), 2) # 绘制最小外接圆红色 (x_c, y_c), r cv2.minEnclosingCircle(cnt) center (int(x_c), int(y_c)) radius int(r) cv2.circle(img_outer, center, radius, (0,0,255), 2) cv2.imshow(Outer Shape, img_outer)4. 检测嵌套轮廓绘制内外轮廓使用cv2.RETR_TREE检索所有层级轮廓结合hierarchy区分内外轮廓父轮廓parent-1子轮廓parent≥0# 重新查找所有轮廓建立树形层级 contours, hierarchy cv2.findContours(binary_close.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) img_tree img.copy() for i, cnt in enumerate(contours): # 父轮廓索引hierarchy[0][i][3] parent hierarchy[0][i][3] if parent -1: # 无父轮廓 → 外层轮廓绿色 cv2.drawContours(img_tree, contours, i, (0,255,0), 2) else: # 有父轮廓 → 内层轮廓红色 cv2.drawContours(img_tree, contours, i, (0,0,255), 2) cv2.imshow(Inner Outer Contour, img_tree)六、高级应用轮廓的形状识别通过轮廓的逼近多边形cv2.approxPolyDP()判断形状如三角形、矩形、圆形核心原理是用最少的点逼近轮廓点的数量对应形状的边数img_shape img.copy() for cnt in valid_contours: perimeter cv2.arcLength(cnt, True) # 轮廓逼近epsilon为周长的0.04倍阈值越小逼近越接近原轮廓 epsilon 0.04 * perimeter approx cv2.approxPolyDP(cnt, epsilon, True) # 获取逼近后的顶点数量 vertex_num len(approx) # 判断形状 if vertex_num 3: shape Triangle elif vertex_num 4: # 4个顶点判断是否为正方形长宽比接近1 x, y, w, h cv2.boundingRect(approx) ratio w / float(h) shape Square if 0.95 ratio 1.05 else Rectangle elif vertex_num 6: shape Circle else: shape Other # 绘制逼近多边形形状文字 cv2.drawContours(img_shape, [approx], 0, (0,255,0), 2) cv2.putText(img_shape, shape, (cnt[:,0,0].min(), cnt[:,0,1].min()-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 1) cv2.imshow(Shape Recognition, img_shape)七、常见问题与解决方案检测不到轮廓二值图前景 / 背景颠倒改用cv2.THRESH_BINARY_INV反向二值化图像有噪声增加高斯去噪或形态学运算轮廓是黑色二值图必须白色为前景黑色为背景。检测到大量冗余小轮廓按轮廓面积 / 周长筛选或增大形态学腐蚀的核尺寸。轮廓不闭合用形态学闭运算填充轮廓间隙或调整二值化阈值。OpenCV3 和 OpenCV4 的 API 差异OpenCV3image, contours, hierarchy cv2.findContours(...)多返回一个修改后的图像OpenCV4contours, hierarchy cv2.findContours(...)推荐简化返回值。八、完整综合示例轮廓检测 筛选 形状识别 绘制import cv2 import numpy as np # 1. 读取图像并预处理 img cv2.imread(shape_mix.jpg) if img is None: raise ValueError(图像读取失败请检查路径) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur cv2.GaussianBlur(gray, (3, 3), 0) ret, binary cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY) # 2. 形态学优化二值图 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) binary_close cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) # 3. 查找外轮廓 contours, hierarchy cv2.findContours(binary_close.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 4. 筛选有效轮廓形状识别绘制 img_result img.copy() valid_contours [] for cnt in contours: area cv2.contourArea(cnt) if area 50: # 筛选面积大于50的轮廓 valid_contours.append(cnt) # 轮廓逼近 perimeter cv2.arcLength(cnt, True) epsilon 0.04 * perimeter approx cv2.approxPolyDP(cnt, epsilon, True) vertex_num len(approx) # 判断形状 if vertex_num 3: shape Triangle color (0, 255, 0) elif vertex_num 4: x, y, w, h cv2.boundingRect(approx) ratio w / float(h) shape Square if 0.95 ratio 1.05 else Rectangle color (0, 0, 255) elif vertex_num 6: shape Circle color (255, 0, 0) else: shape Other color (128, 128, 0) # 绘制轮廓外接矩形形状文字 cv2.drawContours(img_result, [approx], 0, color, 2) x, y, w, h cv2.boundingRect(cnt) cv2.rectangle(img_result, (x, y), (xw, yh), color, 1) cv2.putText(img_result, f{shape}({int(area)}), (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 1) # 5. 显示所有结果 cv2.imshow(Original, img) cv2.imshow(Binary, binary_close) cv2.imshow(Contour Shape Recognition, img_result) print(f原始轮廓数{len(contours)}有效轮廓数{len(valid_contours)}) cv2.waitKey(0) cv2.destroyAllWindows() # 保存结果 cv2.imwrite(contour_result.jpg, img_result)总结OpenCV-Python 查找并绘制轮廓的核心要点预处理是基础灰度→去噪→二值化→形态学优化确保二值图白色前景、黑色背景无噪声和孔洞API 核心参数查找轮廓cv2.RETR_EXTERNAL外轮廓cv2.CHAIN_APPROX_SIMPLE压缩点是最常用组合绘制轮廓contourIdx-1绘所有轮廓thickness-1填充内部实用技巧用cv2.contourArea()/cv2.arcLength()筛选有效轮廓排除噪声用cv2.boundingRect()/cv2.minEnclosingCircle()实现目标定位用cv2.approxPolyDP()做轮廓逼近实现形状识别层级轮廓cv2.RETR_TREE检索所有嵌套轮廓通过hierarchy区分内外轮廓。轮廓操作是 OpenCV 图像处理的核心技能广泛应用于目标检测、图像分割、工业检测如瑕疵识别、形状分析等场景掌握上述方法即可应对绝大多数实际开发需求。

相关新闻

全网首发!万字硬核解析:如何用向量引擎API构建企业级GPT-5.2与Sora2双模态中台(附完整源码+架构图)

全网首发!万字硬核解析:如何用向量引擎API构建企业级GPT-5.2与Sora2双模态中台(附完整源码+架构图)

摘要本文不仅仅是一篇教程。 更是一次对当下AI开发模式的深度反思与重构。 随着GPT-5.2、Sora2、Veo3等核弹级模型的相继发布。 传统的“单点直连”开发模式已经彻底崩塌。 面对高昂的维护成本、复杂的网络环境以及碎片化的接口标准。 我们迫切需要一种新的架构思想。 本文将通…

2026/7/3 16:41:30 阅读更多 →
HGDB数据库时区修改

HGDB数据库时区修改

文章目录环境文档用途详细信息环境 系统平台:N/A 版本:4.1.1,4.3.2 文档用途 用于指导HGDB修改时区的操作 详细信息 1、查看系统时间与时区 –linux系统 [rootlocalhost ~]# date -R Fri, 27 Jul 2018 14:37:48 0800 –Windows系统 控制面板–…

2026/7/3 16:41:42 阅读更多 →
CMake工程指南(二):安装配置与开发环境搭建

CMake工程指南(二):安装配置与开发环境搭建

环境准备 在开始使用CMake之前,我们需要搭建合适的开发环境。本教程使用以下环境: 编辑环境:Visual Studio Code / Cursor编译环境:Ubuntu 24.04 (通过VS Code Remote SSH模式) CMake安装 方式一:使用系统包管理器…

2026/7/4 10:48:49 阅读更多 →

最新新闻

AI冲击下数据岗位重构:国际人才策略与能力原子化实践

AI冲击下数据岗位重构:国际人才策略与能力原子化实践

1. 项目概述:这不是一份“就业报告”,而是一份人才迁徙路线图“2025年美国数据岗位市场”——光看标题,你可能以为这又是一份堆砌招聘平台统计数字、罗列热门职位名称的常规行业简报。但实际不是。我连续三年深度参与硅谷、纽约、奥斯汀三地的…

2026/7/4 16:36:50 阅读更多 →
STM32与MC6470 IMU的硬件协同与运动控制优化

STM32与MC6470 IMU的硬件协同与运动控制优化

1. MC6470与STM32L4S5ZI的硬件协同架构解析MC6470作为一款六轴惯性测量单元(IMU),其核心价值在于将三轴加速度计和三轴陀螺仪集成在单芯片方案中。在实际项目中,我测量到其加速度计量程可达16g,角速度测量范围达到2000dps,这对于大…

2026/7/4 16:34:49 阅读更多 →
XWiki路径遍历漏洞CVE-2025-55747复现与深度解析

XWiki路径遍历漏洞CVE-2025-55747复现与深度解析

1. 项目概述与漏洞背景 最近在梳理一些开源项目的安全公告时,XWiki的一个路径遍历漏洞(CVE-2025-55747)引起了我的注意。这个漏洞编号看着新鲜,但本质上又是一个经典的“输入验证不严”导致的安全问题。简单来说,攻击者…

2026/7/4 16:30:48 阅读更多 →
SpringBoot+Vue家政平台毕设实战:从工程化思维到生产级实现

SpringBoot+Vue家政平台毕设实战:从工程化思维到生产级实现

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 你有没有过这样的经历:毕业设计选题时,面对“家政服务平台”这类看似普通的题目,感觉无从下手&a…

2026/7/4 16:30:48 阅读更多 →
PC微信小程序V1MMWX加密包逆向解析:AES+XOR双重加密原理与Python解密实战

PC微信小程序V1MMWX加密包逆向解析:AES+XOR双重加密原理与Python解密实战

1. 项目概述:为什么我们需要关注PC微信小程序的加密包?如果你是一名前端开发者、安全研究员,或者单纯对微信小程序的技术实现感到好奇,那么你很可能已经发现,直接从PC端微信获取到的小程序包(.wxapkg文件&a…

2026/7/4 16:30:48 阅读更多 →
基于改进YOLOv3的实时口罩佩戴检测系统实现

基于改进YOLOv3的实时口罩佩戴检测系统实现

1. 项目概述:基于YOLOv3的口罩佩戴检测系统 这个毕业设计项目实现了一个基于深度学习的口罩佩戴检测系统,采用改进的YOLOv3算法作为核心检测模型。系统能够实时检测图像或视频中的人脸,并准确判断是否佩戴口罩、未佩戴口罩或佩戴不规范三种状…

2026/7/4 16:28:46 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻