学习 opencv---(8)非线性滤波:中值滤波,双边滤波
正如我们上一篇文章中讲到的,线性滤波可以实现很多种不同的图像变换。然而非线性滤波,如中值滤波器和双边滤波器,有时可以达到更好的实现效果。
邻域算子的其他一些例子还有对 二值图像进行操作的形态学算子,用于计算距离变换和寻找连通量的半全局算子
一、理论与概念讲解——从现象到本质
1.1 非线性滤波概述
之前的那篇文章里,我们所考虑的滤波器都是线性的,即俩个信号之和的响应和他们各自响应之和相等。换句话说,每个像素的输出值是一些输入像素的加权和,线性滤波器易于构造,并且易于从频率响应角度来进行分析。
其实在很多情况下,使用邻域像素的非线性滤波也许会得到更好的效果。比如在噪声是散粒噪声而不是高斯噪声,即图像偶尔会出现很大的值的时候。在这种情况下,用高斯滤波器对图像进行模糊的话,噪声像素是不会被去除的,它们只是转换为更为柔和但仍然可见的散粒。
这就到了中值滤波登场的时候了。
1.2 中值滤波
中值滤波(Median filter)是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像边缘细节,.
中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,其基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点,对于斑点噪声(speckle noise)和椒盐噪声(salt-and-pepper noise)来说尤其有用,因为它不依赖于邻域内那些与典型值差别很大的值。中值滤波器在处理连续图像窗函数时与线性滤波器的工作方式类似,但滤波过程却不再是加权运算。
中值滤波在一定的条件下可以克服常见线性滤波器如最小均方滤波、方框滤波器、均值滤波等带来的图像细节模糊,而且对滤除脉冲干扰及图像扫描噪声非常有效,也常用于保护边缘信息, 保存边缘的特性使它在不希望出现边缘模糊的场合也很有用,是非常经典的平滑噪声处理方法。
●中值滤波与均值滤波器比较:
中值滤波器与均值滤波器比较的优势:在均值滤波器中,由于噪声成分被放入平均计算中,所以输出受到了噪声的影响,但是在中值滤波器中,由于噪 声成分很难选上,所以几乎不会影响到输出。因此同样用3x3区域进行处理,中值滤波消除的噪声能力更胜一筹。中 值滤波无论是在消除噪声还是保存边缘方面都是一个不错的方法。
中值滤波器与均值滤波器比较的劣势:中值滤波花费的时间是均值滤波的5倍以上。
顾名思义,中值滤波选择每个像素的邻域像素中的中值作为输出,或者说中值滤波将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
例如,取3 x 3的函数窗,计算以点[i,j]为中心的函数窗像素中值步骤如下:
(1) 按强度值大小排列像素点.
(2) 选择排序像素集的中间值作为点[i,j]的新值.
这一过程如图下图所示.
一般采用奇数点的邻域来计算中值,但如果像素点数为偶数时,中值就取排序像素中间两点的平均值.采用大小不同邻域的中值滤波器的结果如图。
中值滤波在一定条件下,可以克服线性滤波器(如均值滤波等)所带来的图像细节模糊,而且对滤除脉冲干扰即图像扫描噪声最为有效。在实际运算过程中并不需要图像的统计特性,也给计算带来不少方便。但是对一些细节多,特别是线、尖顶等细节多的图像不宜采用中值滤波。
1.3 双边滤波
双边滤波(Bilateral Filter)是一种非线性的滤波方法,是结合图像的空间邻近度和 像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单,非迭代,局部的特点。
双边滤波器的好处是可以做边缘保存(edge preserving),一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。
在双边滤波器中,输出像素的值依赖于邻域像素值的加权值组合:
而加权系数w(i,j,k,l)取决于定义域核和值域核的乘积。
其中定义域核表示如下(如图):
定义域滤波对应图示:
值域核表示为:
值域滤波:
两者相乘后,就会产生依赖于数据的双边滤波权重函数:
二、深入——OpenCV源码分析溯源
(1)首先让我们一起领略medianBlur()函数的源码,。。
//-----------------------------------【medianBlur()函数中文注释版源代码】-------------------------
// 代码作用:进行中值滤波操作的函数
// 说明:以下代码为来自于计算机开源视觉库OpenCV的官方源代码
// OpenCV源代码版本:3.1.0
// 源码路径:…\opencv\sources\modules\imgproc\src\smooth.cpp
// 源文件中如下代码的起始行数:2760行
// 中文注释by hehhehhehhe
//-------------------------------------------------------------------------------------------------------- void cv::medianBlur(InputArray _src0, OutputArray _dst, int ksize)
{
//处理特定的ksize值的不同情况
CV_Assert((ksize % ==) && (_src0.dims()<=)); //CV_Assert()若括号中的表达式值为false,则返回一个错误信息。
if (ksize <= )
{
_src0.copyTo(_dst);
return;
} /*下面的语句还需时日来理解*/
CV_OCL_RUN(_dst.isUMat(),
ocl_medianFilter(_src0, _dst, ksize)) //拷贝形参Mat数据到临时变量,用于稍后的操作
Mat _src0 = _src0.getMat();
_dst.create(src0.size(),src0.type());
Mat dst = _dst.getMat(); CV_IPP_RUN(IPP_VERSION_X100 >= && ksize <= , ipp_medianFilter(_src0, _dst, ksize)); //若之前有过HAVE_TEGRA_OPTIMIZATION优化选项的定义,则执行宏体中的tegra优化版函数并返回
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::useTegra() && tegra::medianBlur(src0, dst, ksize))
return;
#endif bool useSortNet = ksize == || (ksize ==
#if !(CV_SSE2 || CV_NEON)
&& src0.depth() > CV_8U
#endif
); //开始正式进行滤波操作
Mat src;
if (useSortNet)
{
if (dst.data != src0.data)
src = src0;
else
src0.copyTo(src); //根据不同的景深,给medianBlur_SortNet函数取不同的模板类型值
if (src.depth() == CV_8U)
medianBlur_SortNet<MinMax8u, MinMaxVec8u>(src, dst, ksize);
else if (src.depth() == CV_16U)
medianBlur_SortNet<MinMax16u, MinMaxVec16u>(src, dst, ksize);
else if (src.depth() == CV_16S)
medianBlur_SortNet<MinMax16s, MinMaxVec16s>(src, dst, ksize);
else if (src.depth() == CV_32F)
medianBlur_SortNet<MinMax32f, MinMaxVec32f>(src, dst, ksize);
else
CV_Error(CV_StsUnsupportedFormat, ""); return;
}
else
{
cv::copyMakeBorder(src0, src, , , ksize / , ksize / , BORDER_REPLICATE); int cn = src0.channels();
CV_Assert(src.depth() == CV_8U && (cn == || cn == || cn == )); double img_size_mp = (double)(src0.total()) / ( << );
if (ksize <= + (img_size_mp < ? : img_size_mp < ? : )*
(MEDIAN_HAVE_SIMD && (checkHardwareSupport(CV_CPU_SSE2) || checkHardwareSupport(CV_CPU_NEON)) ? : ))
medianBlur_8u_Om(src, dst, ksize);
else
medianBlur_8u_O1(src, dst, ksize);
}
}
仔细阅读源码我们可以发现,正式进入滤波操作时,根据图像不同的位深,我们会给medianBlur_SortNet函数模板取不同的模板类型值,或者调用medianBlur_8u_Om或medianBlur_8u_O1来进行操作。
上面我们刚说到,medianBlur_SortNet 是一个函数模板,其源码于smooth.cpp的1439行开始,由于其函数体很长,我们在此只贴出它的函数声明。
template<class Op, class VecOp>
static void medianBlur_SortNet( constMat& _src, Mat& _dst, int m );
(2)bilateralFilter函数的源码也比较冗长
从3137行到3506行都是.。大家有兴趣自己去看源代码。,时间紧迫就不看了。。。。。。。。。。。。
再提一点,smooth.cpp源码的第2275行到2552行是OpenCV中自适应双边滤波器(adaptive BilateralFilter)的源代码,有兴趣和精力的童鞋可以去探究探究。(不过我在smooth.cpp没找到。。。。。。。。。。。。。。好尴尬)
三、浅出——API函数快速上手
3.1 中值滤波——medianBlur函数
medianBlur函数使用中值滤波器来平滑(模糊)处理一张图片,从src输入,而结果从dst输出。
且对于多通道图片,每一个通道都单独进行处理,并且支持就地操作(In-placeoperation)。
void medianBlur(InputArray src,OutputArray dst, int ksize);
参数详解:
- 第一个参数,InputArray类型的src,函数的输入参数,填1、3或者4通道的Mat类型的图像;当ksize为3或者5的时候,图像深度需为CV_8U,CV_16U,或CV_32F其中之一,而对于较大孔径尺寸的图片,它只能是CV_8U。
- 第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。我们可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
- 第三个参数,int类型的ksize,孔径的线性尺寸(aperture linear size),注意这个参数必须是大于1的奇数,比如:3,5,7,9 ...
图像深度是指存储每个像素所用的位数,也用于量度图像的色彩分辨率。
孔径的线性尺寸这个是什么东东。。。。。。。。。?????????????????????????
调用范例:
//载入原图
Mat image = imread("1.jpg");
//进行中值滤波操作
Mat out;
medianBlur(image, out, );
3.2 双边滤波——bilateralFilter函数
用双边滤波器来处理一张图片,由src输入图片,结果于dst输出。
void BilateralFilter(InputArray src, OutputArraydst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT);
- 第一个参数,InputArray类型的src,输入图像,即源图像,需要为8位或者浮点型单通道、三通道的图像。
- 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
- 第三个参数,int类型的d,表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
- 第四个参数,double类型的sigmaColor,颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
- 第五个参数,double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
- 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
调用代码示范如下:
//载入原图
Mat image=imread("1.jpg");
//进行双边滤波操作
Mat out;
bilateralFilter(image, out, , *, /);
3.3. 完整的实例
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> using namespace cv; /*--------------------------------------------------------
【1】 说明:中值滤波medianBlur
-----------------------------------------------------------*/ /*
void main()
{
//载入原图
Mat image = imread("1.jpg"); //创建窗口
namedWindow("中值滤波【原图】");
namedWindow("中值滤波【效果图】"); //显示原图
imshow("中值滤波【原图】",image); //进行中值滤波操作
Mat out;
medianBlur(image,out,1); //显示效果图
imshow("中值滤波【效果图】",out); waitKey();
}
*/ /*--------------------------------------------------------
【2】 说明:双边滤波bilatralFilter
-----------------------------------------------------------*/
/*
void main()
{
//载入原图
Mat image = imread("1.jpg"); //创建窗口
namedWindow("双边滤波【原图】");
namedWindow("双边滤波【效果图】"); //显示原图
imshow("双边滤波【原图】",image ); //进行双边滤波操作
Mat out;
bilateralFilter(image, out, 25,25*2,25/2 ); //显示效果图
imshow("双边滤波【效果图】",out); waitKey();
}
*/
四、综合示例——在实战中熟稔
依然是每篇文章都会配给大家的一个详细注释的博文配套示例程序,把这篇文章中介绍的知识点以代码为载体,展现给大家。
这个示例程序中可以用轨迹条来控制各种滤波(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)的参数值,通过滑动滚动条,就可以控制图像在各种平滑处理下的模糊度,有一定的可玩性。废话不多说,上代码吧:
Mat g_srcImage, g_dstImage1, g_dstImage2, g_dstImage3, g_dstImage4, g_dstImage5; //即图片的大小
int g_nBoxFilterValue = ; //方框滤波内核值
int g_nMeanBlurValue = ; //均值滤波内核值
int g_nGaussianBlurValue = ; //高斯滤波内核值
int g_nMedianBlurValue = ; //中值滤波内核值
int g_nBilateralFilterValue = ; //双边滤波内核值 static void on_BoxFilter(int, void *); //方框滤波
static void on_MeanBlur(int,void *); //均值滤波
static void on_GaussianBlur(int,void *); //高斯滤波
static void on_MedianBlur(int,void *); //中值滤波
static void on_BilateralFilter(int,void *); //双边滤波 int main()
{
system("color 5e"); //载入原图
g_srcImage = imread("1.jpg",);
if (!g_srcImage.data)
{
printf("Oh,no,读取srcImage错误~! \n");
return false;
} //克隆原图到5个Mat类型中
g_dstImage1 = g_srcImage.clone();
g_dstImage2 = g_srcImage.clone();
g_dstImage3 = g_srcImage.clone();
g_dstImage4 = g_srcImage.clone();
g_dstImage5 = g_srcImage.clone(); //显示原图
namedWindow("【<0>原图窗口】",);
imshow ("【<0>原图窗口】",g_srcImage); /*----------【1】方框滤波--------------*/
//创建窗口
namedWindow("【<1>方框滤波】",);
//创建轨迹条
createTrackbar("内核值:","【<1>方框滤波】",&g_nBoxFilterValue,,on_BoxFilter);
on_BoxFilter(g_nBoxFilterValue, );
//imshow("【<1>方框滤波】",g_dstImage1); /*----------【2】均值滤波--------------*/
//创建窗口
namedWindow("【<1>方框滤波】",);
//创建轨迹条
createTrackbar("内核值:", "【<2>均值滤波】", &g_nMeanBlurValue, , on_MeanBlur);
on_MeanBlur(g_nMeanBlurValue, );
//imshow("【<2>方框滤波】", g_dstImage2); /*----------【3】高斯滤波--------------*/
//创建窗口
namedWindow("【3】高斯滤波", );
//创建轨迹条
createTrackbar("内核值:", "【3】高斯滤波", &g_nGaussianBlurValue, , on_GaussianBlur);
on_GaussianBlur(g_nGaussianBlurValue, );
//imshow("【3】高斯滤波", g_dstImage3); /*----------【4】中值滤波--------------*/
//创建窗口
namedWindow("【4】中值滤波", );
//创建轨迹条
createTrackbar("内核值:", "【4】中值滤波", &g_nMedianBlurValue, , on_MedianBlur);
on_MedianBlur(g_nMedianBlurValue, );
//imshow("【4】中值滤波", g_dstImage4); /*----------【5】双边滤波--------------*/
//创建窗口
namedWindow("【5】双边滤波", );
//创建轨迹条
createTrackbar("内核值:", "【5】双边滤波", &g_nBilateralFilterValue, , on_BilateralFilter);
on_BilateralFilter(g_nBilateralFilterValue, );
//imshow("【5】双边滤波", g_dstImage4); //输出一些帮助信息
cout <<endl<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n"
<< "\t按下“q”键时,程序退出~!\n"
<< "\n\n\t\t\t\t by hehehhehhe";
while (char(waitKey()) != 'q'); {} return ;
} /*方框滤波操作的回调函数*/
static void on_BoxFilter(int, void *)
{
//方框滤波操作
boxFilter(g_srcImage, g_dstImage1, -, Size(g_nBoxFilterValue + , g_nBoxFilterValue + ));
//显示窗口
imshow("【<1>方框滤波】", g_dstImage1);
} /*均值滤波操作的回调函数*/
static void on_MeanBlur(int, void *)
{
blur(g_srcImage, g_dstImage2, Size(g_nMeanBlurValue + , g_nMeanBlurValue + ), Point(-, -));
imshow("【<2>均值滤波】", g_dstImage2);
} /*高斯滤波操作的回调函数*/
static void on_GaussianBlur(int, void *)
{
GaussianBlur(g_srcImage, g_dstImage3, Size(g_nGaussianBlurValue + , g_nGaussianBlurValue + ), , );
imshow("【<3>高斯滤波】", g_dstImage3);
} /*中值滤波操作的回调函数*/
static void on_MedianBlur(int, void *)
{
medianBlur(g_srcImage, g_dstImage4, g_nMedianBlurValue * + );
imshow("【<4>中值滤波】", g_dstImage4);
} /*双边滤波操作的回调函数*/
static void on_BilateralFilter(int, void *)
{
bilateralFilter(g_srcImage, g_dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue * , g_nBilateralFilterValue / );
imshow("【<5>双边滤波】", g_dstImage5);
}
调试的时候有问题。。。。。。。。。。。。。。。。。。。。但是源码一模一样。。。。。。。。。。。。。。。。。。待我有时间去解决
下面是改过的代码。。。。。。。。。。读者可自行查找区别。。。。。。。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream> using namespace std;
using namespace cv; Mat g_srcImage, g_dstImage1, g_dstImage2, g_dstImage3, g_dstImage4, g_dstImage5; //即图片的大小
int g_nBoxFilterValue = ; //方框滤波内核值
int g_nMeanBlurValue = ; //均值滤波内核值
int g_nGaussianBlurValue = ; //高斯滤波内核值
int g_nMedianBlurValue = ; //中值滤波内核值
int g_nBilateralFilterValue = ; //双边滤波内核值 static void on_BoxFilter(int, void *); //方框滤波
static void on_MeanBlur(int,void *); //均值滤波
static void on_GaussianBlur(int,void *); //高斯滤波
static void on_MedianBlur(int,void *); //中值滤波
static void on_BilateralFilter(int,void *); //双边滤波 int main()
{
system("color 5e"); //载入原图
g_srcImage = imread("1.jpg",);
if (!g_srcImage.data)
{
printf("Oh,no,读取srcImage错误~! \n");
return false;
} //克隆原图到5个Mat类型中
g_dstImage1 = g_srcImage.clone();
g_dstImage2 = g_srcImage.clone();
g_dstImage3 = g_srcImage.clone();
g_dstImage4 = g_srcImage.clone();
g_dstImage5 = g_srcImage.clone(); //显示原图
namedWindow("【<0>原图窗口】",);
imshow ("【<0>原图窗口】",g_srcImage); /*----------【1】方框滤波--------------*/
//创建窗口
namedWindow("【1 方框滤波】",);
//创建轨迹条
createTrackbar("内核值:","【1 方框滤波】",&g_nBoxFilterValue,,on_BoxFilter);
on_BoxFilter(g_nBoxFilterValue, );
//imshow("【<1>方框滤波】",g_dstImage1); /*----------【2】均值滤波--------------*/
//创建窗口
namedWindow("【2】均值滤波",);
//创建轨迹条
createTrackbar("内核值:", "【2】均值滤波", &g_nMeanBlurValue, , on_MeanBlur);
on_MeanBlur(g_nMeanBlurValue, );
//imshow("【<2>方框滤波】", g_dstImage2); /*----------【3】高斯滤波--------------*/
//创建窗口
namedWindow("【3】高斯滤波", );
//创建轨迹条
createTrackbar("内核值:", "【3】高斯滤波", &g_nGaussianBlurValue, , on_GaussianBlur);
on_GaussianBlur(g_nGaussianBlurValue, );
//imshow("【3】高斯滤波", g_dstImage3); /*----------【4】中值滤波--------------*/
//创建窗口
namedWindow("【4】中值滤波", );
//创建轨迹条
createTrackbar("内核值:", "【4】中值滤波", &g_nMedianBlurValue, , on_MedianBlur);
on_MedianBlur(g_nMedianBlurValue, );
//imshow("【4】中值滤波", g_dstImage4); /*----------【5】双边滤波--------------*/
//创建窗口
namedWindow("【5】双边滤波", );
//创建轨迹条
createTrackbar("内核值:", "【5】双边滤波", &g_nBilateralFilterValue, , on_BilateralFilter);
on_BilateralFilter(g_nBilateralFilterValue, );
//imshow("【5】双边滤波", g_dstImage4); //输出一些帮助信息
cout <<endl<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n"
<< "\t按下“q”键时,程序退出~!\n"
<< "\n\n\t\t\t\t by hehehhehhe";
while (char(waitKey()) != 'q'); {} return ;
} /*方框滤波操作的回调函数*/
static void on_BoxFilter(int, void *)
{
//方框滤波操作
boxFilter(g_srcImage, g_dstImage1, -, Size(g_nBoxFilterValue + , g_nBoxFilterValue + ));
//显示窗口
imshow("【1 方框滤波】", g_dstImage1);
} /*均值滤波操作的回调函数*/
static void on_MeanBlur(int, void *)
{
blur(g_srcImage, g_dstImage2, Size(g_nMeanBlurValue + , g_nMeanBlurValue + ), Point(-, -));
imshow("【2】均值滤波", g_dstImage2);
} /*高斯滤波操作的回调函数*/
static void on_GaussianBlur(int, void *)
{
GaussianBlur(g_srcImage, g_dstImage3, Size(g_nGaussianBlurValue* + , g_nGaussianBlurValue* + ), , );
imshow("【3】高斯滤波", g_dstImage3);
} /*中值滤波操作的回调函数*/
static void on_MedianBlur(int, void *)
{
medianBlur(g_srcImage, g_dstImage4, g_nMedianBlurValue * + );
imshow("【4】中值滤波", g_dstImage4);
} /*双边滤波操作的回调函数*/
static void on_BilateralFilter(int, void *)
{
bilateralFilter(g_srcImage, g_dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue * , g_nBilateralFilterValue / );
imshow("【5】双边滤波", g_dstImage5);
}
如果你俩个代码都试过的话,就会发现粗心是多么的不好,
不过话说回来,这个问题希望opencv团队可以解决,这对一个粗心的人来说是一大幸事
学习 opencv---(8)非线性滤波:中值滤波,双边滤波的更多相关文章
- [学习opencv]高斯、中值、均值、双边滤波
http://www.cnblogs.com/tiandsp/archive/2013/04/20/3031862.html [学习opencv]高斯.中值.均值.双边滤波 四种经典滤波算法,在ope ...
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
原文:http://blog.csdn.net/xiaowei_cqu/article/details/7785365 邻域滤波(卷积) 邻域算子值利用给定像素周围像素的值决定此像素的最终输出.如 ...
- opencv-12-高斯滤波-双边滤波(附C++代码实现)
开始之前 这几天由于自己的原因没有写, 一个是因为自己懒了, 一个是感觉这里遇到点问题不想往下写了, 我们先努力结束这个章节吧, 之前介绍了比较常用而且比较好理解的均值和中值滤波, 但是呢,在例程Sm ...
- OpenCv高斯,中值,均值,双边滤波
#include "cv.h" #include "highgui.h" #include <iostream> using namespace s ...
- opencv3 图片模糊操作-均值滤波 高斯滤波 中值滤波 双边滤波
#include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...
- 基于Opencv的自适应中值滤波函数selfAdaptiveMedianBlur()
7.3.3 自适应滤波器 自适应中值滤波器 对于7.3.2节所讨论的中值滤波器,只要脉冲噪声的空间密度不大,性能还是可以的(根据经验需Pa和Pb小于0.2).本节将证明,自适应中值滤波器可以处理更大概 ...
- opencv —— boxFilter、blur、GaussianBlur、medianBlur、bilateralFilter 线性滤波(方框滤波、均值滤波、高斯滤波)与非线性滤波(中值滤波、双边滤波)
图像滤波,指在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像与处理中不可缺少的操作. 邻域算子,指利用给定像素及其周围的像素值,决定此像素的最终输出值的一种算子.线性邻域滤波器就是一种常 ...
- Atitit 图像处理 平滑 也称 模糊, 归一化块滤波、高斯滤波、中值滤波、双边滤波)
Atitit 图像处理 平滑 也称 模糊, 归一化块滤波.高斯滤波.中值滤波.双边滤波) 是一项简单且使用频率很高的图像处理方法 用途 去噪 去雾 各种线性滤波器对图像进行平滑处理,相关OpenC ...
- opencv学习之路(12)、图像滤波
一.图像滤波简介 二.方框滤波——boxFilter() #include<opencv2/opencv.hpp> using namespace cv; void main(){ Mat ...
随机推荐
- [LeetCode] Valid Sudoku 验证数独
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...
- .NET跨平台之旅:将示例站点从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0
终于将“.NET跨平台之旅”的示例站点 about.cnblogs.com 从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0 ,经历了不少周折,在这篇博文中记录一下. 从 AS ...
- 自动化运维工具ansible部署以及使用
测试环境master 192.168.16.74webserver1 192.168.16.70webserver2 192.168.16.72安装ansiblerpm -Uvh http://ftp ...
- Mysql查询——学习阶段
1.开篇 搞开发的都知道,当数据量很大的时候,我们的代码逻辑的简单性就显得十分重要,否则处理起来就需要花费相当多的时间.另外还有一个地方需要注意的是我们写的sql语句. 一个拥有多年开发的资深开发者可 ...
- jquery-leonaScroll-1.3-自定义竖向自适应滚动条插件
下载链接地址:https://share.weiyun.com/9ac3ca3fb29648bb1aad1b83a76b123c (密码:4y9t)[含mini版] 欢迎使用leonaScroll-1 ...
- 协程--gevent模块(单线程高并发)
先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...
- 使用haproxy的ACL封禁IP
http://www.360doc.com/content/11/1226/13/834950_175075893.shtml 该方法,用户访问得到的是403页面 或者尝试用http-request拒 ...
- 【hihoCoder 1454】【hiho挑战赛25】【坑】Rikka with Tree II
http://hihocoder.com/problemset/problem/1454 调了好长时间,谜之WA... 等我以后学好dp再来看为什么吧,先弃坑(╯‵□′)╯︵┻━┻ #include& ...
- iOS 开发总结(上)
来源:蝴蝶之梦天使 链接:http://www.jianshu.com/p/d333cf6ae4b0 在iOS开发中经常需要使用的或不常用的知识点的总结,几年的收藏和积累(踩过的坑). 一. iPho ...
- 《Just for Fun》读后感
这本书有一个长长的中文名字:<只是为了好玩:Linux之父林纳斯自传>,所以博客标题我就用英文书名了. 读罢此书,不禁想起一位长者的名言:“一个人的成功当然要靠自我奋斗,但也要考虑历史的进 ...