人工智能之视觉领域 计算机视觉 第九章 图像轮廓检测

人工智能之视觉领域 计算机视觉

第九章 图像轮廓检测


文章目录

  • [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
  • 前言:图像轮廓检测
    • [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》

相关推荐
硅谷秋水1 小时前
通过测试-时强化学习实现VLA的动态自适应
深度学习·机器学习·计算机视觉·语言模型·机器人
belldeep1 小时前
AI agent:介绍 ZeroClaw 安装,使用
人工智能·ai·agent·zeroclaw
田里的水稻1 小时前
LPC_激光点云定位(LSLAM)-(IPC)
人工智能·算法·数学建模·机器人·自动驾驶
一切尽在,你来1 小时前
AI 大模型应用开发前置知识:Python 类型注解全教程
人工智能·python·ai编程
TechnologyStar1 小时前
智谱autoglm提供的免费OpenClaw服务器
人工智能
CoderJia程序员甲2 小时前
GitHub 热榜项目 - 日榜(2026-02-19)
人工智能·ai·大模型·github·ai教程
qq_454245032 小时前
计算机与AI领域中的“上下文”:多维度解析
数据结构·人工智能·分类
callJJ2 小时前
Spring AI Tool Calling(工具调用)详解——让大模型拥有“动手能力“
java·人工智能·spring·spring ai·tool calling
琅琊榜首20202 小时前
AI赋能内容创作:小说改编短剧全流程实操指南
人工智能