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. 三种拟合方式各有适用场景:轴对齐矩形(快)、最小面积矩形(准)、最小包围圆(适配圆形目标)。
相关推荐
头疼的程序员9 小时前
计算机网络:自顶向下方法(第七版)第九章 学习分享(一)
学习·计算机网络
小墨同学boy10 小时前
越用越强不是广告语:拆解 Hermes Agent 的三层学习机制
人工智能·学习
仲芒10 小时前
[24年单独笔记] MySQL 常用的 DML 命令
数据库·笔记·mysql
lwewan10 小时前
CPU 调度
笔记·考研
John.Lewis10 小时前
C++进阶(6)C++11(2)
开发语言·c++·笔记
才知道的11 小时前
stm32F407学习DAY.27 ADC
stm32·嵌入式硬件·学习
Orange_sparkle11 小时前
learn claude code学习记录-S02
java·python·学习
小郑加油11 小时前
python学习Day1:python的安装与环境搭载
python·学习·小白记录,保姆式教程
CheerWWW12 小时前
C++学习笔记——栈内存与堆内存、宏、auto、std::array
c++·笔记·学习
知识分享小能手12 小时前
MongoDB入门学习教程,从入门到精通,在生产环境中设置MongoDB(21)
数据库·学习·mongodb