Opencv 学习笔记:轮廓筛选 + 拟合(边界框 / 最小矩形 / 包围圆)

在轮廓分析中,仅提取所有轮廓远远不够,需根据尺寸筛选目标轮廓,并通过边界框、最小面积矩形、最小包围圆等方式拟合轮廓,实现目标精准定位。本文整合完整流程,演示如何筛选 "合适轮廓" 并可视化拟合结果。

核心代码实现

python 复制代码
import cv2 as cv
import numpy as np

# 1. 读取图像并校验
src = cv.imread('.\image\22.bmp')
if src is None:
    print('图像读取失败,请检查路径!')
    exit()

# 2. 预处理:去噪+边界填充+二值化(提升轮廓提取准确性)
dst = cv.GaussianBlur(src, (3, 3), 15)  # 高斯滤波去噪
grays = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
# 边界填充(避免图像边缘轮廓断裂)
gray = cv.copyMakeBorder(grays, 1, 1, 1, 1, cv.BORDER_CONSTANT, value=[255, 255, 255])
# 二值化(分离前景/背景)
ret, binary = cv.threshold(gray, 128, 255, cv.THRESH_BINARY)

# 3. 查找轮廓(CCOMP模式:检索内外层轮廓)
contours, hierarchy = cv.findContours(binary, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE)

# 4. 创建结果画布(避免修改原图)
result = src.copy()

# 5. 筛选并拟合轮廓
for i, contour in enumerate(contours):
    # 筛选条件:轮廓尺寸在90~10000之间(过滤过小/过大噪点)
    if 90 < contour.size < 10000:
        # 方式1:绘制边界矩形(轴对齐)
        x, y, w, h = cv.boundingRect(contour)
        print(f"边界矩形尺寸:宽={w}, 高={h}")
        cv.rectangle(result, (x, y), (x + w, y + h), (0, 0, 255), 3)
        
        # 方式2:绘制最小面积矩形(旋转对齐)
        rect = cv.minAreaRect(contour)  # 获取最小面积矩形(中心、尺寸、旋转角度)
        box = cv.boxPoints(rect)        # 计算矩形四个顶点坐标
        box = np.int0(box)              # 坐标转为整数
        cv.drawContours(result, [box], 0, (255, 255, 0), 5)
        
        # 方式3:绘制最小包围圆
        (cx, cy), radius = cv.minEnclosingCircle(contour)
        center = (int(cx), int(cy))
        radius = int(radius)
        cv.circle(result, center, radius, (0, 255, 0), 2)

# 6. 显示结果
cv.namedWindow('src', cv.WINDOW_NORMAL)
cv.resizeWindow('src', 600, 600)
cv.imshow('src', binary)  # 显示二值化图

cv.namedWindow('result', cv.WINDOW_NORMAL)
cv.resizeWindow('result', 600, 600)
cv.imshow('result', result)  # 显示轮廓拟合结果

cv.waitKeyEx(0)
cv.destroyAllWindows()

关键知识点解析

1. 核心流程拆解

步骤 核心操作 作用说明
边界填充 cv.copyMakeBorder() 给图像边缘填充白色像素,避免边缘轮廓因截断无法完整提取
轮廓筛选 contour.size 通过轮廓像素点数量筛选,过滤过小噪点(<90)和过大背景(>10000)
边界矩形 cv.boundingRect() 生成轴对齐的矩形框,计算简单、速度快
最小面积矩形 cv.minAreaRect() 生成贴合轮廓的旋转矩形,更精准匹配目标形状
最小包围圆 cv.minEnclosingCircle() 用圆形拟合轮廓,适用于圆形 / 类圆形目标定位

2. 核心参数说明

  • 轮廓检索模式cv.RETR_CCOMP:检索所有轮廓并分为两层(外层 / 内层),适合有孔洞的目标轮廓提取;
  • contour.size:轮廓点的总像素数(每个点含 x/y 两个值,因此实际点数 = size/2);
  • cv.boxPoints(rect) :将minAreaRect返回的(中心、尺寸、角度)转换为四个顶点坐标,需转为整数才能绘制。

3. 避坑与优化技巧

  • 画布赋值 :原代码result = src是引用赋值(修改 result 会改原图),改为result = src.copy()深拷贝;
  • 轮廓尺寸阈值:90/10000 是经验值,需根据图像分辨率和目标大小调整(分辨率大则阈值相应增大);
  • 拟合方式选择
    • 轴对齐矩形:适合规则、无旋转的目标;
    • 最小面积矩形:适合倾斜、旋转的目标;
    • 最小包围圆:适合圆形目标(如表盘、零件)。
  • 效率优化:若仅需一种拟合方式,注释其他方式可提升运行速度。

总结

  1. 轮廓筛选的核心是通过contour.size过滤无效轮廓,阈值需根据实际场景调整;
  2. 边界填充是提取图像边缘轮廓的关键预处理步骤,避免轮廓断裂;
  3. 三种拟合方式各有适用场景:轴对齐矩形(快)、最小面积矩形(准)、最小包围圆(适配圆形目标)。
相关推荐
崎岖Qiu2 小时前
【深度剖析】:结合 Spring Bean 的生命周期理解 @PostConstruct 的原理
java·笔记·后端·spring·javaee
蒸蒸yyyyzwd3 小时前
mapreduce步骤学习总结
笔记
鴆川傲3 小时前
渗透高级课第二次学习总结
网络·学习
saoys4 小时前
Opencv 学习笔记:轮廓发现(提取 + 绘制全流程)
笔记·opencv·学习
LaoZhangGong1234 小时前
学习TCP/IP的第5步:传输数据
网络·学习·tcp/ip
qwy7152292581634 小时前
3-用摄像头拍摄图像及视频
人工智能·opencv·音视频
茶栀(*´I`*)4 小时前
【视觉探索】OpenCV 全景导论:从数字图像基石到核心模块体系
人工智能·opencv·计算机视觉
zhangrelay5 小时前
如何让手机电脑流畅飞起低碳节能性能拉满-软件安装篇-ESR-Extended Support Release-延长支持版-LTS
linux·运维·笔记·学习
岳轩子5 小时前
jvm学习 引入 第一晚
jvm·学习