OpenCV(三十四):绘制轮廓

什么是轮廓(Contour)

在 OpenCV 中,轮廓是一组连续的点构成的曲线,用于表示图像中某一目标的边界。它基于二值图像搜寻边界,因此轮廓检测通常配合阈值或边缘检测一起使用。

轮廓在图像处理中的典型用途包括:

  • 目标检测与定位
  • 形状匹配
  • 物体面积/周长测量
  • 应用如目标计数、分割、识别

OpenCV 将轮廓视为 numpy 数组的集合,每个轮廓是一个坐标点序列。

轮廓提取原理

输入图像必须是二值图或边缘图

cv2.findContours() 依赖 黑白清晰的边界,它通过扫描二值图寻找像素连接,形成线条式轮廓。

常用输入:

  • 二值图:cv2.threshold()
  • 边缘图:cv2.Canny()

查找方式(Retrieval Mode)

OpenCV 提供不同的轮廓结构方式:

模式 含义
cv2.RETR_EXTERNAL 仅提取最外层轮廓
cv2.RETR_LIST 提取所有轮廓,不建立层级关系
cv2.RETR_TREE 提取所有轮廓,并生成完整层级树结构
cv2.RETR_CCOMP 提取所有,将外轮廓与洞作为不同层组织

轮廓逼近方式(Approximation Mode)

模式 含义
cv2.CHAIN_APPROX_NONE 保存所有边界点
cv2.CHAIN_APPROX_SIMPLE 去除冗余点,仅保存直线拐点(常用)

绘制轮廓(DrawContours )

绘制使用:

python 复制代码
cv2.drawContours(image, contours, index, color, thickness)

参数说明:

  • contours:轮廓列表
  • index:选择第几个轮廓;-1 表示全部绘制
  • color:绘制颜色
  • thickness:线条粗细,-1 表示填充轮廓内区域

OpenCV 绘制轮廓本质上是将点序列连成多段线,从而形成封闭区域。

轮廓常用属性计算

周长(Arc Length)

python 复制代码
cv2.arcLength(contour, closed=True)

面积(Area)

python 复制代码
cv2.contourArea(contour)

外接矩形

  • 普通外接矩形:cv2.boundingRect()
  • 最小外接矩形(任意倾斜):cv2.minAreaRect()

最小包围圆

python 复制代码
cv2.minEnclosingCircle()

轮廓逼近(Douglas-Peucker)

python 复制代码
approx = cv2.approxPolyDP(contour, epsilon, True)

用于判断形状(三角形、矩形等)。

示例

读取 → 灰度化 → 二值化 → 轮廓提取 → 绘制 → 计算面积/周长 → 轮廓逼近

python 复制代码
import cv2
import numpy as np

# =========================
# 1. 自己画一个图片
# =========================
img = np.zeros((400, 400, 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)

# 画一个白色多边形(三角形)
pts = np.array([[200, 250], [300, 350], [100, 350]], np.int32)
cv2.fillPoly(img, [pts], (255, 255, 255))

# 转灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


# =========================
# 2. 二值化
# =========================
ret, thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)


# =========================
# 3. 查找轮廓
# =========================
contours, hierarchy = cv2.findContours(
    thresh,
    cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE
)

print("轮廓数量:", len(contours))


# =========================
# 4. 绘制所有轮廓
# =========================
cv2.drawContours(img, contours, -1, (0, 255, 0), 2)


# =========================
# 5. 遍历轮廓并分析
# =========================
for i, cnt in enumerate(contours):
    area = cv2.contourArea(cnt)
    length = cv2.arcLength(cnt, True)

    print(f"轮廓 {i}: 面积={area:.2f}, 周长={length:.2f}")

    # 轮廓逼近
    epsilon = 0.02 * length
    approx = cv2.approxPolyDP(cnt, epsilon, True)

    # 绘制逼近轮廓(红色)
    cv2.drawContours(img, [approx], -1, (0, 0, 255), 2)

    # 绘制外接矩形(蓝色)
    x, y, w, h = cv2.boundingRect(cnt)
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)


# =========================
# 6. 显示结果
# =========================
cv2.imshow("Binary", thresh)
cv2.imshow("Contours Result", img)
cvcv2.waitKey(0)
cv2.destroyAllWindows()

执行结果:

相关推荐
Ai_easygo17 分钟前
多Agent协作与A2A协议——CrewAI + LangGraph搭建AI协作团队
人工智能
HIT_Weston25 分钟前
151、【Agent】【OpenCode】启动分析(CLI 命令注册)
人工智能·agent·opencode
笑小枫30 分钟前
用 Claude Code 推翻重写笑小枫网站
java·人工智能·spring boot·ai编程
audyxiao00139 分钟前
人工智能顶会AAAI 2026论文分享|SlideBot:用于生成信息丰富、可靠、多模态幻灯片的多智能体框架
人工智能·大模型·aaai·智能体·幻灯片
用户9385156350742 分钟前
Workflow 与 Agent 之争:确定性执行与智能探索的深度剖析
人工智能
阿里云大数据AI技术1 小时前
阿里云 EMR Serverless StarRocks(Stella 2.2.0) 发布:内表与湖表同时支持向量、全文与 AI Function,一条 SQL 完成多模态检索
人工智能
格林威1 小时前
工业相机Chunk功能全解析:图像嵌入时间戳、编码器元数据(附堡盟C#代码)
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
怪奇云呼军1 小时前
闪电智能Voice Agent:ASR 首字延迟和最终识别延迟怎么测?t0-t3 埋点实战
人工智能·科技·ai·语音识别
冬哥聊AI1 小时前
百万行代码里跑Claude Code?三面这题80%的人答不上来
人工智能
甄同学1 小时前
第二十三篇:Tasks系统,Claude Code如何统一管理7种后台任务
人工智能