OpenCV学习之平滑、锐化、图像金字塔
1.平滑(模糊)
平滑又称模糊,是经常用来降噪(和其他目的)的一种图像处理操作。通过对图像应用线性滤波来执行平滑操作。
在线性运算中,像素的权值通常存储在一个称为核(Kernel)的矩阵中。因此,一个滤波可以表示为一个系数的滑动窗口。
中值滤波、高斯滤波和双边滤波都是最常用的OpenCV平滑滤波方法。中值滤波非常适合去除椒盐噪声或斑点噪声,而高斯滤波更适用于边缘检测的预处理阶段。另一方面,双边滤波对于平滑强边缘图像是一种很好的技术。
参考博客
void boxFilter(InputArray src,
OutputArray dst,
int ddepth,
Size ksize,
Point anchor=Point(-1,-1), //意味着定位像素是核的中心
bool normalize=true,
int borderType=BORDER_DEFAULT)
//该函数是一种盒式滤波,其核系数是相等的。
//对normalize=true,每个输出像素值均是其核邻域的均值,
//其所有系数均等于1/n,此处,n=元素的个数。
//对normalize=false,所有的系数都等于1
void GaussionBlur(InputArray src,
OutputArray dst,
Size ksize,
double sigmaX, //在x方向上高斯核的标准偏差(均方差)
double sigmaY=0, //在y方向上高斯核的标准偏差(均方差)
int borderType=BORDER_DEFAULT)
//该函数通过对src输入数组中的每个点用一个高斯核计算卷积,产生dst输出。
//如果sigmaY=0, 则将sigmaY设置为与sigmaX相等;
//如果sigmaX和sigmaY都设置为0,则使用ksize中给定的宽度和高度计算sigmaX和sigmaY
void medianBlur(InputArray src,
OutputArray dst,
int ksize)
//该函数作用于图像的每一个元素,并用邻域像素的中值替换每个像素
void bilateralFilter(InputArray src,
OutputArray dst,
int d, //像素邻域的直径
double sigmaColor, //
double sigmaSpace,
int borderType=BORDER_DEFAULT)
//该函数与高斯滤波类似,考虑将具有权值的邻域像素赋值给每一个像素,
//但和高斯滤波方法以及另一个考虑邻域和被估计像素之间强度的差值的滤波方法相同,
//每个权值仅有两个分量。
//参数sigmaColor的一个较大值意味着像素邻域内相差更远的颜色会被混合,生成的半对等颜色的面积也就越大;
//参数sigmaSpace的一个较大值意味着只要像素之间的颜色足够接近,则更远的像素之间会相互影响。
void blur(InputArray src,
OutputArray dst,
Size ksize,
Point anchor=Point(-1,-1),
int borderType=BORDER_DEFAULT)
//该函数使用归一化盒式滤波器来模糊一幅图像,
//它等价于使用normalize=true值得boxFilter函数。
2.锐化
在OPenCV中,用于锐化的函数有:
void Sobel(InputArray src,
OutputArray dst,
int ddepth, //-1:表示使用和输入图像相同的深度
int dx, //希望的导数阶
int dy, //希望的导数阶
int ksize=3, //核大小
double scale=1, //建立用于计算导数值的尺度因子
double delta=0,
int borderType=BORDER_DEFAULT) //边界类型
/* 该函数使用Sobel算子计算src中的一幅图像的一阶导数、二阶导数、三阶导数或混合图像导数。*/
void Scharr(InputArray src,
OutputArray dst,
int ddepth,
int dx,
int dy,
double scale=1,
double delta=0,
int borderType=BORDER_DEFAULT) //边界类型
/* 该函数计算一个大小为3*3的核更精确的导数。该函数与Sobel函数等价。*/
void Laplacian(InputArray src,
OutputArray dst,
int ddepth,
int ksize=1,
double scale=1;
double delta=0,
int borderType=BORDER_DEFAULT)
/*该函数计算一幅图像的Laplacian值。
3.图像金字塔
在对象检测问题中,通过检测整幅图像去试图找到对象,比较浪费时间。在这种情况下,从较小分辨率的一些图像开始进行对象搜索会更为有效。这种图像集合被形象地称之为金字塔或多级纹理,因为如果将这组图像按照由小到大、从下至上组织,其形式与金字塔结构类型非常相似。
有两种类型的图像金字塔:高斯金字塔和拉普拉斯金字塔。
- 高斯金字塔
高斯金字塔的创建方式如下:在更低的一层通过交替地隔行和隔列删除像素,然后通过对底层领域进行高斯滤波来获得更高一层的像素值。像这样每执行完金字塔的一个步骤后,图像的宽和高减少为原来的1/2,其面积减少为上一层图像面积的1/4。在OpenCV中,可以使用pyrDown, pytUp和buildPyramid计算高斯金字塔。
void pyrDown(InputArray src,
OutputArray dst,
const Size& dstsize=Size(),
int borderType=BORDER_DEFAULT);
//该函数下采样并模糊一幅src图像,将结果保存在dst中。
//当未设置参数dstsize时,其输出图像大小使用Size((src.clos+1)/2, (src.rows+1)/2)计算。
void pyrUp(InputArray src,
OutputArray dst,
const Size& dstsize=Size(),
int borderType=BORDER_DEFAULT);
void buildPyramid(InputArray src,
OutputArrayOfArrays dst,
int maxlevel,
int borderType=BORDER_DEFAULT)
//该函数为存储在src中的图像建立一个高斯金字塔,获得maxlevel幅新图像,
//并将其存储在dst数组中。
//其原始图像存储在dst[0]中,因此结果dst中存储了maxlevel+1幅图像
void pyrMeanShiftFiltering(InputArray src,
OutputArray dst,
double sp, //空间窗口半径
double sr, //颜色窗口半径
int maxLevel=1,
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 5, 1))
//该函数实现了均值漂移分割的滤波阶段,获取一幅具有颜色梯度和细粒度纹理平滑的图像dst,
//参数sp
- 拉普拉斯金字塔
在OpenCV中,虽然没有特定的函数来实现拉普拉斯金字塔,但是拉普拉斯金字塔可由高斯金字塔形成。拉普拉斯金字塔可以看成是其大部分元素为0的一些边界图像,拉普拉斯金字塔的第i层是高斯金字塔中第i层与高斯金字塔中i+1层的扩充版本之间的差。