请问关于matlab中imfilter函数的使用

来源:本网整理

inmind,cm,应该是你输出图片之前定义的[inmind,cm]吧。输出的图片形式为gif图片,名字是comet2.gif。loopcount,inf 可以让这个gif文件一直播放。delaytime是播放时间控制www.zgxue.com防采集请勿采集本网。

请教关于matlab中imfilter函数的使用

imfilter是一个滤波函数,我想请教它具体的实现过程是怎么样的,具体如下面的例子,过程是怎么样的,为什么会得到这样的结果?如果想用C语言实现应该怎么做?灰常感谢!

%把每个句柄记录下来,可以选择需要的线的句柄,进行legend h1=plot(t1,U1_A,'-r','linewidth',1.0);hold on;h2=plot(t2,U1_S,'o','markerfacecolor','w','linewidth',0.5);hold on;h3=plot(t1,U6

------解决方案--------------------

RGB=imread('saturn.png');I=rgb2gray(RGB);J=imnoise(I,'gaussian',0,0.005);K=wiener2(J,[5 5]);imshow(J) figure,imshow(K) 这是代码 希望采纳

引用:
Quote: 引用:

书上这么定义符号变量,会报错;符号变量名必须为简单的变量名称;变量名的命名规则: (3)不得与matlab关键字同名;你的问题在于:变量名包含了 百分号 你可以试试: A=sym('A',[2,2])

卷积运算,你应该好好学习信号与系统

那个是三维数组,也就是相当于很多个矩阵放在一起。A(:,:,1)表示第一个矩阵(二维数组)的内容。下一个问题:imread可以把图象的信息转为矩阵读取。其实那个A(:,:,1)是读了很多个图

图像处理函数详解——imfilter

这要根据你的图的大小,字母的像素多少,以及你所要达到的效果来看了!如果仅仅是想把图中的字母经过腐蚀后变细一些,那么用比较小的对称结构就可以,如正方形、圆形、菱形都行。

功能:对任意类型数组或多维图像进行滤波。

用法:B = imfilter(A,H)

   B = imfilter(A,H,option1,option2,...)

   或写作g = imfilter(f, w, filtering_mode, boundary_options, size_options)

其中,f为输入图像,w为滤波掩模,g为滤波后图像。filtering_mode用于指定在滤波过程中是使用“相关”还是“卷积”。boundary_options用于处理边界充零问题,边界的大小由滤波器的大小确定。具体参数选项见下表:

选项描述

filtering_mode‘corr’通过使用相关来完成,该值为默认。

‘conv’通过使用卷积来完成

boundary_options‘X’输入图像的边界通过用值X(无引号)来填充扩展

其默认值为0

‘replicate’图像大小通过复制外边界的值来扩展

‘symmetric’图像大小通过镜像反射其边界来扩展

‘circular’图像大小通过将图像看成是一个二维周期函数的一个周期来扩展

size_options‘full’输出图像的大小与被扩展图像的大小相同

‘same’输出图像的大小与输入图像的大小相同。这可通过将滤波掩模的中心点的偏移限制到原图像中包含的点来实现,该值为默认值。

举例:originalRGB = imread('peppers.png');

imshow(originalRGB)

h = fspecial('motion', 50, 45);%创建一个滤波器

filteredRGB = imfilter(originalRGB, h);

figure, imshow(filteredRGB)

很高兴再次见到你,你说这些我懂,我想知道的是详细的运算过程

就是用模板对中心像素周围的矩阵做一个卷积

------解决方案--------------------

RGB=imread('saturn.png');I=rgb2gray(RGB);J=imnoise(I,'gaussian',0,0.005);K=wiener2(J,[5 5]);imshow(J) figure,imshow(K) 这是代码 希望采纳

 在进行图像目标识别与跟踪时,摄像机所采集的图像,在成像、数字化以及传输过程中,难免会受到各种各样噪声的干扰,图像的质量往往会出现不尽人意的退化,影响了图像的视觉效果。通常这些噪声干扰使得图像退化,表现为图像模糊,特征淹没,这会对图像分析产生不利,使所获得的图像质量较低。对这样的图像直接进行目标的识别与跟踪是比较困难的。抑制使图像退化的各种干扰信号、增强图像中的有用信号,以及将观测到的不同图像在同一约束条件下进行校正处理就显得非常重要。本文主要对图像预处理过程中的滤波方法进行总结,阐述滤波原理,在VC下基于OpenCV实现各种算法,并给出各种滤波的效果。

1、高斯滤波

      高斯滤波是一种线性平滑滤波,适用于滤除高斯白噪声,已广泛应用于图像处理的预处理阶段。按照本人的理解,对图像进行高斯滤波就是对图像中的每个点的像素值计算,计算的准则是,由该点本身灰度值以及其邻域内的其他像素灰度值加权平均所得,而加权平均的权系数由二维离散高斯函数采样并归一化后所得。具体的高斯函数及其离散化参考《高斯图像滤波原理及其编程离散化实现方法》一文。以下给出图像高斯滤波的实现代码。

void GuassFilter(CvMat *pGrayMat, CvMat* pFilterMat, int nWidth, int nHeight, double dSigma)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//dSigma:高斯滤波参数,方差

int nWidowSize = (int)(1+2*ceil(3*dSigma));  //定义滤波窗口的大小

int nCenter = (nWidowSize)/2;                //定义滤波窗口中心的索引

//生成二维的高斯滤波系数

double* pdKernal = new double[nWidowSize*nWidowSize]; //定义一维高斯核数组

double  dSum = 0.0;                                  //求和,进行归一化

/////////////二维高斯函数公式//////////////////////     

//                         x*x+y*y        ///////

//                   -1*--------------///////

//          1               2*Sigma*Sigma///////

//   ---------------- e///////

//   2*pi*Sigma*Sigma///////

///////////////////////////////////////////////////

for(int i=0; i<nWidowSize; i++)

{

for(int j=0; j<nWidowSize; j++)

{

int nDis_x = i-nCenter;

int nDis_y = j-nCenter;

pdKernal[i+j*nWidowSize]=exp(-(1/2)*(nDis_x*nDis_x+nDis_y*nDis_y)

/(dSigma*dSigma))/(2*3.1415926*dSigma*dSigma);

dSum += pdKernal[i+j*nWidowSize];

}

}

//进行归一化

for(i=0; i<nWidowSize; i++)

{

for(int j=0; j<nWidowSize; j++)

{

pdKernal[i+j*nWidowSize] /= dSum;

}

}

for(i=0; i<nHeight; i++)

{

for(int j=0; j<nWidth; j++)

{

double dFilter=0.0;

double dSum = 0.0;

for(int x=(-nCenter); x<=nCenter; x++)//行

{

for(int y=(-nCenter); y<=nCenter; y++)//列

{

if( (j+x)>=0 && (j+x)<nWidth && (i+y)>=0 && (i+y)<nHeight)//判断边缘

{

double ImageData = cvmGet(pGrayMat ,i+y, j+x);

dFilter += ImageData * pdKernal[(y+nCenter)*nWidowSize+(x+nCenter)];

dSum += pdKernal[(y+nCenter)*nWidowSize+(x+nCenter)];

}

}

}

cvmSet(pFilterMat, i, j, dFilter/dSum);

}

}

delete[]pdKernal;

}

