图像在采集、传输、处理的过程中通常都会存在一定的噪声干扰,噪声对于图像时一种干扰信息,使图像变得更模糊,掩盖了图像的一些特征,给图像处理带来了不便,滤波时消除图像在采集、传输和处理过程中所产生的噪声
滤波处理的函数主要有:均值滤波,方框滤波,高斯滤波,中值滤波,双边滤波
1、均值滤波
均值滤波是将当前像素周围像素点的像素平均值作为当前像素点的像素
void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT );
src:输入图像,图像的深度必须是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F其中的一种
dst:输出图像
ksize:滤波核的大小
anchor:锚点,该值默认为(-1,-1),在核的中心位置
borderType:图像边界处理的方法
图像在滤波时采用的处理通常为:选取当前点周围的若干个像素点的均值,例如选取ksize为Size(3,3),则当前像素点的值为其自身及其周围像素点共9个像素点的像素平均值,采用的滤波模板如下:
例如,有一个像素点的值为80,其周围的像素点如下图所示
75 | 193 | 37 |
121 | 80 | 189 |
45 | 94 | 232 |
如果对其进行均值滤波,则其滤波值的计算方法为:
Value=(75+193+37+121+80+189+45+94+232)/9=118
得到的当前的新值为118
blur(m_srcImage, m_dstImage, Size(1, 1), Point(-1, -1));
2、高斯滤波
高斯滤波中将中心点的权值加大,远离中心点的权值减小,最后得到当前点的像素值
例如,其模板可以为
void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
double sigmaX, double sigmaY = 0,
int borderType = BORDER_DEFAULT );
src:输入图像,图像的深度必须是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F其中的一种
dst:输出图像
ksize:高斯计算核。核的宽度核高度可以不相同,但是他们必须都是正奇数,或者在其为0时通过sigma的计算得到计算结果
sigmaX:表示核在x轴方向的标准偏差
sigmaY:表示核在y轴方向的标准偏差
borderType:边框样式
Mat getGaussianKernel( int ksize, double sigma, int ktype = CV_64F );
该函数用来产生高斯滤波器的系数
ksize:核大小,它应该是正的奇数
sigma:高斯标准偏差。如果不是正数,则通过计算得到
ktype:滤波器系数,它可以是CV_32F和CV_64F类型
GaussianBlur(m_srcImage, m_dstImage, Size(1, 1), 0, 0);
3、中值滤波
中值滤波是取当前像素点及其周围临近像素点总共奇数个像素点,将这些像素点排序,然后将位于中间位置的值作为当前像素点的像素值,例如,当前像素点是像素值为78的 位于图像中间的点
将上述排序后得到[66,78,90,91,93,94,95,97,101],该序列中处于中心位置的是93,因此用93来替换到原来的78作为当前点的新像素值,得到
void medianBlur( InputArray src, OutputArray dst, int ksize );
src:需要进行滤波的原始图像,可以是1、3、4通道的图像,当ksize大小为3或者5时,图像深度应该是CV_8U,CV_16U或cv_32f,对于大尺度图像图像只能时CV_8U
dst:滤波处理结果图像
ksize:核的尺度大小,必须时大于1的奇数,例如3、5、7等
medianBlur(m_srcImage, m_dstImage,3);
4、双边滤波
双边滤波指有两种因素影响着滤波,一种时空间距离,一种时颜色差值范围,
控件距离决定距离当前像素多远的像素能够影响这当前滤波
颜色差值范围是指在当前指定控件范围内,与当前颜色的差值在多少范围内的颜色能够影响当前的滤波结果
void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT );
src:需要滤波的原始图像,图像为8位或者浮点型单通道、三通道
dst:滤波结果图像
d:在滤波时选取的空间距离参数,这里表示以当前像素点为中心点的直径,一般时5
sigmaColor:在滤波时选取的颜色差值范围,该值决定了周围哪些像素点能够参与到滤波中来
sigmaSpace:坐标空间中的sigma值,它的值越大,说明有越多的点能够参与到滤波计算中来
其中sigma的值:为了简单起见,可以将两个sigma的值设置为相同,如果他们比较小(<10),则滤波的效果会不太明显
如果它们的值较大(>150),则滤波效果会比较明显,会产生卡通效果
bilateralFilter(m_srcImage, m_dstImage, 31, 31 * 2, 31 / 2);
5、方框归一化滤波 方框非归一化滤波
方框滤波也同样采用周围像素点的平均值作为当前像素点的像素值,采用boxFilter完成
void boxFilter( InputArray src, OutputArray dst, int ddepth,
Size ksize, Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT );
src:要滤波的原始图像
dst:滤波结果图像
ddepth:滤波输出结果的图像深度,如果为-1,则表示与原始图像具有同样的深度
ksize:滤波核的大小
anchor:锚点,默认值为(-1,-1),表示锚点位于核中心点
normalize:标记值,标记是否使用当前的核进行归一化处理
borderType:用来推断图像的外部像素值
该滤波函数所使用的滤波核为
其中
通过上述公式可以看出,当normalize的值为true时,方框滤波就是均值滤波
boxFilter(m_srcImage, m_dstImage, -1, Size(5, 5));方框归一化滤波
boxFilter(m_srcImage, m_dstImage, -1, Size(1, 1), Point(-1, -1), false);方框非归一化滤波
总体如下
/*******滤波**********/
//方框滤波
void DlgImageProcessing::on_btnBoxFilter_clicked()
{
if (m_srcImage.data)
{
int ksize = ui.comboBoxFilterKsize->currentText().toInt();
bool normalize = false;
QString qsNormalize = ui.comboBoxFilterNormalize->currentText();
if (qsNormalize == "false")
{
normalize = false;
}
else
{
normalize = true;
}
Mat dstImage;
boxFilter(m_srcImage, dstImage, -1, Size(ksize, ksize), Point(-1, -1), normalize);
cv::imshow("this result", dstImage);
emit ShowImage(dstImage);
}
else
{
QMessageBox::warning(this, "提示", "没图片");
}
}
//均值滤波
void DlgImageProcessing::on_btnBlur_clicked()
{
if (m_srcImage.data)
{
int ksize = ui.comboBoxBlurKsize->currentText().toInt();
Mat dstImage;
blur(m_srcImage, dstImage, Size(ksize, ksize), Point(-1, -1));
cv::imshow("this result", dstImage);
emit ShowImage(dstImage);
}
else
{
QMessageBox::warning(this, "提示", "没图片");
}
}
//高斯滤波
void DlgImageProcessing::on_btnGaussianBlur_clicked()
{
if (m_srcImage.data)
{
int ksize = ui.comboBoxGaussianBlurKsize->currentText().toInt();
Mat dstImage;
GaussianBlur(m_srcImage, dstImage, Size(ksize, ksize), 0, 0);
cv::imshow("this result", dstImage);
emit ShowImage(dstImage);
}
else
{
QMessageBox::warning(this, "提示", "没图片");
}
}
//中值滤波
void DlgImageProcessing::on_btnMedianBlur_clicked()
{
if (m_srcImage.data)
{
int ksize = ui.comboBoxMedianBlurKsize->currentText().toInt();
Mat dstImage;
medianBlur(m_srcImage, dstImage, ksize);
cv::imshow("this result", dstImage);
emit ShowImage(dstImage);
}
else
{
QMessageBox::warning(this, "提示", "没图片");
}
}
//双边滤波
void DlgImageProcessing::on_btnBilateralFilter_clicked()
{
if (m_srcImage.data)
{
int d = ui.comboBoxBilateralFilterD->currentText().toInt();
double colorSigma = ui.comboBoxBilateralFilterColorSigma->currentText().toDouble();
double spaceSigma = ui.comboBoxBilateralFilterSpace->currentText().toDouble();
//bilateralFilter(m_srcImage, dstImage, 31, 31 * 2, 31 / 2);
Mat dstImage;
bilateralFilter(m_srcImage, dstImage, d, colorSigma, spaceSigma);
cv::imshow("this result", dstImage);
emit ShowImage(dstImage);
}
else
{
QMessageBox::warning(this, "提示", "没图片");
}
}
原图
双边滤波
方框滤波
均值滤波
高斯滤波
中值滤波
个人站点
1、CSDN地址:
2、知乎
欢迎关注我的知乎专题Qt学视觉 - 知乎使用qt所写的视觉软件https://www.zhihu.com/column/c_1237691650757353472
3、微信公众号《Qt学视觉》
欢迎关注