Opencv系列(二)


Opencv图像滤波

连通域&直方图

计算图像直方图

void cv::calcHist
(   
    const Mat *     images,           //输入图像
    int     nimages,                  //源图像的个数(通常为1)
    const int *     channels,         //列出通道
    InputArray  mask,                 //输入掩码(需处理的像素)
    OutputArray     hist,             //输出直方图
    int     dims,                     //直方图的维度(通道数量)
    const int *     histSize,         //每个维度位数
    const float **  ranges,           //每个维度的范围
    bool    uniform = true,           //true表示箱子间距相同
    bool    accumulate = false        //是否在多次调用时进行累积
    )

二值函数

cv::threshold()

〖原理〗:通过将所有像素与某个阈值(第三个参数)进行比较赋值,将图像表示为只有两种像素值的图像(例子:学生排队)。

阈值是图像分割的标尺。

#include<opencv2/imgproc.hpp>
//创建二值图像
double cv::threshold
(   
    InputArray  src,          //输入图像(多通道、8位或32位浮点类型)   
    OutputArray     dst,      //输出图像
    double  thresh,           //指定阈值
    double  maxval,           //设定最大值(常取255)
    int     type              //阈值类型
    )
/*type,详见参数介绍
1、THRESH_BINARY:将所有大于thresh的像素赋值为maxval,将其他像素赋值为0;
2、THRESH_BINARY_INY:将所有大于thresh的像素赋值为0,将其他像素赋值为maxval;
3、THRESH_TRUNC:截断,将所有大于thresh的像素赋值为thresh,其他像素值不变;
4、THRESH_TOZERO:所有大于thresh的像素值保持不变,将其他像素赋值为0;
5、THRESH_TOZERO_INV:所有大于thresh的像素值赋值为0,其他像素值保持不变.
6、THRESH_OTSU:使用Otsu算法去寻找到最优的阈值
7、THRESH_TRIANGLE:使用三角化方法寻找到最有的阈值
*/

【应用】:可用于区分图像的前景和背景(通常前景的像素值大于背景的像素值);

形态学运算变换图像

概念

  • 形态学是一种滤波器,用结构元素探测图像中每个像素的操作过程称为形态学滤波器的应用过程;
  • 结构元素是一堆像素的组合,原则上可以是任何形状,通常是正方形、圆形或菱形,中心点为原点(锚点)。
    作用
  • 可用于强化或消除特殊形状

腐蚀与膨胀

//腐蚀图像
//原理:在某个像素上应用结构元素时,结构元素的锚点与该像素对齐,腐蚀就是把当前像素替换
成所定义像素集合中的最小像素值。
void cv::erode  (   
    InputArray  src,           //输入图像:灰度图像&彩色图像
    OutputArray     dst,       //输出图像
    InputArray  kernel,           //结构元素,默认cv::Mat(),3x3的正方形
    Point   anchor = Point(-1,-1),  //结构元素的锚点位置,默认为中心
    int     iterations = 1,         //腐蚀次数
    int     borderType = BORDER_CONSTANT,  //边界类型(像素外推的方法)
    const Scalar &  borderValue = morphologyDefaultBorderValue()   //连续
边界的边界值
)

//膨胀图像
//原理:把当前像素替换成所定义像素集合中的最大像素值。
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::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() 
)   

形态学梯度运算提取图像边缘

//以腐蚀和膨胀操作作为基础,执行高级的形态变换
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() 
)   

图形分割

CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers );
// cv::InputArray image:待分割的源图像;
// cv::InputOutputArray markers:标记图像;即这个参数用于存放函数调后的输出结果,需和源图片有一样的尺寸和类型。

利用分水岭算法实现图像分割

图像滤波

  • 概念:即选择性地提取图像中某些方面的内容,这些内容通常在特定的应用环境下传达了重要信息。
  • 作用:滤波器是一种放大(也可以不改变)图像中某些频段,同时滤掉(或减弱)其他频段的算子,分为低通滤波器&高通滤波器。
  • 示例:去噪(噪声点)、重采样

频域分析

描述图像的两种形式:

  • 频域:观察图像内容强度值(灰度值)变化的频率(蓝天 VS 杂货间),图像中精致的细节对应着高频;

  • 空域:观察图像内容灰度分布来描述图像特征(直方图)