2、均值滤波

       均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度值g(x,y),即g(x,y)=1/m ∑f(x,y), m为该模板中包含当前像素在内的像素总个数。这样的方法可以平滑图像,速度快,算法简单。但是无法去掉噪声,这能微弱的减弱它。其实现代码如下。

void MeanFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, int nWindows)

{

////////////////////////参数说明/////////////////////////////////// c_a_3();

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//nWindows:滤波窗口大小

if((nWindows%2) == 0)

{

MessageBox("此函数必须设置邻域为奇数矩阵");

return;

}

int nNumData = nWindows/2;

if((nWindows>nHeight) && (nWindows>nWidth))

{

MessageBox("滤波窗口超出许可范围,请检查!");

return;

}

for(int i=nNumData; i<(nHeight-nNumData); i++)

{

for(int j=nNumData; j<(nWidth-nNumData); j++)

{

double dData = 0.0;

int nNum = 0;

for(int m=-nNumData; m<=nNumData; m++)

{

for(int n=-nNumData; n<=nNumData; n++)

{

if((m!=0) && (n!=0))

{

dData += cvmGet(pGrayMat ,i+m, j+n);

nNum++;

}

}

}

dData /= nNum;

cvmSet(pFilterMat, i, j, dData);

}

}

}

3、中值滤波

      中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。其实现过程为:

      1)通过从图像中的某个采样窗口取出奇数个数据进行排序

      2)用排序后的中值作为当前像素点的灰度值

      在图像处理中,中值滤波常用来保护边缘信息,是经典的平滑噪声的方法,该方法法对消除椒盐噪音非常有效,在光学测量条纹图象的相位分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大。其实现代码如下:

