OpenCV图像视频分析(1)

发布于:2024-11-28 ⋅ 阅读:(40) ⋅ 点赞:(0)

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:黑帽的定义是用闭操作之后的结构减去原图