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. 三种拟合方式各有适用场景:轴对齐矩形(快)、最小面积矩形(准)、最小包围圆(适配圆形目标)。
相关推荐
JustDI-CM7 小时前
AI学习笔记-提示词工程
人工智能·笔记·学习
悟纤7 小时前
学习与专注音乐流派 (Study & Focus Music):AI 音乐创作终极指南 | Suno高级篇 | 第33篇
大数据·人工智能·深度学习·学习·suno·suno api
爱写bug的野原新之助7 小时前
加密摘要算法MD5、SHA、HMAC:学习笔记
笔记·学习
ZH15455891317 小时前
Flutter for OpenHarmony Python学习助手实战:Web开发框架应用的实现
python·学习·flutter
百锦再7 小时前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
CappuccinoRose8 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明
A9better8 小时前
C++——不一样的I/O工具与名称空间
开发语言·c++·学习
小乔的编程内容分享站8 小时前
C语言笔记之函数
c语言·笔记
AI职业加油站8 小时前
职业提升之路:我的大数据分析师学习与备考分享
大数据·人工智能·经验分享·学习·职场和发展·数据分析
四谎真好看9 小时前
JavaWeb学习笔记(Day13)
笔记·学习·学习笔记·javaweb