Void MedianFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, int nWindows)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//nWindows:滤波窗口大小

if((nWindows%2) == 0)

{

MessageBox("此函数必须设置邻域为奇数矩阵");

return;

}

int nNumData = nWindows/2;

unsigned char* nData = new unsigned char[nWindows*nWindows-1]; //保存邻域中的数据

if((nWindows>nHeight) && (nWindows>nWidth))

{

MessageBox("滤波窗口超出许可范围,请检查!");

return;

}

for(int i=nNumData; i<(nHeight-nNumData); i++)

{

for(int j=nNumData; j<(nWidth-nNumData); j++)

{

int nIndex = 0;

for(int m=-nNumData; m<=nNumData; m++)

{

for(int n=-nNumData; n<=nNumData; n++)

{

if((m!=0) && (n!=0))

nData[nIndex++] = (unsigned char)cvmGet(pGrayMat, i+m, j+n);

}

}

InsertSort(nData, nIndex);      //排序

unsigned char nMedium = 0;

if(nIndex%2==0)   

nMedium = (unsigned char)((nData[(nIndex-1)/2] + nData[(nIndex+1)/2])/2);

else

nMedium = nData[nIndex/2];

cvmSet(pFilterMat, i, j, nMedium);

}

}

delete[]nData;

}

      以上代码中用到了排序函数InsertSort(unsigned char a[], int count),关于具体的代码实现以及其他排序算法,请参考博文《数组排序方法及C实现的总结》。

4、双边滤波(Bilateral filter)

         双边滤波是一种可以保边去噪的滤波器。之所以可以达到这样的效果,是因为该滤波器是由两个函数构成,一个函数是由几何空间距离决定滤波器系数,另外一个由像素差决定滤波器系数。 

      在前面几种讲述的滤波方法中,像素点的灰度值均是由该点邻域内其他点的灰度值决定的,比如高斯滤波和均值滤波都可看作是加权平均,中值滤波取的是邻域灰度中值。双边滤波则不但考虑邻域范围内点的灰度值,同样考虑这些点距离中心点的几何距离,这样可以得到滤波后的点的灰度值表达公式为:

 

      其中k为归一化系数,其表达式为:

       h和x分别为滤波后和滤波前对应点的灰度值;

      c表示中心点与其邻域内点的空间相似度;

      s表示中心点与其邻域内点的灰度相似度。

      在实现过程中,c和s函数均可用高斯函数实现,即其定义如下:

      可根据以上原理实现双边滤波如下。

Void BilateralFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, double dSigma1, double dSigma2, int nWindows)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//dSigma1、dSigma2:分别为几何与灰度相关高斯函数的方差

double* dDistance = new double[nWindows*nWindows]; //计算距离中间点的几何距离

double* dGrayDiff = new double[nWindows*nWindows]; //定义中心点到当前点的灰度差

for(int i=0; i<nWindows*nWindows; i++)

{

int nNumX = i/nWindows;

int nNumY = i%nWindows;

dDistance[i] = ((nWindows-1)/2-nNumX)*((nWindows-1)/2-nNumX)+((nWindows-1)/2-nNumY)*((nWindows-1)/2-nNumY);

dDistance[i] = exp(-0.5*dDistance[i]/dSigma1/dSigma1);   //C参数

}

//以下求解灰度值的差

for(i=0; i<nHeight; i++)

{

for(int j=0; j<nWidth; j++)

{

double dGray = cvmGet(pGrayMat, i, j);    //当前点的灰度值

double dData = 0.0;

double dTotal = 0.0;                      //用于进行归一化

for(int m=0; m<nWindows*nWindows; m++)

{

int nNumX = m/nWindows;               //行索引

int nNumY = m%nWindows;               //列索引 c_a_3();

int nX = i-(nWindows-1)/2+nNumX;

int nY = j-(nWindows-1)/2+nNumY;

if( (nY>=0) && (nY<nWidth) && (nX>=0) && (nX<nHeight))

{

double dGray1 = cvmGet(pGrayMat, nX, nY);

dGrayDiff[m] = fabs(dGray-dGray1);

dGrayDiff[m] = exp(-0.5*dGrayDiff[m]*dGrayDiff[m]/dSigma2/dSigma2); //S参数

if(m!=4)

{

dData += dGray1 * dGrayDiff[m] * dDistance[m]; //C和S参数综合

dTotal += dGrayDiff[m]*dDistance[m];    //加权系数求和,进行归一化

}

}

}

dData /=dTotal;

cvmSet(pFilterMat, i, j, dData);

}

}

delete[]dDistance;

delete[]dGrayDiff;

}

5、结果对比

     以下对几种滤波方法的结果进行展示对比。

     1)待处理的彩色图片

      2)灰度化后的图像(灰度化实现详见《图像灰度化方法总结及其VC实现》)

      3)高斯滤波(Sigma=0.4)

      4)均值滤波(滤波窗口=3)

      5)中值滤波结果(滤波窗口=3)

      6)双边滤波结果(滤波窗口=3,距离Sigma=10, 灰度Sigma=300)

      根据以上几幅图,可以看出高斯滤波和均值滤波模糊了边界,而中值滤波和双边滤波则能够较好的保存图像的边界信息。

      另外,作者最近正在思考每种方法中所对应参数的设置策略,能否有根据图像某种特性而变化的自适应的参数,目前所有的参数都是根据经验进行设置的,因为整个过程并没有反馈信息。因此,后续还需要研究各种不同参数的设置方法,以最大限度的增大信噪比,同时还能够为目标识别提供良好的边缘信息。

------解决方案--------------------

RGB=imread('saturn.png');I=rgb2gray(RGB);J=imnoise(I,'gaussian',0,0.005);K=wiener2(J,[5 5]);imshow(J) figure,imshow(K) 这是代码 希望采纳

加油!书中自有颜如玉!

------解决方案--------------------

RGB=imread('saturn.png');I=rgb2gray(RGB);J=imnoise(I,'gaussian',0,0.005);K=wiener2(J,[5 5]);imshow(J) figure,imshow(K) 这是代码 希望采纳

引用:
Quote: 引用:

