计算机视觉处理(OpenCV基础教学(十九):图像轮廓特征查找技术详解)

OpenCV基础教学(十九):图像轮廓特征查找技术详解

在图像处理中,找到物体的轮廓后,我们通常需要进一步分析这些轮廓的特征。轮廓特征查找是图像分析的重要环节,它能帮助我们获取轮廓的形状、大小、位置等信息。本文将详细讲解三种常用的轮廓特征查找方法:外接矩形、最小外接圆和最小外接矩形。

总流程图:

一、轮廓特征查找概述

在OpenCV中,我们可以通过各种几何形状来描述轮廓的特征,这些特征在目标检测、物体测量、图像配准等应用中非常有用。下面将分别介绍三种最常用的轮廓特征查找方法。

二、外接矩形(Bounding Rectangle)

2.1 什么是外接矩形?

外接矩形是能够完全包含轮廓的最小矩形,其边与坐标轴平行。这是最简单的轮廓包围形式,常用于快速定位物体。

2.2 代码实现

python 复制代码
# 导入OpenCV库
import cv2

# 1. 读取图片
image_np = cv2.imread('./picture.png')

# 复制出一张图片,专门用来绘制轮廓
image_contour = image_np.copy()

# 2. 灰度化图片
image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)

# 3. 二值化图像
ret, image_binary = cv2.threshold(image_gray, 127, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)

# 4. 寻找轮廓
contours, hierarchy = cv2.findContours(image_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 5. 绘制轮廓
cv2.drawContours(image_contour, contours, -1, (0, 0, 255), 2)

# 6. 根据轮廓点的坐标寻找外接矩形
# 我们需要注意的是:boundingRect 这个函数返回的是 外接矩形的左上角的点的坐标及外接矩形的宽度和高度,它并不会为我们绘制矩形
# 且这个函数一次只能获取一个轮廓的外接矩形
for cnt in contours:
    # 通过cv2.boundingRect获取当前轮廓点所构成的外接矩形的左上角的点的坐标及外接矩形的宽度和高度
    x, y, w, h = cv2.boundingRect(cnt)
    # 此时的(x,y)就是左上角的点的坐标 w是矩形的宽度 h是矩形的高度
    top_left = (x, y)
    # 右下角的点的坐标
    bottom_right = (x + w, y + h)
    # 通过rectangle去绘制矩形
    cv2.rectangle(image_contour, top_left, bottom_right, (255, 0, 0), 2)

# 7. 显示结果
cv2.imshow('image_np', image_np)
cv2.imshow('image_contour', image_contour)
cv2.waitKey(0)

2.3 关键函数解析

cv2.boundingRect(contour)

  • 功能:计算轮廓的外接矩形
  • 参数 :
    • contour:输入的轮廓点集
  • 返回值 :
    • (x, y, w, h):矩形的左上角坐标(x, y)和宽度w、高度h
  • 特点 :
    • 只能处理一个轮廓
    • 返回的矩形是轴对齐的(边与坐标轴平行)

cv2.rectangle(img, pt1, pt2, color, thickness)

  • 功能:在图像上绘制矩形
  • 参数 :
    • img:目标图像
    • pt1:矩形左上角点
    • pt2:矩形右下角点
    • color:颜色(B, G, R)
    • thickness:线宽,-1表示填充

三、最小外接圆(Minimum Enclosing Circle)

3.1 什么是最小外接圆?

最小外接圆是能够完全包围轮廓的最小圆形,常用于圆形物体的检测和测量。

3.2 代码实现

python 复制代码
# 导入OpenCV库
import cv2
import numpy as np

# 1. 读取图片
image_np = cv2.imread('./picture.png')

# 复制出一张图片,专门用来绘制轮廓
image_contour = image_np.copy()

# 2. 灰度化图片
image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)

# 3. 二值化图像
ret, image_binary = cv2.threshold(image_gray, 127, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)

# 4. 寻找轮廓
contours, hierarchy = cv2.findContours(image_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 5. 绘制轮廓
cv2.drawContours(image_contour, contours, -1, (0, 0, 255), 2)

# 6. 绘制最小外接圆
# 注意:cv2.minEnclosingCircle()也是只能一个一个去获取最小外接圆
for cnt in contours:
    # cv2.minEnclosingCircle()返回的是圆心坐标和半径大小
    (x, y), radius = cv2.minEnclosingCircle(cnt)
    # 返回的圆心坐标和半径都不是整数,都需要进行一次取整
    (x, y, radius) = np.int0((x, y, radius))
    # 使用cv2.circle()去进行画圆
    cv2.circle(image_contour, (x, y), radius, (255, 0, 0), 2)

# 7. 显示结果
cv2.imshow('image_np', image_np)
cv2.imshow('image_contour', image_contour)
cv2.waitKey(0)

3.3 关键函数解析

cv2.minEnclosingCircle(contour)

  • 功能:计算轮廓的最小外接圆
  • 参数 :
    • contour:输入的轮廓点集
  • 返回值 :
    • (center, radius):圆心坐标和半径
    • 注意:返回的是浮点数,需要转换为整数才能绘制
  • 特点 :
    • 只能处理一个轮廓
    • 返回的圆是最小包围圆

np.int0(array)

  • 功能:将浮点数数组转换为整数数组
  • 注意 :与np.int32功能类似

cv2.circle(img, center, radius, color, thickness)

  • 功能:在图像上绘制圆形
  • 参数 :
    • img:目标图像
    • center:圆心坐标
    • radius:半径
    • color:颜色(B, G, R)
    • thickness:线宽,-1表示填充

四、最小外接矩形(Rotated Rectangle)

4.1 什么是最小外接矩形?

最小外接矩形是能够完全包围轮廓的最小矩形,可以任意角度旋转,也称为旋转矩形。

4.2 代码实现

python 复制代码
# 导入OpenCV库
import cv2
import numpy as np

# 1. 读取图片
image_np = cv2.imread('./picture.png')

# 复制出一张图片,专门用来绘制轮廓
image_contour = image_np.copy()

# 2. 灰度化图片
image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)

