大家好,这里是AI与计算机视觉!
在计算机视觉实操中,除了基础的图像预处理,轮廓检测也是高频核心需求——它能精准提取图像中目标的形状、轮廓,还能实现目标计数、尺寸测量,是很多项目的关键一步。
不管是零件计数、药片统计,还是工业缺陷检测、文档边框提取,都离不开轮廓检测。今天这篇纯实操,从预处理铺垫到轮廓提取、计数、过滤,一步到位,代码复制即用,零基础也能快速上手!
全程无复杂推导,重点讲实操、讲应用,帮你快速落地到自己的项目中,避开所有新手坑!
一、前置环境配置(10秒搞定)
依赖库与之前通用,无需额外安装,直接复制命令(若未安装可执行):
bashpip install opencv-python numpy |
所有案例通用导入模块(复制到代码开头即可):
pythonimport cv2import numpy as np |
使用说明:将测试图片命名为 objects.jpg,放在代码同一目录下(推荐用包含多个独立目标的图片,如硬币、零件图);若图片路径不同,可在cv2.imread()中填写完整路径。
二、核心流程:预处理→ 轮廓检测 → 绘制与计数
轮廓检测的关键前提:先对图像进行预处理(灰度+二值化),突出目标区域,才能精准找到轮廓,避免背景干扰。
步骤1:图像读取与预处理(关键铺垫)
预处理主要实现“突出目标、抑制背景”,这里用自适应阈值二值化,适配光照不均的场景,比固定阈值更稳定:
python# 1. 读取原始图像(彩色图)img = cv2.imread("objects.jpg")# 备份原图,用于后续绘制轮廓(避免修改原图)img_copy = img.copy()# 2. 灰度化(轮廓检测仅支持单通道图像)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 3. 自适应阈值二值化(突出目标,抑制背景噪点)binary = cv2.adaptiveThreshold(gray, 255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, # 高斯自适应阈值cv2.THRESH_BINARY_INV, # 黑白反转,让目标变为白色(便于检测)blockSize=11, # 块大小(必须为奇数,越大越平滑)C=2 # 阈值偏移量,调整目标与背景的对比度) |
步骤2:查找轮廓(核心操作)
使用OpenCV内置函数findContours,快速提取图像中的所有轮廓,重点掌握参数含义,避免提取到多余轮廓:
python# 查找轮廓(返回轮廓列表和层级关系)# 核心参数说明:# binary:二值化后的图像(必须)# cv2.RETR_EXTERNAL:只提取最外层轮廓(忽略轮廓内部的小轮廓,推荐)# cv2.CHAIN_APPROX_SIMPLE:压缩轮廓点,减少内存占用(如矩形轮廓只保留4个顶点)contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# 打印轮廓数量(初步统计目标个数)print(f"检测到的轮廓总数:{len(contours)}") |
步骤3:绘制轮廓 + 目标计数(可视化效果)
将提取到的轮廓绘制在原图上,同时添加计数文本,直观看到检测效果,可直接用于项目展示:
python# 1. 绘制轮廓(在备份的原图上绘制,颜色为绿色,线条宽度2)# contours:所有轮廓列表;-1:绘制所有轮廓(指定索引可绘制单个轮廓)cv2.drawContours(img_copy, contours, -1, (0, 255, 0), 2)# 2. 添加目标计数文本(位置:左上角(20,40),字体、大小、颜色可调整)count = len(contours)cv2.putText(img_copy, f"目标计数:{count}",(20, 40), cv2.FONT_HERSHEY_SIMPLEX,1.2, (0, 0, 255), 2 # 字体大小1.2,红色,线条宽度2)# 3. 展示效果(原图 vs 二值化图 vs 轮廓检测结果)cv2.imshow("原图", img)cv2.imshow("二值化图(预处理)", binary)cv2.imshow("轮廓检测结果", img_copy)# 等待按键关闭窗口,释放资源cv2.waitKey(0)cv2.destroyAllWindows() |
✅ 新手注意
•绘制轮廓时,一定要操作原图的备份(如img_copy),避免修改原图影响后续操作;
•参数cv2.RETR_EXTERNAL是最常用的轮廓提取模式,适合大多数计数、检测场景;
•若轮廓线条过细/过粗,可调整drawContours的最后一个参数(线条宽度)。
三、进阶技巧:过滤小轮廓,避免噪点干扰
实际场景中,二值化后可能会残留小噪点,导致检测到多余的小轮廓,影响计数准确性。这里教大家通过轮廓面积过滤,只保留有效目标:
python# 延续上面的代码,过滤面积过小的轮廓(自定义面积阈值)valid_contours = [] # 存储有效轮廓min_area = 100 # 最小轮廓面积(可调整,根据目标大小设定)for cnt in contours:# 计算每个轮廓的面积area = cv2.contourArea(cnt)# 只保留面积大于min_area的轮廓(过滤小噪点)if area > min_area:valid_contours.append(cnt)# 重新绘制有效轮廓,统计有效目标数量img_valid = img.copy()cv2.drawContours(img_valid, valid_contours, -1, (0, 255, 0), 2)valid_count = len(valid_contours)cv2.putText(img_valid, f"有效目标计数:{valid_count}",(20, 40), cv2.FONT_HERSHEY_SIMPLEX,1.2, (0, 0, 255), 2)# 展示过滤后的效果cv2.imshow("过滤小轮廓后结果", img_valid)cv2.waitKey(0)cv2.destroyAllWindows()# 打印有效目标数量print(f"有效目标数量:{valid_count}") |
✅ 参数调整建议
min_area(最小轮廓面积)需根据目标大小调整:目标越大,阈值设越大;目标越小(如小药片、小零件),阈值设越小,可多测试几次找到最佳值。
四、完整可运行代码(直接复制)
整合所有步骤,包含预处理、轮廓检测、计数、过滤,复制即可运行,无需修改:
pythonimport cv2import numpy as np# 1. 读取图像并备份img = cv2.imread("objects.jpg")img_copy = img.copy()# 2. 预处理(灰度化 + 自适应阈值二值化)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)binary = cv2.adaptiveThreshold(gray, 255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,blockSize=11,C=2)# 3. 查找轮廓contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# 4. 过滤小轮廓valid_contours = []min_area = 100for cnt in contours:if cv2.contourArea(cnt) > min_area:valid_contours.append(cnt)# 5. 绘制轮廓 + 计数cv2.drawContours(img_copy, valid_contours, -1, (0, 255, 0), 2)valid_count = len(valid_contours)cv2.putText(img_copy, f"有效目标计数:{valid_count}",(20, 40), cv2.FONT_HERSHEY_SIMPLEX,1.2, (0, 0, 255), 2)# 6. 展示所有效果cv2.imshow("原图", img)cv2.imshow("二值化预处理", binary)cv2.imshow("轮廓检测+计数结果", img_copy)# 7. 保存结果(可选)cv2.imwrite("contour_result.jpg", img_copy)# 释放资源cv2.waitKey(0)cv2.destroyAllWindows()# 打印结果print(f"检测到轮廓总数:{len(contours)}")print(f"有效目标数量:{valid_count}") |
✅ 避坑提醒
若运行报错“找不到图片”,请确认图片名称正确(objects.jpg),且与代码文件在同一目录;若轮廓检测不到,可调整二值化的blockSize和C参数,或降低min_area阈值。
五、应用场景与实战建议
1.计数场景:零件计数、药片计数、硬币计数(调整min_area即可适配不同大小的目标);
2.检测场景:工业缺陷检测(如零件划痕、污渍的轮廓提取)、文档边框提取、人脸轮廓提取;
3.进阶拓展:通过轮廓可进一步计算目标的周长、面积、形状(如判断是圆形还是矩形),适配更复杂的项目需求;
4.新手实战:建议先用简单的图片(如5-10枚硬币的图片)测试,熟悉参数后再应用到自己的项目中。
关注【AI与计算机视觉】,每天一个实操干货,从传统视觉到深度学习,循序渐进搞定计算机视觉!大家觉得分享有用的话别忘了点赞+在看+转发+赞赏哟,亲们的支持是小编更新最大的动力!