书上这么定义符号变量,会报错;符号变量名必须为简单的变量名称;变量名的命名规则: (3)不得与matlab关键字同名;你的问题在于:变量名包含了 百分号 你可以试试: A=sym('A',[2,2])

 在进行图像目标识别与跟踪时,摄像机所采集的图像,在成像、数字化以及传输过程中,难免会受到各种各样噪声的干扰,图像的质量往往会出现不尽人意的退化,影响了图像的视觉效果。通常这些噪声干扰使得图像退化,表现为图像模糊,特征淹没,这会对图像分析产生不利,使所获得的图像质量较低。对这样的图像直接进行目标的识别与跟踪是比较困难的。抑制使图像退化的各种干扰信号、增强图像中的有用信号,以及将观测到的不同图像在同一约束条件下进行校正处理就显得非常重要。本文主要对图像预处理过程中的滤波方法进行总结,阐述滤波原理,在VC下基于OpenCV实现各种算法,并给出各种滤波的效果。

1、高斯滤波

      高斯滤波是一种线性平滑滤波,适用于滤除高斯白噪声,已广泛应用于图像处理的预处理阶段。按照本人的理解,对图像进行高斯滤波就是对图像中的每个点的像素值计算,计算的准则是,由该点本身灰度值以及其邻域内的其他像素灰度值加权平均所得,而加权平均的权系数由二维离散高斯函数采样并归一化后所得。具体的高斯函数及其离散化参考《高斯图像滤波原理及其编程离散化实现方法》一文。以下给出图像高斯滤波的实现代码。

void GuassFilter(CvMat *pGrayMat, CvMat* pFilterMat, int nWidth, int nHeight, double dSigma)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//dSigma:高斯滤波参数,方差

int nWidowSize = (int)(1+2*ceil(3*dSigma));  //定义滤波窗口的大小

int nCenter = (nWidowSize)/2;                //定义滤波窗口中心的索引

//生成二维的高斯滤波系数

double* pdKernal = new double[nWidowSize*nWidowSize]; //定义一维高斯核数组

double  dSum = 0.0;                                  //求和,进行归一化

/////////////二维高斯函数公式//////////////////////     

//                         x*x+y*y        ///////

//                   -1*--------------///////

//          1               2*Sigma*Sigma///////

//   ---------------- e///////

//   2*pi*Sigma*Sigma///////

///////////////////////////////////////////////////

for(int i=0; i<nWidowSize; i++)

{

for(int j=0; j<nWidowSize; j++)

{

int nDis_x = i-nCenter;

int nDis_y = j-nCenter;

pdKernal[i+j*nWidowSize]=exp(-(1/2)*(nDis_x*nDis_x+nDis_y*nDis_y)

/(dSigma*dSigma))/(2*3.1415926*dSigma*dSigma);

dSum += pdKernal[i+j*nWidowSize];

}

}

//进行归一化

for(i=0; i<nWidowSize; i++)

{

for(int j=0; j<nWidowSize; j++)

{

pdKernal[i+j*nWidowSize] /= dSum;

}

}

for(i=0; i<nHeight; i++)

{

for(int j=0; j<nWidth; j++)

{

double dFilter=0.0;

double dSum = 0.0;

for(int x=(-nCenter); x<=nCenter; x++)//行

{

for(int y=(-nCenter); y<=nCenter; y++)//列

{

if( (j+x)>=0 && (j+x)<nWidth && (i+y)>=0 && (i+y)<nHeight)//判断边缘

{

double ImageData = cvmGet(pGrayMat ,i+y, j+x);

dFilter += ImageData * pdKernal[(y+nCenter)*nWidowSize+(x+nCenter)];

dSum += pdKernal[(y+nCenter)*nWidowSize+(x+nCenter)];

}

}

}

cvmSet(pFilterMat, i, j, dFilter/dSum);

}

}

delete[]pdKernal;

}

2、均值滤波

       均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度值g(x,y),即g(x,y)=1/m ∑f(x,y), m为该模板中包含当前像素在内的像素总个数。这样的方法可以平滑图像,速度快,算法简单。但是无法去掉噪声,这能微弱的减弱它。其实现代码如下。 c_a_3();

void MeanFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, int nWindows)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//nWindows:滤波窗口大小

if((nWindows%2) == 0)

{

MessageBox("此函数必须设置邻域为奇数矩阵");

return;

}

int nNumData = nWindows/2;

if((nWindows>nHeight) && (nWindows>nWidth))

{

MessageBox("滤波窗口超出许可范围,请检查!");

return;

}

for(int i=nNumData; i<(nHeight-nNumData); i++)

{

for(int j=nNumData; j<(nWidth-nNumData); j++)

{

double dData = 0.0;

int nNum = 0;

for(int m=-nNumData; m<=nNumData; m++)

{

for(int n=-nNumData; n<=nNumData; n++)

{

if((m!=0) && (n!=0))

{

dData += cvmGet(pGrayMat ,i+m, j+n);

nNum++;

}

}

}

dData /= nNum;

cvmSet(pFilterMat, i, j, dData);

}

}

}

3、中值滤波

      中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。其实现过程为:

      1)通过从图像中的某个采样窗口取出奇数个数据进行排序

      2)用排序后的中值作为当前像素点的灰度值

      在图像处理中,中值滤波常用来保护边缘信息,是经典的平滑噪声的方法,该方法法对消除椒盐噪音非常有效,在光学测量条纹图象的相位分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大。其实现代码如下:

Void MedianFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, int nWindows)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//nWindows:滤波窗口大小

if((nWindows%2) == 0)

{

MessageBox("此函数必须设置邻域为奇数矩阵");

return;

}

int nNumData = nWindows/2;

unsigned char* nData = new unsigned char[nWindows*nWindows-1]; //保存邻域中的数据

if((nWindows>nHeight) && (nWindows>nWidth))

{

MessageBox("滤波窗口超出许可范围,请检查!");

return;

}

for(int i=nNumData; i<(nHeight-nNumData); i++)

{

for(int j=nNumData; j<(nWidth-nNumData); j++)

{

int nIndex = 0;

for(int m=-nNumData; m<=nNumData; m++)

{

for(int n=-nNumData; n<=nNumData; n++)

{

if((m!=0) && (n!=0))

nData[nIndex++] = (unsigned char)cvmGet(pGrayMat, i+m, j+n);

}

}

InsertSort(nData, nIndex);      //排序

unsigned char nMedium = 0;

if(nIndex%2==0)   

nMedium = (unsigned char)((nData[(nIndex-1)/2] + nData[(nIndex+1)/2])/2);

else

nMedium = nData[nIndex/2];

cvmSet(pFilterMat, i, j, nMedium);

}

}

delete[]nData;

}

      以上代码中用到了排序函数InsertSort(unsigned char a[], int count),关于具体的代码实现以及其他排序算法,请参考博文《数组排序方法及C实现的总结》。

4、双边滤波(Bilateral filter)

         双边滤波是一种可以保边去噪的滤波器。之所以可以达到这样的效果,是因为该滤波器是由两个函数构成,一个函数是由几何空间距离决定滤波器系数,另外一个由像素差决定滤波器系数。 

      在前面几种讲述的滤波方法中,像素点的灰度值均是由该点邻域内其他点的灰度值决定的,比如高斯滤波和均值滤波都可看作是加权平均,中值滤波取的是邻域灰度中值。双边滤波则不但考虑邻域范围内点的灰度值,同样考虑这些点距离中心点的几何距离,这样可以得到滤波后的点的灰度值表达公式为:

 

      其中k为归一化系数,其表达式为:

       h和x分别为滤波后和滤波前对应点的灰度值;

      c表示中心点与其邻域内点的空间相似度;

      s表示中心点与其邻域内点的灰度相似度。

      在实现过程中,c和s函数均可用高斯函数实现,即其定义如下:

      可根据以上原理实现双边滤波如下。

Void BilateralFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, double dSigma1, double dSigma2, int nWindows)

