最近几天学习了好多opencv里有关轮廓查找与绘制的函数,想做一下整理,把所有学的函数列出来,以便于统一思考一下,怎样充分的运用它们做一些自己想做的事情。就比如我最近参加一个比赛,负责做我们项目里的动作行为识别,轮廓识别就是首当其冲的一个研究点。
今天把它们列在这里,也希望可以帮到各位博客友人,以便于思考解决你们想做的事情。
1、什么是轮廓?
轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度,提取轮廓就是提取这些具有相同颜色或者灰度的曲线,或者说是连通域,轮廓在形状分析和物体的检测和识别中非常有用。
注意事项:
①为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理
或者 Canny 边界检测
②查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图
像的话,你应该将原始图像存储到其他变量中(clone(), copyTo())
③在OpenCV中,查找轮廓就像在黑色背景中找白色物体。你应该记住,
要找的物体应该是白色而背景应该是黑色。
2、开始上函数!
(1)查找轮廓---findContours()
image: 输入图像, Mat类型8位单通道图像(一般为二值图)
contours: 检测到的轮廓, 每个轮廓存储为一个点向量, 即Point类型的vector表示
hierarchy: 可选的输出向量, 包含图像的拓扑信息。其作为轮廓数量的表示, 包含了许多元素, 每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0]~hierarchy[i][3], 分别表示后一轮廓、前一轮廓、父轮廓、内嵌轮廓的索引编号, 如果没有对应项, 设置为负数
mode: 轮廓检索模式, 取值如下:
CV_RETR_EXTERNAL=0-----表示只检测最外层轮廓
CV_RETR_LIST=1------提取所有轮廓并放置在list中, 轮廓不建立等级关系
CV_RETR_CCOMP=2------提取所有轮廓并组织为双层结构
CV_RETR_TREE=3------提取所有轮廓并重新建立网状轮廓结构
method: 轮廓的近似方法
offset: 每个轮廓的可选偏移量, 默认值Point()
例子:
(2)绘制轮廓---drawContours()
image: 目标图像, Mat类型对象即可
contours: 所有的输入轮廓, 每个轮廓存储为一个点向量
contourIdx: 轮廓绘制指示变量(索引), 若为负值, 则表示绘制所有轮廓
color: 绘制轮廓的颜色
thickness: 轮廓线条的粗细, 默认值1, 如果为负值, 则绘制轮廓内部, 可选宏 CV_FILLED
lineType: 线条类型, 默认值8
hierarcy: 可选的层次结构信息, 默认值noArray()
maxLevel: 表示用于绘制轮廓的最大等级, 默认值INT_MAX
offset: 可选的轮廓偏移参数, 默认值Point()
例子:
(3)寻找凸包---convexHull()
points: 输入的二维点集, 可以填Mat类型或std::vector
hull: 函数调用后找到的凸包
clockwise: 操作方向标志符, 当为true时, 输出的凸包为顺时针方向, false为逆时针方向(假定坐标系x轴指向右,y轴指向上方)
returnPoints: 操作标志符, 默认值true. 当标志符为true时, 函数返回凸包各个点, 否则返回凸包各点的指数, 当输出数组是std::vector时, 此标志被忽略
例子1:
例子2:
(4)凸包缺陷分析---convexityDefects()
contour: 表示输入参数检测到的轮廓, 可以用findContours函数获得
convexhull: 输入参数表示检测到的凸包, 可以用convexHull函数获得
convexityDefects: 检测到的最终结果, 应为vector<vector<Vec4i>>类型, Vec4i存储了起始点、结束点、距离及最远点到凸包的距离
(5)轮廓外接矩形---boundingRect()
points: 输入的二维点集, 可以填Mat类型或std::vector
返回值: Rect类矩形对象
例子:
(6)轮廓最小外接矩形---minAreaRect()
points: 输入的二维点集, 可以填Mat类型或std::vector
返回值: RotatedRect类矩形对象, 外接旋转矩形主要成员有center、size、 angle、points
例子:
(7)轮廓最小外接圆---minEnclosingCircle()
points: 输入的二维点集, 可以填Mat类型或std::vector
center: Point2f&类型的center, 圆的输出圆心
radius: float&类型, 表示圆的输出半径
(8)轮廓椭圆拟合---fitEllipse()
points: 输入的二维点集, 可以填Mat类型或std::vector
返回值: RotatedRect类旋转矩形对象
(9)逼近多边形曲线---approxPolyDP()
curve: 输入的二维点集, 可以填Mat类型或std::vector
approxCurve: 多边形逼近的结果, 其类型和输入二维点集类型一致
epsilon: 逼近的精度, 为原始曲线和近似曲线间的最大值
closed: 如果其为真, 则近似的曲线为封闭曲线, 否则近似的曲线不封闭
(10)计算轮廓面积---contourArea()
contour: 输入的二维点集或轮廓, 可以填Mat类型或std::vector
oriented: 默认值false, 表示返回面积为绝对值, 负责带符号
返回值: double类型返回轮廓面积
(11)计算轮廓长度---arcLength()
curve: 输入的二维点集, 可以填Mat类型或std::vector
colsed: 用于指示曲线是否封闭的标识符, 默认值true, 表示曲线封闭
返回值: double类型返回轮廓长度
(12)计算点与轮廓的距离及位置关系---pointPolygonTest()
contour: 所需检测的轮廓对象
pt: Point2f 类型的pt, 待判定位置的点
measureDist: 是否计算距离的标志, 当其为true时, 计算点到轮廓的最短距离, 当其为false时, 只判定轮廓与点的位置关系, 具体关系如下:
①返回值为-1, 表示点在轮廓外部
②返回值为0, 表示点在轮廓上
③返回值为1, 表示点在轮廓内部
例子:
(13)矩的计算---moments()
array: 输入参数, 可以是光栅图像或二维数组
binaryImage:默认值false, 非零像素取其本身值, 若为true, 则非零像素取1
返回值: Moments类的对象, 返回对应的轮廓的空间矩/中心矩和归一化中心矩(最高3阶)
例子:
(14)形状匹配---matchShapes()
contour1: 所需比较的轮廓1
contour2: 所需比较的轮廓2
method: 轮廓比较的方法
parameter: 比较方法的特殊参数(目前不支持)
(15)颜色空间转换---cvtColor()
(16)颜色区间范围删选---inRange()
src: 输入原图或数组
lowerb: 低边界或者颜色阈值
upperb: 高边界或者颜色阈值
dst: 输出目标图像, 需要和原图一样的size并且类型需为CV_8U
例子: