OpenCV:图像轮廓
目录
简述
1. 什么是图像轮廓?
2. 查找图像轮廓
2.1 接口定义
2.2 参数说明
2.3 代码示例
2.4 运行结果
3. 绘制图像轮廓
3.1 接口定义
3.2 参数说明
3.3 代码示例
3.4 运行结果
4. 计算轮廓周长
5. 计算轮廓面积
6. 示例:计算图像轮廓的面积与周长
7. 应用场景
相关阅读
OpenCV:多边形逼近与凸包-CSDN博客
简述
在图像处理领域,轮廓是图像中物体的边界或形状信息的表达方式。通过提取轮廓,可以对图像中的目标进行识别、测量和分析。本文将从概念到实际操作详细介绍图像轮廓及其相关操作,并展示如何在 OpenCV 中实现。
1. 什么是图像轮廓?
图像轮廓 是图像中物体边界的闭合曲线,表示具有相同强度或颜色像素的连接路径。它是一种重要的图像特征,常用于形状分析和对象检测。
特点
- 轮廓基于二值图像计算,必须先将输入图像转换为二值图。
- OpenCV 提供的轮廓查找算法将视图像中的白色区域为前景(目标)。
- 轮廓的方向可以是顺时针或逆时针。
2. 查找图像轮廓
OpenCV 提供了 cv2.findContours() 函数来查找图像的轮廓。
2.1 接口定义
contours, hierarchy = cv2.findContours(image, mode, method)
2.2 参数说明
image:输入的二值图像(通常是灰度图的阈值化结果)。
mode:轮廓的检索模式,常见值:
- cv2.RETR_EXTERNAL:只检测最外层轮廓。
- cv2.RETR_LIST:检测所有轮廓,不建立层级关系。
- cv2.RETR_TREE:检测所有轮廓,并构建完整层级关系。
method:轮廓的近似方法:
- cv2.CHAIN_APPROX_NONE:存储所有的轮廓点。
- cv2.CHAIN_APPROX_SIMPLE:只存储必要的轮廓点,压缩水平和垂直冗余点。
返回值:
- contours:检测到的轮廓列表,每个轮廓是一个 Numpy 数组。
- hierarchy:每个轮廓的层级关系。
2.3 代码示例
import cv2
# 读取图像并转为灰度图
image = cv2.imread('D:\\resource\\filter\\find_contours.png', cv2.IMREAD_GRAYSCALE)
# 二值化
_, binary_img = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)
# 轮廓查找
#contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
# 显示图像
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
示例说明:
- 当前示例使用的图像为:白色背景,中间画了一个黑色的矩形。
- 用win11自带的画图软件画出来的,并非纯粹的黑白图像,在代码中最好进行二值化处理。
- 该示例的作用是将图像中所有轮廓的必要点打印出来。
2.4 运行结果
打印结果显示的是:图像必要的轮廓点。
该图像包含2个轮廓 :
- 最外层的白色背景边框。
- 中间黑色矩形边框。
3. 绘制图像轮廓
OpenCV 提供了 cv2.drawContours() 函数用于绘制轮廓。
3.1 接口定义
cv2.drawContours(image, contours, contourIdx, color, thickness)
3.2 参数说明
image:目标图像,轮廓将绘制在此图像上。
contours:轮廓数据,cv2.findContours() 的输出。
contourIdx:指定绘制的轮廓索引:
- -1:绘制所有轮廓。
- >=0:绘制特定索引的轮廓。
color:绘制轮廓的颜色(BGR 格式)。
thickness:线条粗细,-1 表示填充轮廓。
3.3 代码示例
import cv2
# 读取图像
image = cv2.imread('D:\\resource\\filter\\find_contours.png')
# 转为灰度图
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
_, binary_img = cv2.threshold(gray_img, 150, 255, cv2.THRESH_BINARY)
# 轮廓查找
contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
result = cv2.drawContours(image, contours, -1, (0,0,255), 2)
# 显示图像
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
示例说明:
- 依旧使用同一张图片。
- 该示例的作用是将图像中所有的轮廓用红色的线条绘制出来,其中线条的粗细数值为2。
3.4 运行结果
将图像中所有的轮廓绘制出来:
4. 计算轮廓周长
OpenCV 提供了 cv2.arcLength() 函数计算轮廓的周长。
接口定义
perimeter = cv2.arcLength(curve, closed)
参数说明
curve
:输入轮廓点。closed
:布尔值,是否将轮廓视为闭合曲线。
返回值:
轮廓的周长(浮点数)。
5. 计算轮廓面积
OpenCV 提供了 cv2.contourArea() 函数计算轮廓的面积。
接口定义:
area = cv2.contourArea(contour)
参数说明:
contour:
输入轮廓点。
返回值:
轮廓的面积(浮点数)。
6. 示例:计算图像轮廓的面积与周长
示例如下:
import cv2
# 读取图像
image = cv2.imread('D:\\resource\\filter\\find_contours.png')
# 转为灰度图
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
_, binary_img = cv2.threshold(gray_img, 150, 255, cv2.THRESH_BINARY)
# 轮廓查找
#contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# print(contours)
# 绘制轮廓
#result = cv2.drawContours(image, contours, -1, (0,0,255), 2)
# 计算面积
area = cv2.contourArea(contours[1])
print("area=%d"%(area))
# 计算周长
len = cv2.arcLength(contours[1], True)
print("len=%d"%(len))
# 显示图像
#cv2.imshow('image', image)
#cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
示例说明:
- 依旧使用同一张图像。
- 查找图像轮廓,取索引为1的轮廓。
- 计算其面积与周长,并打印出来。
打印输出:
PS D:\code\opencv_python> & "D:/Program Files/Python38-32/python.exe" d:/code/opencv_python/calc_contours.py
area=35951
len=769
PS D:\code\opencv_python>
7. 应用场景
- 目标检测与识别:通过轮廓提取图像中的特定对象。
- 形状分析:计算周长、面积等几何属性。
- 物体测量:用于测量物体的尺寸和外观特征。