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() |
| 参数限制 | 一个轮廓 | 一个轮廓 | 一个轮廓 |
七、注意事项
- 二值化效果:轮廓特征查找的效果很大程度上取决于二值化的质量
- 轮廓筛选:在实际应用中,可能需要根据面积、长宽比等特征筛选轮廓
- 精度取舍:最小外接矩形精度最高但计算量最大,根据需求选择合适的方法
- 数据类型:注意函数返回的数据类型,某些函数返回浮点数需要转换为整数
- 轮廓层级 :
findContours返回的轮廓可能包含层级关系,需要根据实际需求处理
八、总结
轮廓特征查找是图像处理中的重要技术,通过外接矩形、最小外接圆和最小外接矩形等方法,我们可以有效地描述和分析轮廓的几何特征。在实际应用中:
- 外接矩形:最适合快速定位和物体检测
- 最小外接圆:适合圆形物体的检测和测量
- 最小外接矩形:提供最精确的轮廓包围,适合精确匹配和测量
理解这些方法的特点和适用场景,能够帮助我们在实际项目中做出合适的选择。结合轮廓检测和特征查找,我们可以构建更复杂的图像分析系统。