欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

OpenCV 从零学习 · 第 8 讲:轮廓查找与绘制(findContours / drawContours,数物体、框目标)

OpenCV 从零学习 · 第 8 讲:轮廓查找与绘制

函数:cv2.findContours / cv2.drawContours | 难度:★★☆☆☆

"轮廓"(Contour)是连接所有连续边界点的曲线,代表图像里一个个物体的外形。拿到轮廓后,你就能数物体个数、给目标画框、算面积、识别形状——这是从"边缘线"走向"理解物体"的关键一步。轮廓查找的输入必须是二值图(如 threshold / Canny 的结果)。


一、查找轮廓 cv2.findContours

函数签名(OpenCV 4.x)

contours, hierarchy = cv2.findContours(image, mode, method)
参数 含义
image二值图(白=前景)。此函数会原地修改该图,建议传一份副本
mode轮廓检索模式(见下)
method轮廓近似方法(见下)

返回值contours 是一个列表,每个元素是一个形状为 (N,1,2) 的 NumPy 数组,存该轮廓的所有点;hierarchy 是轮廓层级关系(嵌套轮廓时用)。

mode 取值 用途
RETR_EXTERNAL只取最外层轮廓(忽略内部嵌套),最常用
RETR_LIST所有轮廓,不建立层级
RETR_TREE完整层级树(如一个圆里套一个方)
method 取值 用途
CHAIN_APPROX_SIMPLE压缩冗余点,只留端点(推荐,省内存)
CHAIN_APPROX_NONE保留轮廓上每一个像素点
⚠ 新手必踩坑(版本差异)
OpenCV 4.x(你现在装的)返回两个值:contours, hierarchy = cv2.findContours(...)
OpenCV 3.x 返回三个值:image, contours, hierarchy = cv2.findContours(...)
网上老教程多是 3.x 写法,直接抄会"太多值无法解包"报错。本文按 4.x 写。
场景 A · 数图里有多少个物体
对一张白底黑块的二值图,RETR_EXTERNAL 找出所有外轮廓,len(contours) 就是物体个数。
import cv2
img   = cv2.imread('blocks.png')
gray  = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, bin = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)  # 物体变白
contours, _ = cv2.findContours(bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print('物体个数 =', len(contours))
场景 B · 过滤小噪点
二值图常带细小噪点轮廓。用 cv2.contourArea(c) 算面积,只保留面积大于某阈值的轮廓,噪点就被去掉了。

二、绘制轮廓 cv2.drawContours

img = cv2.drawContours(img, contours, contourIdx, color, thickness)
参数 含义
img要画上去的图(原地修改,无返回值也可用)
contoursfindContours 的返回值
contourIdx要画的轮廓索引,-1 表示全部
colorBGR 颜色,如 (0,0,255) 红
thickness线宽,-1 表示填充轮廓内部
场景 C · 把找到的轮廓描红
cv2.drawContours(img, contours, -1, (0,0,255), 2) 给所有物体描上 2 像素红边。

三、轮廓的常用度量与外接框

函数 作用
cv2.contourArea(c)轮廓面积(像素数)
cv2.arcLength(c, closed)周长,closed=True 表示闭合
cv2.boundingRect(c)返回 (x,y,w,h) 正外接矩形
cv2.approxPolyDP(c, eps, closed)多边形近似,eps 越大越粗略
场景 D · 给每个物体画外接框(目标检测框雏形)
遍历轮廓,对每个算 x,y,w,h = cv2.boundingRect(c),再用 cv2.rectangle 画框——这就是最简单版的"框出目标"。
场景 E · 用边数判断形状
approx = cv2.approxPolyDP(c, 0.02*cv2.arcLength(c,True), True),看 len(approx):3=三角形、4=矩形/方形、≈10 且接近圆=圆。
for c in contours:
    if cv2.contourArea(c) < 100:      # 过滤小噪点
        continue
    x, y, w, h = cv2.boundingRect(c)
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)

本讲要点

  • 输入二值图;OpenCV 4.x 返回 contours, hierarchy 两个值(3.x 是三个,别抄错)。
  • RETR_EXTERNAL + CHAIN_APPROX_SIMPLE 是数物体、画外框的常用组合。
  • 用面积过滤噪点、用 boundingRect 画框、用 approxPolyDP 判断形状。

下一讲:第 9 讲 · 在图像上画图形与文字(line / rectangle / circle / putText)——把"框、点、标签"真正画出来做标注。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功