1.图像二值分析
1.1.图像二值化
常见的二值化方法如下:
- 基于全局阈值(threshold函数)得到的二值图像
- 基于自适应阈值(adaptiveThreshold函数)得到的二值图像
- 基于边缘检测(Canny函数)得到的二值图像
- 基于像数值范围1(inRange函数)得到的二值图像
全局阈值分割
double cv::threshold(InputArray src,OutputArray dst,double thresh,double maxval,int type)
- src:输入图像
- dst:输出图像
- thresh:阈值
- maxval:最大值
- type:阈值化方法
- THRESH_BINARY:二值化,大于阈值的赋值为最大值,其他情况下赋值为0
- THRESH_BINARY_INV:二值化反,大于阈值的赋值为0,其他情况下赋值为最大值
- THRESH_TRUNC:阈值截断,大于阈值的赋值为阈值,其他情况下赋值为0
- THRESH_TOZERO:阈值取零,大于阈值的保留原有值,其他情况下赋值为0
- THRESH_TOZERO_INV:阈值取零反,大于阈值的赋值为0,其他情况下保留原有值
- THRESH_OTSU:使用大律法自动计算阈值,这时输入图像src必须为单通道灰度图像
- THRESH_TRIANGLE:三角法求阈值
自适应阈值分割:
void cv::adaptiveThhreshold(InputArray src,OutputArray dst,double maxval,int adaptiveMethhod,int thresholdType,int blockSize,double c)
- src:输入图像
- dst:输出图像
- maxval:赋值给满足自适应条件的前景图像灰度值,一般设置为255即可
- adaptiveMethhod:自适应方法,有均值自适应(ADAPTIVE_THRESH_MEAN_C)和高斯自适应(ADAPTIVE_THRESH_GAUSSIAN_C)两种
- thresholdType:阈值化类型
- blockSize:计算时候窗口大小1,且必须为奇数
- c:常量
1.2.连通组件分析
连通组件标记:
int cv::connectedComponents(
InputArray image, //输入的二值图像
OutputArray labels, //输出的标记,其中背景标记为0
int connectivity=8, //连通域,默认是8连通
int ltype=CV_32S //输出的labels类型默认是CV_32S
)
在上述代码当中,labels输出的标签图像,每个像素点都有一个标签值,在正常情况下,标签值大于0且相同的像素点属于同一个连通组件。标签的数据类型默认为整数类型(CV_32S);带有统计信息的函数定义如下:
int cv::connectedComponentsWithStats( InputArray image, OutputArray labels, OutputArray stats, OutputArray centroids, int connectivity=8, int ltype=CV_32S, int ccltype )
在上述代码中,centriods是每个连通组件的中心坐标,stats参数表示的是统计信息,这些统计信息包含以下内容:
- CC_STAT_LEFT:连通组件的外接矩形左上角的x值
- CC_STAT_TOP:连通组件的外接矩形左上角的y值
- CC_STAT_WIDTH:连通组件的外接矩形宽度
- CC_STAT_HEIGHT:连通组件的外接矩形高度
- CC_STAT_AREA:像素总和/连通组件面积
1.3.轮廓分析
轮廓发现
void cv::findContours(InputArray image,OutputArrayOfArrays contours,OutputArray hierarchy,int mode,int method,Point offset=Point())
- image:输入图像,且必须是单通道的
- contours:所有轮廓,每个轮廓都是一个编码点集合
- hierarchy:所有轮廓的层次信息合集,每个对象的轮廓层次用一个Vec4i数据结构表示:
同层下个轮廓索引 |
同层上个轮廓索引 |
下层第一个子轮廓索引 |
上层父轮廓索引 |
Vec4i[0] |
Vec4i[1] |
Vec4i[2] |
Vec4i[3] |
- mode:获取轮廓信息方式
- RETR_EXTERNAL:只获取最外层的轮廓
- RETR_TREE:获取全部轮廓,并且按照树形结构组织将拓扑信息输出到hierarchy参数
- method:每个轮廓点的编码方式
- CHAIN_APPROX_NONE:表示对所有轮廓点进行编码
- CHAIN_APPROX_SIMPLE:表示过滤水平、垂直、对角线上的点,只保留顶点,用这种方式来实现轮廓编码
- offset:每个轮廓点是否有相对于原图的位置迁移
轮廓绘制
void cv::drawContrours(
InputOutputArray image, //需要将轮廓信息绘制在该图像
InputArrayOfArrays contours, //绘制的所有轮廓数据
int contourIdx, //表示绘制第几个轮廓,当设为-1时,表示绘制所有轮廓
const Scalar &color, //绘制轮廓的颜色
int thinkness=1, //绘制轮廓的线宽,当设为-1时,表示填充该轮廓
int lineType=LINE_8, //绘制轮廓的线段类型
InputArray hierarchy=noArray(),//可选的层次信息
int maxLevel=INT_MAX, //当设为0时,表示只绘制当前的轮廓;当设为1时,表示绘制当前轮廓与它的嵌套轮廓;当设为2时,表示绘制当前轮廓与它嵌套轮廓的嵌套轮廓,以此类推
Point offset=Point()
)
//注意:只有设置了hierarchy时,maxLevel才有效
轮廓测量
//计算面积
double cv::contourArea(InputArray contour,booll oriented=false)
//计算周长
double cv::arcLength(InputArray curve,bool close)
//计算轮廓最大外接矩形
Rect cv::boundingRect(InputArray array)
//计算轮廓最下外接矩形
RotatedRect cv::minAreaRect(InputArray points)
拟合与逼近
//拟合椭圆
//RotatedRect的输出包含拟合之后的椭圆中心位置、椭圆的长轴和短轴直径、椭圆倾斜角度
RotatedRect cv::fitEllipse(InputArray points)
//拟合直线
void cv::fitLine(InputArray points,OutputArray line,int distType,double param,doublle,reps,double aeps)
//轮廓逼近
void cv::approxPollyDP(InputArray curve,OutputArray approxCurve,double epsilon,bool closed)
轮廓分析
(1)横纵比
轮廓外接矩形的横纵比(宽度/高度),外接矩形包括最大外接矩形和最小外接矩形
(2)延展度
轮廓面积与最大外接矩形的比值
(3)实密度
轮廓面积与凸包面积的比值
(4)对象像素均值
在进行轮廓绘制时,将thickness设置为-1就能完成轮廓填充,并生成轮廓对象所对应的掩膜,然后用mean函数实现对掩膜区域的均值求解,最终得到每个对象的轮廓所占区域的像素均值
2.图像形态学
2.1.腐蚀与膨胀
//膨胀操作
void cv::dilate(
InputArray src, //输入图像
OutputArray dst, //输出图像
InputArray kernel, //结构元素
Point anchor=Point(-1,-1), //锚定点
int iterations=1, //迭代次数
int borderType=BORDER_CONSTANT,//边缘处理方式
const Scalar &borderValue=morphologyDefaultBorderValue()
)
//腐蚀操作
void cv::erode(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar &borderValue=morphologyDefaultBorderValue()
)
OpenCV中获取结构元素的函数如下:
Mat cv::getStructuringElement(
int shape, //形状
Size ksize, //大小
Point anchor=Point(-1,-1) //锚定
)
shape支持3种类型的形状结构:
- cv::MORPH_RECT=0:矩形结构,支持任意宽高比
- cv::MORPH_CROSS=1:十字交叉
- cv::MORHH_ELLIPSE=2:椭圆或圆形
2.2.开/闭操作
- 开操作的定义时先腐蚀后膨胀,即开操作=腐蚀+膨胀。
- 闭操作的定义时先膨胀后腐蚀,即闭操作=膨胀+腐蚀。
OpenCV可以通过设置morphologyEx函数的参数来支持指定的形态学操作,即可以通过该函数来完成形态学的各种操作:
void cv::morphologyEx(
InputArray src, //输入图像
OutputArray dst, //输出图像
int op, //形态学操作
InputArray kernel, //结构元素
Point anchor=Point(-1,-1), //锚定点
int iterations=1, //迭代次数
int borderType=BORDER_CONSTANT,//边缘处理方式
const Scalar &borderValue=morphologyDefaultBorderValue()
)
- 当op=MORPH_OPEN时表示执行的是开操作,开操作可以删除二值图像中较小的干扰块,解决图像二值化之后噪点过多的问题
- 当op=MORPH_CLOSE时表示执行的是闭操作,闭操作常用于填充二值图像内部的孔洞区域,以获得更加完整的前景对象
2.3.形态学梯度
- 基本梯度– 膨胀减去腐蚀之后的结果
- 内梯度– 原图减去腐蚀之后的结果
- 外梯度– 膨胀减去原图的结果
2.4.顶帽与黑帽
在OpenCV当中执行顶帽和黑帽的操作都需要先调用morphologyEx函数,然后将op参数分别设置为MORPH_TOPHAT和MORPH_BLACKHAT
- MORPH_TOPHAT:顶帽的定义是用原图减去开操作之后的结果
- MORPH_BLACKHAT:黑帽的定义是用闭操作之后的结构减去原图