OpenCV基础教学(十七):图像轮廓检测技术详解
图像轮廓检测是计算机视觉中一项基础而重要的技术,它能够帮助我们识别图像中物体的形状、边界和结构。本文将详细讲解OpenCV中轮廓检测的基本原理与实现方法。
总流程图:

一、什么是图像轮廓?
图像轮廓是连接所有连续边缘点的曲线,具有相同颜色或强度的边界。与边缘检测不同,轮廓检测不仅找到边界,还把这些边界连接成完整的曲线,形成闭合的区域。
二、轮廓检测的基本流程
下图展示了图像轮廓检测的完整流程:
图片输入 → 灰度化 → 二值化 → 寻找轮廓 → 绘制轮廓 → 图片输出
下面我们详细解析每个步骤:
三、轮廓检测详细步骤
3.1 读取图像
python
import cv2
# 读取图像
image = cv2.imread('./picture.png')
# 复制一份用于绘制轮廓
image_contours = image.copy()
3.2 灰度化处理
将彩色图像转换为灰度图像,减少后续处理的计算量:
python
# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
3.3 二值化处理
二值化是将灰度图像转换为黑白图像的过程。这是轮廓检测的关键步骤,因为findContours()函数要求输入是二值图像:
python
# 二值化
# 注意:目标物体需要是白色的,背景是黑色的
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)
重要提示 :OpenCV的轮廓检测函数要求目标物体是白色的,背景是黑色的。如果原始图像中目标物体是黑色的,需要使用反向阈值化(如THRESH_BINARY_INV)。
3.4 寻找轮廓
使用findContours()函数查找图像中的所有轮廓:
python
# 查找轮廓
contours, hierarchy = cv2.findContours(
binary, # 输入二值图像
cv2.RETR_EXTERNAL, # 轮廓检索模式
cv2.CHAIN_APPROX_SIMPLE # 轮廓近似方法
)
函数参数详解:
-
轮廓检索模式:
cv2.RETR_EXTERNAL:只检测最外层轮廓cv2.RETR_LIST:检测所有轮廓,不建立层级关系cv2.RETR_CCOMP:检测所有轮廓,并建立两级层级关系cv2.RETR_TREE:检测所有轮廓,并建立完整的层级树
-
轮廓近似方法:
cv2.CHAIN_APPROX_NONE:存储所有轮廓点cv2.CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角方向,只存储端点cv2.CHAIN_APPROX_TC89_L1:使用Teh-Chin链逼近算法cv2.CHAIN_APPROX_TC89_KCOS:使用Teh-Chin链逼近算法
返回值说明:
-
contours:一个列表,包含所有轮廓的坐标点contours[0]:第0个轮廓的所有边界点坐标contours[1]:第1个轮廓的所有边界点坐标
-
hierarchy:轮廓的层级关系,是一个四维数组hierarchy[i] = [next, previous, child, parent]next:同层级下一个轮廓的索引previous:同层级前一个轮廓的索引child:第一个子轮廓的索引parent:父轮廓的索引
3.5 绘制轮廓
使用drawContours()函数在图像上绘制找到的轮廓:

python
# 绘制所有轮廓
cv2.drawContours(
image_contours, # 目标图像
contours, # 轮廓列表
-1, # 轮廓索引(-1表示绘制所有)
(0, 0, 255), # 颜色(BGR格式)
2 # 线条粗细
)
# 或者只绘制指定轮廓
cv2.drawContours(
image_contours,
contours,
1, # 只绘制第2个轮廓(索引从0开始)
(0, 255, 0),
cv2.FILLED # 填充轮廓内部
)
函数参数详解:
-
轮廓索引:
- 整数:绘制指定索引的轮廓
-1:绘制所有轮廓
-
线条粗细:
- 正整数:轮廓线条的像素宽度
cv2.FILLED:填充轮廓内部
四、轮廓分析常用函数
4.1 轮廓面积和周长
python
# 计算轮廓面积
area = cv2.contourArea(contour)
# 计算轮廓周长
perimeter = cv2.arcLength(contour, closed=True) # closed表示是否为闭合轮廓
4.2 轮廓近似
python
# 多边形近似
epsilon = 0.02 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# 凸包检测
hull = cv2.convexHull(contour)
4.3 轮廓边界几何
python
# 获取最小外接矩形
rect = cv2.boundingRect(contour) # 返回 (x, y, w, h)
# 获取旋转矩形
rotated_rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rotated_rect)
box = np.int0(box)
# 获取最小外接圆
(x, y), radius = cv2.minEnclosingCircle(contour)
# 获取拟合椭圆
ellipse = cv2.fitEllipse(contour)
4.4 轮廓特征
python
# 计算轮廓中心(质心)
M = cv2.moments(contour)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
九、总结
图像轮廓检测是计算机视觉中的基础技术,在物体识别、形状分析、图像分割等领域有广泛应用。通过本文的学习,你应该已经掌握了:
- 轮廓检测的基本流程:灰度化、二值化、寻找轮廓、绘制轮廓
- OpenCV关键函数 :
findContours()和drawContours()的使用 - 轮廓分析方法:面积、周长、边界几何等特征提取
- 实际应用场景:物体计数、形状识别、轮廓匹配等
轮廓检测通常与其他图像处理技术(如边缘检测、形态学操作)结合使用,以达到更好的效果。在实际应用中,需要根据具体需求选择合适的参数和方法。