频域分析:把图像分解成从低频到高频的频率成分。图像强度值变化慢的区域只包含低频率,强度值变化快的区域产生高频率。

二维图像的频率分为垂直频率和水平频率。

低通滤波器

目的:消除图像中的高频部分,减少图像变化的幅度(把前景变得光滑;把前景和背景之间的差异变小)。

常用方法:把每个像素的值替换成它周围像素的平均值,线性滤波。

块滤波器(box filter)——>卷积核(掩膜)

//典型示例一:均值滤波器
void cv::blur   (   
    InputArray  src,                  //输入图像
    OutputArray     dst,              //输出图像
    Size    ksize,                    //卷积核大小(值为系统默认指定?)
    Point   anchor = Point(-1,-1),     //锚点位置
    int     borderType = BORDER_DEFAULT //边界类型
)   
void cv::boxFilter  (   
    InputArray  src,
    OutputArray     dst,
    int     ddepth,
    Size    ksize,
    Point   anchor = Point(-1,-1),
    bool    normalize = true,
    int     borderType = BORDER_DEFAULT 
)   
void cv::filter2D   (   
    InputArray  src,
    OutputArray     dst,
    int     ddepth,
    InputArray  kernel,                        //卷积核值
    Point   anchor = Point(-1,-1),
    double  delta = 0,
    int     borderType = BORDER_DEFAULT 
)   
//典型示例二:高斯滤波器
void cv::GaussianBlur   (   
    InputArray  src,
    OutputArray     dst,
    Size    ksize,                   //滤波器尺寸,必须为奇数,否则会引发错误
    double  sigmaX,                  //控制高斯曲线水平方向形状的参数
    double  sigmaY = 0,              //控制高斯曲线垂直方向形状的参数
    int     borderType = BORDER_DEFAULT     
)  

图像降采样

  • 降低图像精度的过程称为缩减像素采样(downsampling);
  • 提升图像精度的过程称为提升像素采样(upsampling)

难点:重采样的过程需要尽可能地保持图像质量

中值滤波器

//原理:非线性滤波,把当前像素和它的邻域组成一个集合,然后计算出这个集合的中间值,以此
作为当前像素的值(用邻域内集合的中位数代替当前像素值)
void cv::medianBlur (   
    InputArray  src,
    OutputArray     dst,
    int     ksize                    //注意这里的ksize类型是 int类型
)

高通滤波器

定向滤波器(边缘检测)

  • 二维图像分为水平方向和垂直方向;
  • 比较经典的卷积核称为算子

Q:如何辨别x方向和y方向的滤波?(分别沿x/y方向去找灰度值发生急剧变化的边缘处)

//Sobel滤波器:只对垂直或水平方向的图像频率起作用
void cv::Sobel  (   
    InputArray  src,
    OutputArray     dst,
    int     ddepth,             //位深,-1代表输出图像和源图像的位深相同
    int     dx,                 //x方向的微分,几阶导数
    int     dy,                 //y方向的微分,几阶导数
    int     ksize = 3,          //sobel内核尺寸,只能为 1,3,5或7
    double  scale = 1,
    double  delta = 0,
    int     borderType = BORDER_DEFAULT 
)   
//Schar滤波器
void cv::Scharr (   
    InputArray  src,
    OutputArray     dst,
    int     ddepth,           //注意,此处位深最好选用CV_16S,否则会丢失很多信息
    int     dx,
    int     dy,
    double  scale = 1,
    double  delta = 0,
    int     borderType = BORDER_DEFAULT 
)
  
    
//Laplacian算子    
void cv::Laplacian  (   
    InputArray  src,
    OutputArray     dst,
    int     ddepth,
    int     ksize = 1,
    double  scale = 1,
    double  delta = 0,
    int     borderType = BORDER_DEFAULT 
)       

Canny边缘检测算子

//Canny边缘检测算法
void cv::Canny  (   
    InputArray  image,           //8位的输入图像
    OutputArray     edges,       //输出图像,一般是二值图像
    double  threshold1,          //低阈值,常取高阈值的1/2或1/3
    double  threshold2,          //高阈值
    int     apertureSize = 3,    //sobel算子的size,通常取值3
    bool    L2gradient = false   //选择true表示用L2归一化,选择false表示用L1
来归一化
)

文章作者: oceanechy
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 oceanechy !
  目录