# 3. 二值化图像
ret, image_binary = cv2.threshold(image_gray, 127, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)

# 4. 寻找轮廓
contours, hierarchy = cv2.findContours(image_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 5. 绘制轮廓
cv2.drawContours(image_contour, contours, -1, (0, 0, 255), 2)

# 6. 寻找最小外接矩形
# 注意:cv2.minAreaRect 只能一个一个轮廓的去返回结果
for cnt in contours:
    # cv2.minAreaRect 返回的是 角度、矩形中心、矩形的宽和高
    rect = cv2.minAreaRect(cnt)
    # 由于rect所包含的信息不能够帮我们直接去绘制旋转矩形
    # 所以需要使用cv2.boxPoints来帮我们获取旋转矩形的四个顶点坐标
    box = np.int0(cv2.boxPoints(rect))
    # 根据四个顶点坐标将最小外接矩形绘制出来
    # cv2.drawContours 的contours参数必须是contours级别的
    # 此时的box是cnt级别的
    cv2.drawContours(image_contour, [box], -1, (255, 0, 0), 2)

# 7. 结果显示
cv2.imshow('image_np', image_np)
cv2.imshow('image_contour', image_contour)
cv2.waitKey(0)

4.3 关键函数解析

cv2.minAreaRect(contour)

  • 功能:计算轮廓的最小外接旋转矩形
  • 参数 :
    • contour:输入的轮廓点集
  • 返回值 :
    • ((center_x, center_y), (width, height), angle):中心点坐标、宽度高度、旋转角度
    • 注意:返回的是浮点数

cv2.boxPoints(rect)

  • 功能:获取旋转矩形的四个顶点坐标
  • 参数 :
    • rect:minAreaRect返回的旋转矩形
  • 返回值 :
    • 四个顶点的坐标数组,形状为(4, 2)

五、三种方法的对比

特征 外接矩形 最小外接圆 最小外接矩形
形状 轴对齐矩形 圆形 可旋转矩形
精度 较低 中等 最高
速度 最快 中等 较慢
适用场景 快速定位 圆形物体 精确匹配
函数 boundingRect() minEnclosingCircle() minAreaRect()
参数限制 一个轮廓 一个轮廓 一个轮廓

七、注意事项

  1. 二值化效果:轮廓特征查找的效果很大程度上取决于二值化的质量
  2. 轮廓筛选:在实际应用中,可能需要根据面积、长宽比等特征筛选轮廓
  3. 精度取舍:最小外接矩形精度最高但计算量最大,根据需求选择合适的方法
  4. 数据类型:注意函数返回的数据类型,某些函数返回浮点数需要转换为整数
  5. 轮廓层级 :findContours返回的轮廓可能包含层级关系,需要根据实际需求处理

八、总结

轮廓特征查找是图像处理中的重要技术,通过外接矩形、最小外接圆和最小外接矩形等方法,我们可以有效地描述和分析轮廓的几何特征。在实际应用中:

  1. 外接矩形:最适合快速定位和物体检测
  2. 最小外接圆:适合圆形物体的检测和测量
  3. 最小外接矩形:提供最精确的轮廓包围,适合精确匹配和测量

理解这些方法的特点和适用场景,能够帮助我们在实际项目中做出合适的选择。结合轮廓检测和特征查找,我们可以构建更复杂的图像分析系统。

相关推荐
蜗牛互联网1 分钟前
Java Agent 工具调用的 allowlist、参数校验与调用预算
java·开发语言·人工智能·后端·oracle
MicrosoftReactor3 分钟前
技术速递|使用 GitHub Security Lab Taskflow Agent 实现 AI 驱动的模糊测试
人工智能·ai·github·copilot·agent·模糊测试·ai-agent
promanz4 分钟前
关于RAG文件格式转换
人工智能
桃西西呀4 分钟前
Spring AI Alibaba 之五:我把五个子智能体拼成客服流水线,才看懂内置 flow 编排和 A2A 远程调用
人工智能
翻滚的芋头5 分钟前
神经网络基础——前馈神经网络FNN
人工智能
IamZJT_8 分钟前
Agent 系统工程 10|一次长任务失败,如何定位原因并验证修复?
人工智能
橘和柠8 分钟前
模型量化完全指南:GGUF、GPTQ、AWQ 怎么选
人工智能
小白马突突突13 分钟前
零信脱敏正式提出“不过度脱敏”产品原则
人工智能·文件脱敏·文档脱敏·零信脱敏·pdf脱敏工具
Code_Solitude13 分钟前
高数第一章函数笔记(原稿手写+AI识别优化)
人工智能·笔记
龙亘川15 分钟前
面向绿色低碳城市:一网统管打通交通与能源治理的关键路径
大数据·人工智能·智慧城市·能源·开源软件