{

////////////////////////参数说明///////////////////////////////////

//pGrayMat:待处理图像数组

//pFilterMat:保存高斯滤波结果

//nWidth:图像宽度

//nHeight:图像高度

//dSigma1、dSigma2:分别为几何与灰度相关高斯函数的方差

double* dDistance = new double[nWindows*nWindows]; //计算距离中间点的几何距离

double* dGrayDiff = new double[nWindows*nWindows]; //定义中心点到当前点的灰度差

for(int i=0; i<nWindows*nWindows; i++)

{

int nNumX = i/nWindows;

int nNumY = i%nWindows;

dDistance[i] = ((nWindows-1)/2-nNumX)*((nWindows-1)/2-nNumX)+((nWindows-1)/2-nNumY)*((nWindows-1)/2-nNumY);

dDistance[i] = exp(-0.5*dDistance[i]/dSigma1/dSigma1);   //C参数

}

//以下求解灰度值的差

for(i=0; i<nHeight; i++)

{

for(int j=0; j<nWidth; j++)

{

double dGray = cvmGet(pGrayMat, i, j);    //当前点的灰度值

double dData = 0.0;

double dTotal = 0.0;                      //用于进行归一化

for(int m=0; m<nWindows*nWindows; m++)

{ c_a_3();

int nNumX = m/nWindows;               //行索引

int nNumY = m%nWindows;               //列索引

int nX = i-(nWindows-1)/2+nNumX;

int nY = j-(nWindows-1)/2+nNumY;

if( (nY>=0) && (nY<nWidth) && (nX>=0) && (nX<nHeight))

{

double dGray1 = cvmGet(pGrayMat, nX, nY);

dGrayDiff[m] = fabs(dGray-dGray1);

dGrayDiff[m] = exp(-0.5*dGrayDiff[m]*dGrayDiff[m]/dSigma2/dSigma2); //S参数

if(m!=4)

{

dData += dGray1 * dGrayDiff[m] * dDistance[m]; //C和S参数综合

dTotal += dGrayDiff[m]*dDistance[m];    //加权系数求和,进行归一化

}

}

}

dData /=dTotal;

cvmSet(pFilterMat, i, j, dData);

}

}

delete[]dDistance;

delete[]dGrayDiff;

}

5、结果对比

     以下对几种滤波方法的结果进行展示对比。

     1)待处理的彩色图片

      2)灰度化后的图像(灰度化实现详见《图像灰度化方法总结及其VC实现》)

      3)高斯滤波(Sigma=0.4)

      4)均值滤波(滤波窗口=3)

      5)中值滤波结果(滤波窗口=3)

      6)双边滤波结果(滤波窗口=3,距离Sigma=10, 灰度Sigma=300)

      根据以上几幅图,可以看出高斯滤波和均值滤波模糊了边界,而中值滤波和双边滤波则能够较好的保存图像的边界信息。

      另外,作者最近正在思考每种方法中所对应参数的设置策略,能否有根据图像某种特性而变化的自适应的参数,目前所有的参数都是根据经验进行设置的,因为整个过程并没有反馈信息。因此,后续还需要研究各种不同参数的设置方法,以最大限度的增大信噪比,同时还能够为目标识别提供良好的边缘信息。

其实你真的很漂亮

------解决方案--------------------

RGB=imread('saturn.png');I=rgb2gray(RGB);J=imnoise(I,'gaussian',0,0.005);K=wiener2(J,[5 5]);imshow(J) figure,imshow(K) 这是代码 希望采纳

引用:
美女,我们做朋友吧

哈哈哈哈哈,我不是美女啊,长得很一般

matlab只支持离散数字,但是不支持连续的,可以直接表示为矩阵,参考如下:x=[0.5 3.5 4.5;10.5 6.5 7.5];low=x(1,:);up=x(2,:);内容来自www.zgxue.com请勿采集。

免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
Copyright © 2017 www.zgxue.com All Rights Reserved