人工智能之视觉领域 计算机视觉
第九章 图像轮廓检测
文章目录
- [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
- 前言:图像轮廓检测
- [1. 通俗理解:什么是"轮廓"?](#1. 通俗理解:什么是“轮廓”?)
- [2. 轮廓检测的核心前提:二值图像](#2. 轮廓检测的核心前提:二值图像)
- [3. 核心函数详解](#3. 核心函数详解)
- [3.1 查找轮廓:`cv2.findContours()`](#3.1 查找轮廓:
cv2.findContours())
- [📋 常用 `mode`(检索模式):](#📋 常用
mode(检索模式):)- [📋 常用 `method`(近似方法):](#📋 常用
method(近似方法):)- [3.2 绘制轮廓:`cv2.drawContours()`](#3.2 绘制轮廓:
cv2.drawContours())- [4. 轮廓分析:面积、周长、边界框](#4. 轮廓分析:面积、周长、边界框)
- [5. 完整工作流程(Mermaid 图)](#5. 完整工作流程(Mermaid 图))
- [6. 配套代码实战](#6. 配套代码实战)
- [示例 1:基础轮廓检测与绘制](#示例 1:基础轮廓检测与绘制)
- [示例 2:物体计数 + 形状识别](#示例 2:物体计数 + 形状识别)
- [7. 应用场景详解](#7. 应用场景详解)
- [🎯 场景1:硬币计数](#🎯 场景1:硬币计数)
- [🎯 场景2:文档扫描中的表格/文字框检测](#🎯 场景2:文档扫描中的表格/文字框检测)
- [🎯 场景3:工业零件质检](#🎯 场景3:工业零件质检)
- [8. 常见问题与技巧](#8. 常见问题与技巧)
- [❓ 问题1:轮廓太多,包含噪点?](#❓ 问题1:轮廓太多,包含噪点?)
- [❓ 问题2:轮廓不闭合?](#❓ 问题2:轮廓不闭合?)
- [❓ 问题3:如何只检测特定大小的物体?](#❓ 问题3:如何只检测特定大小的物体?)
- [✅ 本章总结](#✅ 本章总结)
- 资料关注
前言:图像轮廓检测
学习目标:掌握从图像中提取物体轮廓的完整流程,能使用 OpenCV 查找、绘制、分析轮廓,并应用于物体计数、形状识别等实际任务。
1. 通俗理解:什么是"轮廓"?
想象你有一张黑白图:
- 白色是背景
- 黑色是物体
✅ 轮廓 = 物体边界的闭合曲线
它是一组连续的点,围成一个封闭区域,代表了物体的"外框"。
在计算机视觉中,轮廓是形状分析、目标识别、物体计数的基础。
2. 轮廓检测的核心前提:二值图像
OpenCV 的 cv2.findContours() 只能处理二值图像(黑白图)!
🔁 标准流程 :
彩色图 → 灰度图 → 二值化 → 轮廓检测
为什么?
- 轮廓是"前景 vs 背景"的边界
- 二值图只有 0(黑)和 255(白),边界清晰
3. 核心函数详解
3.1 查找轮廓:cv2.findContours()
python
contours, hierarchy = cv2.findContours(image, mode, method)
| 参数 | 说明 |
|---|---|
image |
二值图像(必须是单通道 uint8) |
mode |
轮廓检索模式(见下表) |
method |
轮廓近似方法(见下表) |
📋 常用 mode(检索模式):
| 模式 | 作用 |
|---|---|
cv2.RETR_EXTERNAL |
只检测最外层轮廓(忽略内部孔洞)→ 推荐初学者用 |
cv2.RETR_TREE |
检测所有轮廓,并重建完整的层级结构(父子关系) |
cv2.RETR_LIST |
检测所有轮廓,但不建立层级 |
📋 常用 method(近似方法):
| 方法 | 作用 |
|---|---|
cv2.CHAIN_APPROX_NONE |
保存所有边界点(数据量大) |
cv2.CHAIN_APPROX_SIMPLE |
压缩水平/垂直/对角线段,只保留端点(推荐!) |
💡 示例:一个矩形有 4 个角点
NONE会存几百个点(每条边所有像素)SIMPLE只存 4 个点!
3.2 绘制轮廓:cv2.drawContours()
python
cv2.drawContours(image, contours, contourIdx, color, thickness)
| 参数 | 说明 |
|---|---|
image |
要绘制的图像(会被修改!建议复制一份) |
contours |
findContours 返回的轮廓列表 |
contourIdx |
绘制哪个轮廓?-1 = 全部,0 = 第一个,1 = 第二个... |
color |
颜色(BGR格式,如 (0, 255, 0) 绿色) |
thickness |
线宽(-1 = 填充轮廓内部) |
4. 轮廓分析:面积、周长、边界框
OpenCV 提供丰富函数分析每个轮廓:
| 功能 | 函数 | 说明 |
|---|---|---|
| 轮廓面积 | cv2.contourArea(cnt) |
单位:像素² |
| 轮廓周长 | cv2.arcLength(cnt, closed=True) |
closed 必须为 True |
| 边界矩形 | cv2.boundingRect(cnt) |
返回 (x, y, w, h) |
| 最小外接圆 | cv2.minEnclosingCircle(cnt) |
返回 (center, radius) |
| 拟合多边形 | cv2.approxPolyDP(cnt, epsilon, True) |
用于形状识别 |
5. 完整工作流程(Mermaid 图)
绘制
计数
形状识别
原始彩色图像
转灰度 cv2.cvtColor
二值化 cv2.threshold / adaptiveThreshold
可选:形态学去噪 morphologyEx
查找轮廓 cv2.findContours
分析需求?
drawContours
len(contours)
计算面积/周长/多边形近似
显示或保存结果
6. 配套代码实战
示例 1:基础轮廓检测与绘制
python
import cv2
import numpy as np
# 1. 读取图像
img = cv2.imread('shapes.jpg')
if img is None:
# 创建测试图像
img = np.zeros((400, 600, 3), dtype=np.uint8)
cv2.rectangle(img, (50, 50), (150, 150), (255, 255, 255), -1)
cv2.circle(img, (300, 100), 50, (255, 255, 255), -1)
cv2.ellipse(img, (500, 100), (60, 30), 0, 0, 360, (255, 255, 255), -1)
# 2. 转灰度 + 二值化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 3. 查找轮廓(只取最外层)
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 4. 绘制轮廓(复制原图避免修改)
result = img.copy()
cv2.drawContours(result, contours, -1, (0, 255, 0), 2) # 绿色,线宽2
# 5. 显示
cv2.imshow('Original', img)
cv2.imshow('Contours', result)
print(f"✅ 检测到 {len(contours)} 个轮廓")
cv2.waitKey(0)
cv2.destroyAllWindows()
示例 2:物体计数 + 形状识别
python
import cv2
import math
def recognize_shape(approx):
"""根据近似多边形顶点数判断形状"""
num_vertices = len(approx)
if num_vertices == 3:
return "Triangle"
elif num_vertices == 4:
# 判断是否为矩形(检查角度)
return "Rectangle"
elif num_vertices > 10:
return "Circle"
else:
return "Polygon"
# 读取图像(建议用 coins.jpg 或 shapes.jpg 测试)
img = cv2.imread('coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊 + 二值化(OTSU 自动阈值)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
_, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 形态学闭运算:连接硬币边缘
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 分析每个轮廓
result = img.copy()
for i, cnt in enumerate(contours):
area = cv2.contourArea(cnt)
if area < 100: # 过滤小噪点
continue
# 计算周长
perimeter = cv2.arcLength(cnt, True)
# 多边形近似(epsilon = 周长的 2%)
epsilon = 0.02 * perimeter
approx = cv2.approxPolyDP(cnt, epsilon, True)
# 识别形状
shape = recognize_shape(approx)
# 获取边界框
x, y, w, h = cv2.boundingRect(cnt)
# 绘制结果
cv2.drawContours(result, [cnt], -1, (0, 255, 0), 2)
cv2.putText(result, f"{shape} #{i+1}", (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
# 显示
cv2.imshow('Object Counting & Shape Recognition', result)
print(f"✅ 共检测到 {len([c for c in contours if cv2.contourArea(c) > 100])} 个有效物体")
cv2.waitKey(0)
cv2.destroyAllWindows()
7. 应用场景详解
🎯 场景1:硬币计数
- 步骤:二值化 → 闭运算(连接边缘)→ 轮廓检测 → 过滤小面积 → 计数
- 关键:用
RETR_EXTERNAL避免检测硬币内部反光孔洞
🎯 场景2:文档扫描中的表格/文字框检测
- 步骤:边缘检测(Canny)→ 膨胀连接 → 轮廓检测 → 筛选矩形区域
🎯 场景3:工业零件质检
- 步骤:模板匹配定位 → 轮廓提取 → 比较面积/周长是否在公差范围内
8. 常见问题与技巧
❓ 问题1:轮廓太多,包含噪点?
✅ 解决:
- 二值化前加高斯模糊
- 形态学开运算去噪
- 用
contourArea()过滤小面积轮廓
❓ 问题2:轮廓不闭合?
✅ 解决:
- 二值化时尝试
THRESH_OTSU - 用闭运算(
MORPH_CLOSE)填充断裂
❓ 问题3:如何只检测特定大小的物体?
✅ 解决:
python
valid_contours = []
for cnt in contours:
area = cv2.contourArea(cnt)
if 500 < area < 5000: # 设定面积范围
valid_contours.append(cnt)
✅ 本章总结
| 步骤 | 关键操作 | 函数 |
|---|---|---|
| 预处理 | 灰度 → 二值化 → 去噪 | cvtColor, threshold, morphologyEx |
| 找轮廓 | 提取边界 | cv2.findContours(mode=RETR_EXTERNAL, method=CHAIN_APPROX_SIMPLE) |
| 绘轮廓 | 可视化结果 | cv2.drawContours(..., -1, color, thickness) |
| 分析 | 面积、周长、形状 | contourArea, arcLength, approxPolyDP |
🌟 现在可以:
- 数出一张图里有多少个硬币
- 识别图中的三角形、矩形、圆形
- 为后续的"目标跟踪"或"OCR 区域定位"提供精准 ROI!
资料关注
咚咚王
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》