图像处理 平均值 高斯_均值滤波、中值滤波、高斯滤波 图像处理函数的适用图像 - CSDN
  • 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识...

           本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识。希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生。
           【数字图像处理】一.MFC详解显示BMP格式图片
           【数字图像处理】二.MFC单文档分割窗口显示图片
           【数字图像处理】三.MFC实现图像灰度、采样和量化功能详解
           【数字图像处理】四.MFC对话框绘制灰度直方图
           【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
           【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
            
    免费资源下载地址:
            http://download.csdn.net/detail/eastmount/8785591

     

    一. 图像增强简介

            图像增强是对图像进行处理,使其比原始图像更适合于特定的应用,它需要与实际应用相结合。对于图像的某些特征如边缘、轮廓、对比度等,图像增强是进行强调或锐化,以便于显示、观察或进一步分析与处理。图像增强的方法是因应用不同而不同的,研究内容包括:(参考课件和左飞的《数字图像处理》)

     

    二. 图像平滑

            图像平滑是一种区域增强的算法,平滑算法有邻域平均法、中指滤波、边界保持类滤波等。在图像产生、传输和复制过程中,常常会因为多方面原因而被噪声干扰或出现数据丢失,降低了图像的质量(某一像素,如果它与周围像素点相比有明显的不同,则该点被噪声所感染)。这就需要对图像进行一定的增强处理以减小这些缺陷带来的影响。

           1.简单平滑-邻域平均法
            图像简单平滑是指通过邻域简单平均对图像进行平滑处理的方法,用这种方法在一定程度上消除原始图像中的噪声、降低原始图像对比度的作用。它利用卷积运算对图像邻域的像素灰度进行平均,从而达到减小图像中噪声影响、降低图像对比度的目的。
            但邻域平均值主要缺点是在降低噪声的同时使图像变得模糊,特别在边缘和细节处,而且邻域越大,在去噪能力增强的同时模糊程度越严重。

            2.高斯平滑
           
    为了克服简单局部平均法的弊端(图像模糊),目前已提出许多保持边缘、细节的局部平滑算法。它们的出发点都集中在如何选择邻域的大小、形状和方向、参数加平均及邻域各店的权重系数等。
            图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的权重。
            在图像简单平滑中,算法利用卷积模板逐一处理图像中每个像素,这一过程可以形象地比作对原始图像的像素一一进行过滤整理,在图像处理中把邻域像素逐一处理的算法过程称为滤波器。平滑线性滤波器的工作原理是利用模板对邻域内像素灰度进行加权平均,也称为均值滤波器。
            高斯平滑与简单平滑不同,它在对邻域内像素进行平均时,给予不同位置的像素不同的权值,下图的所示的3*3和5*5领域的高斯模板。

            模板越靠近邻域中心位置,其权值越高。在图像细节进行模糊时,可以更多的保留图像总体的灰度分布特征。下图是常用的四个模板和matlab代码实现:

            代码如下:

    I1 = imread('blood1.tif');
    I=imnoise(I1,‘salt & pepper’,0.04);                %对图像加椒盐噪声
    imshow(I);
    h1= [0.1 0.1 0.1; 0.1 0.2 0.1; 0.1 0.1 0.1];        %定义4种模板
    h2=1/16.*[1 2 1;2 4 2;1 2 1];
    h3=1/8.*[1 1 1;1 0 1;1 1 1];
    h4=1/2.*[0 1/4 0;1/4 1 1/4;0 1/4 0];
    I2=filter2(h1,I);                                   %用4种模板进行滤波处理
    I3=filter2(h2,I);
    I4=filter2(h3,I);
    I5=filter2(h4,I);
    figure,imshow(I2,[])                                %显示处理结果
    figure,imshow(I3,[])
    figure,imshow(I4,[])
    figure,imshow(I5,[])

            运行效果如下图所示:

            3.中值滤波
            在使用邻域平均法去噪的同时也使得边界变得模糊。而中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。
            选一个含有奇数点的窗口W,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。

            例如选择滤波的窗口如下图,是一个一维的窗口,待处理像素的灰度取这个模板中灰度的中值,滤波过程如下:

            常用的窗口还有方形、十字形、圆形和环形。不同形状的窗口产生不同的滤波效果,方形和圆形窗口适合外轮廓线较长的物体图像,而十字形窗口对有尖顶角状的图像效果好。

            中值滤波对于消除孤立点和线段的干扰十分有用,尤其是对于二进噪声,但对消除高斯噪声的影响效果不佳。对于一些细节较多的复杂图像,可以多次使用不同的中值滤波。matlab实现参考:http://blog.csdn.net/timidsmile/article/details/6904381

            4.边界保持类滤波
            K近邻均值滤波器(KNNF)是指在m*m的窗口中,属于同一集合类的像素,它们的灰度值将高度相关。被处理的像素(对应于窗口中心的像素)可以用窗口内与中心像素灰度最接近的k个近邻像素的平均灰度来替代。步骤如下:
            (1).作一个m*m的作用模板
            (2).在其中选择K个与待处理像素的灰度差为最小的像素
            (3).用这K个像素的灰度均值替换掉原来的值

            在K近旁均值滤波器(KNNMF)中,不选K个邻近像素的平均灰度来替代,而选K个邻近像素的中值灰度来替代,上图中2,3,3中选择3即可。
            下面介绍具体MFC VC++6.0代码实现过程。

     

    三. 图像平滑代码实现

            第一步:在资源视图的Menu中添加子菜单“图像增强”,然后添加“图像平滑”四个选项如下图所示:

            第二步:打开类向导,在ImageProcessingView类中添加相应的四个实现函数:

            第三步:就是具体的平滑实现函数。
            1.普通平滑 模板一
            该算法采用的模板如下:

            代码如下:

    /**************************************************
      第九章--图像增强    
      图像平滑 普通平滑 模板
     
    float H1[3][3]={{1.0/10,1.0/10,1.0/10}, //模板一:系数1/10
    			   {1.0/10,2.0/10,1.0/10},
    			   {1.0/10,1.0/10,1.0/10}};
    		
    float H2[3][3]={{1.0/16,2.0/16,1.0/16}, //模板二:系数1/16
    			   {2.0/16,4.0/16,2.0/16},
    			   {1.0/16,2.0/16,1.0/16}};
    
    float H3[3][3]={{1.0/8,1.0/8,1.0/8},    //模板三:系数1/8,此种情况为把点转为空心矩形
    			   {1.0/8,0.0/8,1.0/8},
    			   {1.0/8,1.0/8,1.0/8}};
    
    float H4[3][3]={{0.0,1.0/8,0.0},        //模板四:系数乘数据后的矩阵
    			   {1.0/8,1.0/2,1.0/8},
    			   {0.0,1.0/8,0.0}};
    
    /**************************************************/
    
    
    void CImageProcessingView::OnTxzqPtph1() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:普通平滑 模板一",MB_OK,0);
    
    	/******************************************************************/
    	/* 图想平滑的算法:                                               
    	/*   1.定义常用的四个模板,它们的维数均为3,矩阵的个数均为9个数据   
    	/*   2.它的思想是把一个点分散到这周围的9个点上,这样使图像更模糊   
    	/*   3.通过卷积计算围绕该点的矩阵像素和,计算其平均值(除9)赋值给点 
    	/*   4.模块不同,处理后的图像也各不相同                           
    	/******************************************************************/
    
    	/*第一步:先定义数据模板*/
    	int HWS=3;                                //模板维数:此四个模板均为3维的
    	float H1[3][3]={{1.0/10,1.0/10,1.0/10},   //模板一:系数1/10
    					{1.0/10,2.0/10,1.0/10},
    					{1.0/10,1.0/10,1.0/10}};
    	
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[m_nImage];    
    	float red,green,blue;
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置
    
    	//图像增强:平滑 它要获取源图像周围9个点的矩阵乘以模板9个点的矩阵,故一维图像转二维
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		//原图:一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    
    		//赋值为黑色,相当于清零
    		red=green=blue=0;
    
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//模板一 进行模板平均,把该点像素分散到四周
    					TR=j*m_nWidth*3+k*3;	
    					red+=H1[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H1[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H1[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		ImageSize[i]=(unsigned char)(red);
    		ImageSize[i+1]=(unsigned char)(green);
    		ImageSize[i+2]=(unsigned char)(blue);
    	}
    		
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;
    	Invalidate();
    }

            运行效果如图所示,图像平滑模糊了,但效果不是很好。

            其中实现的具体原理如下:
            首先将图像像素矩阵转换为(X,Y)的二维矩阵进行操作,同时获取(X,Y)坐标为中心的3*3矩阵,再通过它与3*3模板进行像素平均操作,就是两个3*3矩阵互乘。需要注意的是矩阵一个格子是RGB三字节(24位BMP),同时获取该中心点位置时,通过两层循环for(k=n-1;k<=n+1;k++)实现获取矩阵中九个点的像素。最后对该点(X,Y)的RGB进行赋值操作即可。


           2.普通平滑 模板二
            该算法采用的模板如下:

            代码如下:

    void CImageProcessingView::OnTxzqPtph2() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:普通平滑 模板二",MB_OK,0);
    
    	/*第一步:先定义数据模板*/
    	int HWS=3;
    	float H2[3][3]={{1.0/8,1.0/8,1.0/8},    //模板三:系数1/8 此种情况为把点转为空心矩形
    					{1.0/8,0.0/8,1.0/8},
    					{1.0/8,1.0/8,1.0/8}};
    	
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	
    	//重点:图像的每行像素都必须是4的倍数:1*1的图像为 r g b 00H   
    	int num;            //记录每行多余的图像素数个数  
    	int sfSize;         //补齐后的图像大小  
        if(m_nWidth*3%4!=0) {  
            num=(4-m_nWidth*3%4);  
            sfSize=(m_nWidth*3+num)*m_nHeight; //每行多number个  
        }  
        else {  
            num=0;  
            sfSize=m_nWidth*m_nHeight*3;  
        }  
      
        /*更改文件头信息 定义临时文件头结构变量*/  
        BITMAPFILEHEADER bfhsf;  
        BITMAPINFOHEADER bihsf;         
        bfhsf=bfh;  
        bihsf=bih;  
        bfhsf.bfSize=sfSize+54;  
        fwrite(&bfhsf,sizeof(BITMAPFILEHEADER),1,fpw);  
        fwrite(&bihsf,sizeof(BITMAPINFOHEADER),1,fpw);  
        fread(m_pImage,m_nImage,1,fpo);  
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[sfSize];    
    	float red,green,blue;
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置  
        int countWidth=0;      //记录每行的像素个数,满行时变回0  
    	int place=0;           //建立临时坐标 记录起始坐标(0,0)平移过来的位置 
    
    	//图像增强 平滑
    	for(int i=0; i<m_nImage; )
    	{
    		//原图一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    
    		//赋值为黑色,相当于清零
    		red=green=blue=0;
    
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//模板二 进行模板平均,把该点像素分散到四周
    					TR=j*m_nWidth*3+k*3;	
    					red+=H2[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H2[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H2[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		//通过变量place赋值变换后的图像 i始终指向原图3的倍数 为了补0而添加place变量
    		ImageSize[place]=(unsigned char)(red);
    		i++; place++;
    		ImageSize[place]=(unsigned char)(green);
    		i++; place++;
    		ImageSize[place]=(unsigned char)(blue);
    		i++; place++;
    		countWidth=countWidth+3;
    		
    		if(countWidth==m_nWidth*3)    
            {    
    			if(num==0)  
                {  
                    countWidth=0;    
                    place=Y*m_nWidth*3;
                }  
                else //num为补0  
                {  
                    for(int n=0;n<num;n++)  
                    {    
                        ImageSize[place]=0;  
    					place++;  
                    }  
                    countWidth=0;   
                    place=Y*(m_nWidth*3+num); //重点 添加Num  
                }  
    		} 
    	}
    		
    	fwrite(ImageSize,sfSize,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture=2;
    	level=400;
    	Invalidate();
    }

            你可能注意到了,在图像处理过程中,如果每行的字节数不是4的倍数,可能会出现斜线之类的处理BUG,所以需要手动补0筹齐4的倍数,代码中补0后运行效果如下图所示,我也一直没找到原因,可能是思想和深度还没有达到,以后有机会在解决吧!同时后面的算法都不准备再进行补0处理,主要讲述算法的思想!

             3.高斯平滑
             采用的模板如下:

            代码如下图所示:

    //高斯平滑
    void CImageProcessingView::OnTxzqGsph() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:高斯平滑",MB_OK,0);
    
    	/*第一步:先定义数据模板*/
    	int HWS=3;                                //模板维数为3维
    	float H[3][3]={{1.0/16,2.0/16,1.0/16},    //高斯模板 系数1/16
    				   {2.0/16,4.0/16,2.0/16},
    				   {1.0/16,2.0/16,1.0/16}};
    	
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[m_nImage];    
    	float red,green,blue;
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置
    
    	//图像增强:平滑 
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		//原图:一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    
    		//赋值为黑色,相当于清零
    		red=green=blue=0;
    
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//模板二 进行模板平均,把该点像素分散到四周
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		ImageSize[i]=(unsigned char)(red);
    		ImageSize[i+1]=(unsigned char)(green);
    		ImageSize[i+2]=(unsigned char)(blue);
    	}
    		
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;
    	Invalidate();
    }

            运行效果如下图所示:

            4.中值滤波
            中值滤波我的理解是:它不但可以去除孤点噪声,而且可以保持图像的边缘特性,不会产生显著的模糊;它的方法是把局部区域的像素按灰度等级进行排序,再取该邻域中灰度的中值作为当前像素的灰度值。其步骤如下:
            (1).将滤波模板(含若干个点的滑动窗口)在图像中漫游,并将模板中心与图像中的某个像素位置重合;
            (2).读取模板中各对应像素的灰度值;
            (3).将这些灰度值从小到大排序;
            (4).取这一列数据的中间数据,将其赋值给对应模板中心位置的像素。

            我采用的是3*3的模本,取矩阵中间位置像素替代原像素。代码如下:

    //中值滤波
    void CImageProcessingView::OnTxzqZzlb() 
    {
    	if(numPicture==0) {
    		AfxMessageBox("载入图片后才能图像增强(平滑)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(平滑)!选取的模板为:中值滤波",MB_OK,0);
    
    	//打开临时的图片
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
        fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
        unsigned char *ImageSize;        
        ImageSize = new unsigned char[m_nImage];    
    	int X,Y;               //一维坐标转换为二维坐标
    	int TR,TG,TB;          //记录红绿蓝坐标位置
    
    	//选取它为中心的周围9个点像素(注意一个点为RGB)
    	int H[9]={0,0,0,0,0,0,0,0,0};    
    	int HWS=3;             //维数为三维
    
    	//图像增强:平滑 它要获取源图像周围9个点的矩阵乘以模板9个点的矩阵,故一维图像转二维
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		//原图:一维矩阵转换为二维矩阵
    		X=(i/3)%m_nWidth;    //图像在X列
    		Y=(i/3)/m_nWidth;    //图像在Y行
    		
    		//第一行 第一列 最后一行 最后一列 直接复制
    		if(X==0 || Y==0 || X==m_nWidth*3 || Y==m_nHeight) 
    		{
    			if(i+2>m_nImage) break;
    			ImageSize[i] = m_pImage[i];
    			ImageSize[i+1] = m_pImage[i+1];
    			ImageSize[i+2] = m_pImage[i+2];
    			continue;
    		}
    
    		//对图像进行像素求和并取平均值 HWS维数
    		int num=0;
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )      //防止越界
    				{			
    					//获取当前位置Red像素 k一次增加RGB三个像素 R=G=B
    					TR = j*m_nWidth*3+k*3;	
    					H[num] = m_pImage[TR];
    					num++;
    				}
    			}
    		}
    		//排序获取中间值
    		int temp=0;
    		for(int x=0;x<9;x++)
    		{
    			for(int y=x;y<9;y++)
    			{
    				if(H[x]>=H[y])
    				{
    					temp=H[x];
    					H[x]=H[y];
    					H[y]=temp;
    				}
    			}
    		}
    		//CString str;
    		//str.Format("矩阵:%d %d %d, %d %d %d, %d %d %d",H[0],H[1],H[2],H[3],H[4],H[5],H[6],H[7],H[8]);
    		//AfxMessageBox(str);
    
    		//对新图像赋值 灰度图像RGB相同
    		ImageSize[i]=H[4];
    		ImageSize[i+1]=H[4];
    		ImageSize[i+2]=H[4];
    	}
    		
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;
    	Invalidate();
    }

            运行效果如下图所示:

            PS:这部分总算讲述完成,算法都是根据自己的理解用底层代码实现的,而不是向其它的通过调用GDI+库实现。可能存在因为理解不够或其它的错误,欢迎提出修改~
            推荐资料:
            图像平滑处理——OpenCV         数字图像处理学习笔记——图像平滑锐化 
            中值滤波    

     

    四. 图像锐化

           有时还需要加强图像中景物的边缘和轮廓,边缘和轮廓通常位于图像中灰度突出的地方,因而可以直观的想到用灰度的差分对边缘和轮廓进行提取,通常可以通过梯度算子进行提取。图像锐化的目的是提高图像的对比度,从而使图像更清晰,通过提高邻域内像素的灰度差来提高图像的对比度。
           下面介绍图像锐化的几种算子及效果。
            1.拉普拉斯算子(Laplacian)
            拉普拉斯算子是图像邻域内像素灰度差分计算的基础,通过二阶微分推导出的一种图像邻域增强算法。它的基本思想是当邻域的中心像素灰度低于它所在邻域内的其他像素的平均灰度时,此中心像素的灰度应该被进一步降低;当高于时进一步提高中心像素的灰度,从而实现图像锐化处理。
            在算法实现过程中,通过对邻域中心像素的四方向或八方向求梯度,并将梯度和相加来判断中心像素灰度与邻域内其他像素灰度的关系,并用梯度运算的结果对像素灰度进行调整。
            一个连续的二元函数f(x,y),其拉普拉斯运算定义为:

            对于数字图像,拉普拉斯算子可以简化为:

            也可以表示为卷积的形式:

            其中K=1,I=1时H(r,s)取下式,四方向模板:

            通过模板可以发现,当邻域内像素灰度相同时,模板的卷积运算结果为0;当中心像素灰度高于邻域内其他像素的平均灰度时,模板的卷积运算结果为正数;当中心像素的灰度低于邻域内其他像素的平均灰度时,模板的卷积为负数。对卷积运算的结果用适当的衰弱因子处理并加在原中心像素上,就可以实现图像的锐化处理。
            其中实现过程步骤如下:
            添加子菜单和类向导添加实现函数

            代码如下:

    /*****************************************/
    /* 图像锐化:我在menu中创建5个子的menu    */
    /* 防止出现平滑错误,一次只调用一个下拉单 */
    /* ID_RH_Laplacian Laplacian拉普拉斯算子 */
    /* ID_RH_Sobel Sobel算子                 */
    /* ID_RH_Prewitt Prewitt算子             */
    /* ID_RH_Isotropic Isotropic算子         */
    /* ID_RH_GTMB 高通模板H2                 */
    /*****************************************/
    
    void CImageProcessingView::OnRHLaplacian() 
    {
    	if(numPicture==0) 
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用拉普拉斯(Laplacian)算子!");
    
    	//模板维数:此四个模板均为3维的
    	int HWS=3;  
    	int H[3][3]={{0,-1,0},    //模板为拉普拉斯算子(中心为4的Laplacian)
    				{-1,4,-1},
    				{0,-1,0}};
    
    	//读写文件
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	//new和delete有效的进行动态内存的分配和释放
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int red,green,blue;
    	int X,Y;       //一维坐标转换为二维坐标
    	int TR,TG,TB;  //记录红绿蓝坐标位置
    	
    	//图像增强 锐化
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		red=green=blue=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		if(red>=0 && red<256) ImageSize[i]=red;
    		else if(red<0) ImageSize[i]=0;      //ImageSize[i]=-red;
    		else ImageSize[i]=0;
    		
    		if(green>=0 && green<256) ImageSize[i+1]=green;
    		else if(green<0) ImageSize[i+1]=0;  //ImageSize[i+1]=-green;
    		else ImageSize[i+1]=0;
    		
    		if(blue>=0 && blue<256) ImageSize[i+2]=blue;
    		else if(blue<0) ImageSize[i+2]=0;   //ImageSize[i+2]=-blue;
    		else ImageSize[i+2]=0;
    	}
    	
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示:


            2.高通滤波
            常用的高通模板如下所示,其中H2有的书又称为拉普拉斯八方向的锐化模板。

            选取H2模板,代码如下所示:

    //高通模板
    void CImageProcessingView::OnRhGtmb() 
    {
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用高通模板!");
    
    	int HWS=3;                                
    	int H[3][3]={{-1,-1,-1},    
    				{-1,8,-1},
    				{-1,-1,-1}};
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int red,green,blue;
    	int X,Y;       
    	int TR,TG,TB; 
    	
    	//图像增强 锐化
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		red=green=blue=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		
    		//对新图像赋值
    		if(red>=0 && red<256) ImageSize[i]=red;
    		else if(red<0) ImageSize[i]=0;      //ImageSize[i]=-red;
    		else ImageSize[i]=0;
    		
    		if(green>=0 && green<256) ImageSize[i+1]=green;
    		else if(green<0) ImageSize[i+1]=0;  //ImageSize[i+1]=-green;
    		else ImageSize[i+1]=0;
    		
    		if(blue>=0 && blue<256) ImageSize[i+2]=blue;
    		else if(blue<0) ImageSize[i+2]=0;   //ImageSize[i+2]=-blue;
    		else ImageSize[i+2]=0;
    	}
    	
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();	
    }

            运行效果如下图所示,该效果相对较好:

     


           3.Sobel算子

            代码如下所示,需要注意X和Y两个方向的模板处理:

    //Sobel算子采用PPT上的d(x)d(y)模板
    void CImageProcessingView::OnRHSobel() 
    {
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用Sobel算子!");
    
    	int HWS=3;                                
    	//模板为Sobel算子
    	int HX[3][3]={{1,0,-1},{2,0,-2},{1,0,-1}};
    	int HY[3][3]={{-1,-2,-1},{0,0,0},{1,2,1}};
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);	
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int redX,greenX,blueX;
    	int redY,greenY,blueY;
    	int X,Y;       
    	int TR,TG,TB;  
    	
    	//图像增强 锐化
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		redX=greenX=blueX=0;
    		redY=greenY=blueY=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					redX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					redY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					greenX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					greenY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blueX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    					blueY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		//s=(d(x)*d(x)+d(y)*d(y))开根号
    		int R,G,B;
    		R=(int)(sqrt(redX*redX*1.0+redY*redY*1.0));
    		G=(int)(sqrt(greenX*greenX*1.0+greenY*greenY*1.0));
    		B=(int)(sqrt(blueX*blueX*1.0+blueY*blueY*1.0));
    
    		if(redX<0 && redY<0) ImageSize[i]=0;
    		else if(R>255) ImageSize[i]=255;
    		else ImageSize[i]=R;
    		
    		if(greenX<0 && greenY<0) ImageSize[i+1]=0;
    		else if(G>255) ImageSize[i+1]=255;
    		else ImageSize[i+1]=G;
    
    		if(blueX<0 && blueY<0) ImageSize[i+2]=0;
    		else if(B>255) ImageSize[i+2]=255;
    		else ImageSize[i+2]=B;
    	}
    	
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示:

            如果采用Sobel边缘细化,建议二值化(0和255阈值化)处理后再锐化,彩色图建议先灰度处理再进行其他处理。


          4.Isotropic算子
     

            代码实现如下:

    //Isotropic算子采用PPT上的d(x)模板 d(y)
    void CImageProcessingView::OnRHIsotropic() 
    {
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    
    	AfxMessageBox("图像增强(锐化):采用Isotropic算子!");
    
    	int HWS=3;                               
    	//模板为Isotropic算子
    	float HX[3][3]={{1,0,-1},
    					{sqrt(2.0),0,-sqrt(2.0)}, 
    					{1,0,-1} };
    	float HY[3][3]={{-1,-sqrt(2.0),-1},
    					{0,0,0}, 
    					{1,sqrt(2.0),1} };
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	float redX,greenX,blueX;
    	float redY,greenY,blueY;
    	int X,Y;      
    	int TR,TG,TB;  
    	
    	//图像增强
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		redX=greenX=blueX=0;
    		redY=greenY=blueY=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					redX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					redY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					greenX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					greenY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blueX+=HX[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    					blueY+=HY[(j-Y+HWS/2)][(k-X+HWS/2)]*(float)(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值 s=(d(x)*d(x)+d(y)*d(y))开根号
    		int R,G,B;
    		R=(int)(sqrt(redX*redX*1.0+redY*redY*1.0));
    		G=(int)(sqrt(greenX*greenX*1.0+greenY*greenY*1.0));
    		B=(int)(sqrt(blueX*blueX*1.0+blueY*blueY*1.0));
    
    		if(redX<0 && redY<0) ImageSize[i]=0;
    		else if(R>255) ImageSize[i]=255;
    		else ImageSize[i]=R;
    		
    		if(greenX<0 && greenY<0) ImageSize[i+1]=0;
    		else if(G>255) ImageSize[i+1]=255;
    		else ImageSize[i+1]=G;
    
    		if(blueX<0 && blueY<0) ImageSize[i+2]=0;
    		else if(B>255) ImageSize[i+2]=255;
    		else ImageSize[i+2]=B;
    	}
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示,效果与上面的Sobel类似:


           5.Prewitt算子

            代码如下图所示:

    //Prewitt算子采用PPT上的d(x)模板,不是d(y)
    void CImageProcessingView::OnRHPrewitt() 
    {
    	
    	if(numPicture==0)
    	{
    		AfxMessageBox("载入图片后才能图像增强(锐化)!",MB_OK,0);
    		return;
    	}
    	AfxMessageBox("图像增强(锐化):采用Prewitt算子!");
    
    	int HWS=3;                               
    	int H[3][3]={{1,0,-1},    //模板为Prewitt算子
    				{1,0,-1},
    				{1,0,-1}};
    
    	FILE *fpo = fopen(BmpName,"rb");
    	FILE *fpw = fopen(BmpNameLin,"wb+");
    	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
    	fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
    	fread(m_pImage,m_nImage,1,fpo);
    
    	unsigned char *ImageSize;      
    	ImageSize=new unsigned char[m_nImage];  
    	int red,green,blue;
    	int X,Y;      
    	int TR,TG,TB; 
    	
    	//图像增强:平滑
    	for(int i=0; i<m_nImage ; i=i+3 )
    	{
    		X=(i/3)%m_nWidth;    //X列
    		Y=(i/3)/m_nWidth;    //Y行
    		red=green=blue=0;
    		
    		//对图像进行像素求和并取平均值 HWS维数
    		for(int j=Y-HWS/2 ; j<Y+HWS/2+1 ; j++ )                      //第j行
    		{
    			for(int k=X-HWS/2 ; k<X+HWS/2+1 ; k++ )                  //第k列
    			{
    				if( j>=0 && k>=0 && k<m_nWidth && j<m_nHeight )
    				{			
    					
    					TR=j*m_nWidth*3+k*3;	
    					red+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TR]);
    					TG=j*m_nWidth*3+k*3+1;
    					green+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TG]);
    					TB=j*m_nWidth*3+k*3+2;
    					blue+=H[(j-Y+HWS/2)][(k-X+HWS/2)]*(m_pImage[TB]);
    				}
    			}
    		}
    		//对新图像赋值
    		if(red>=0 && red<256) ImageSize[i]=red;
    		else if(red<0) ImageSize[i]=0;      //ImageSize[i]=-red;
    		else ImageSize[i]=0;
    		
    		if(green>=0 && green<256) ImageSize[i+1]=green;
    		else if(green<0) ImageSize[i+1]=0;  //ImageSize[i+1]=-green;
    		else ImageSize[i+1]=0;
    		
    		if(blue>=0 && blue<256) ImageSize[i+2]=blue;
    		else if(blue<0) ImageSize[i+2]=0;   //ImageSize[i+2]=-blue;
    		else ImageSize[i+2]=0;	
    	}
    	fwrite(ImageSize,m_nImage,1,fpw);  
    	fclose(fpo);
    	fclose(fpw);
    	numPicture = 2;
    	level=400;	
    	Invalidate();
    }

            运行效果如下图所示,只选取了X分量:

            最后还是希望文章对你有所帮助,如果文章有不足或错误之处,请海涵。自己给自己点个赞,挺不容易的,但还会继续写完~同时后面的图像处理准备研究些感兴趣的东西,而不是这样的长篇大论了,例如怎样实现验证码提取、如何实现图像恢复、DICOM图像等知识吧!

          (By:Eastmount 2015-06-08 下午6点   http://blog.csdn.net/eastmount/

    展开全文
  • 图像处理高斯模糊

    2018-08-20 14:16:47
    通常,图像处理软件会提供"模糊"(blur)滤镜,使图片产生模糊的效果。   "模糊"的算法有很多种,其中有一种叫做"高斯模糊"(Gaussian Blur)。它将正态分布(又名"高斯...

    转自:1.高斯模糊的算法:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html

     

    通常,图像处理软件会提供"模糊"(blur)滤镜,使图片产生模糊的效果。

     

    "模糊"的算法有很多种,其中有一种叫做"高斯模糊"(Gaussian Blur)。它将正态分布(又名"高斯分布")用于图像处理。

    本文介绍"高斯模糊"的算法,你会看到这是一个非常简单易懂的算法。本质上,它是一种数据平滑技术(data smoothing),适用于多个场合,图像处理恰好提供了一个直观的应用实例。

    一、高斯模糊的原理

    所谓"模糊",可以理解成每一个像素都取周边像素的平均值。

    上图中,2是中间点,周边点都是1。

    "中间点"取"周围点"的平均值,就会变成1。在数值上,这是一种"平滑化"。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。

    显然,计算平均值时,取值范围越大,"模糊效果"越强烈。

    上面分别是原图、模糊半径3像素、模糊半径10像素的效果。模糊半径越大,图像就越模糊。从数值角度看,就是数值越平滑。

    接下来的问题就是,既然每个点都要取周边像素的平均值,那么应该如何分配权重呢?

    如果使用简单平均,显然不是很合理,因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。

    二、正态分布的权重

    正态分布显然是一种可取的权重分配模式。

    在图形上,正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。

    计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。

    三、高斯函数

    上面的正态分布是一维的,图像都是二维的,所以我们需要二维的正态分布。

    正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:

    其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于0。

    根据一维高斯函数,可以推导得到二维高斯函数:

    有了这个函数 ,就可以计算每个点的权重了。

    四、权重矩阵

    假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:

    更远的点以此类推。

    为了计算权重矩阵,需要设定σ的值。假定σ=1.5,则模糊半径为1的权重矩阵如下:

    这9个点的权重总和等于0.4787147,如果只计算这9个点的加权平均,还必须让它们的权重之和等于1,因此上面9个值还要分别除以0.4787147,得到最终的权重矩阵。

    五、计算高斯模糊

    有了权重矩阵,就可以计算高斯模糊的值了。

    假设现有9个像素点,灰度值(0-255)如下:

    每个点乘以自己的权重值:

    得到

    将这9个值加起来,就是中心点的高斯模糊的值。

    对所有点重复这个过程,就得到了高斯模糊后的图像。如果原图是彩色图片,可以对RGB三个通道分别做高斯模糊。

    六、边界点的处理

    如果一个点处于边界,周边没有足够的点,怎么办?

    一个变通方法,就是把已有的点拷贝到另一面的对应位置,模拟出完整的矩阵。

    参考文献

    1.高斯模糊的算法:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html

    2.How to program a Gaussian Blur without using 3rd party libraries

     

    展开全文
  • 高斯模糊原理2.1 矩阵范围的像素平均值2.2 正态分布的权重3. 计算高斯模糊 1. 高斯模糊介绍 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的...


    图像处理系列笔记: https://blog.csdn.net/qq_33208851/article/details/95335809


    1. 高斯模糊介绍

    高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波器。

    2. 高斯模糊原理

    2.1 矩阵范围的像素平均值

    “模糊”,就是将图像中每个像素值进行重置的过程,这个过程采用将每一个像素都设置成周边像素的平均值。
    在这里插入图片描述
    上图中,2是中间点,周边点都是1。假设周边的点对中间点的影响都是相同的,即构造的卷积算子如下:
    在这里插入图片描述
    然后计算求和:
    在这里插入图片描述
    将图中‘2’置为:
    在这里插入图片描述
    “中间点"取"周围点"的平均值,变成10/9。在数值上,这是一种"平滑化”。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。
    显然,计算平均值时,取值范围越大,"模糊效果"越强烈。如下三幅图,分别表示原图,3X3和5X5的模糊效果图。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    接下来的问题就是,既然每个点都要取周边像素的平均值,那么应该如何分配权重呢?
    如果使用简单平均,显然不是很合理,因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。

    2.2 正态分布的权重

    正态分布显然是一种可取的权重分配模式。
    在图形上,正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。
    计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。
    高斯函数
    在这里插入图片描述
    正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:
    在这里插入图片描述
    其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于0。
    在这里插入图片描述
    上面的正态分布是一维的,图像都是二维的,所以我们需要二维的正态分布。
    在这里插入图片描述
    在这里插入图片描述
    有了这个函数 ,就可以计算每个点的权重了。
    权重矩阵:
    假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:
    在这里插入图片描述
    更远的点以此类推。
    为了计算权重矩阵,需要设定σ的值。假定σ=1.5(σ值越大图像越平滑/模糊),则模糊半径为1的权重矩阵如下:
    在这里插入图片描述
    这9个点的权重总和等于0.4787147,如果只计算这9个点的加权平均,还必须让它们的权重之和等于1,因此上面9个值还要分别除以0.4787147,得到最终的权重矩阵
    在这里插入图片描述

    3. 计算高斯模糊

    有了权重矩阵,就可以计算高斯模糊的值了。假设现有9个像素点,灰度值(0-255)如下:
    在这里插入图片描述
    每个点乘以自己的权重值:
    在这里插入图片描述
    将这9个值加起来,就是中心点的高斯模糊的值。
    对所有点重复这个过程,就得到了高斯模糊后的图像。如果原图是彩色图片,可以对RGB三个通道分别做高斯模糊。

    参考文章:https://baike.baidu.com/item/高斯模糊/10885810?fr=aladdin
    https://www.jianshu.com/p/302a895c12dd
    图像处理系列笔记: https://blog.csdn.net/qq_33208851/article/details/95335809

    展开全文
  • 高斯滤波属于线性平滑滤波的一种,可以消除高斯噪声,广泛应用于图像处理的减噪过程。大家常说高斯滤波是最有用的滤波操作,虽然它用起来效率往往不是最高的。 首先,我们先要了解高斯滤波的原理,以及高斯滤波消除...

    高斯滤波

    高斯滤波属于线性平滑滤波的一种,可以消除高斯噪声,广泛应用于图像处理的减噪过程。大家常说高斯滤波是最有用的滤波操作,虽然它用起来效率往往不是最高的。

    首先,我们先要了解高斯滤波的原理,以及高斯滤波消除的高斯噪声是什么?

    噪声,是图像中表现极为突兀的像素点或者像素块,会给图像带来干扰,让图像变得不清楚,或者说影响观察图像的细节。
    而高斯噪声,就是噪声像素的概率密度函数服从高斯分布(正态分布)
    高斯噪声就是它的概率密度函数服从高斯分布(即正态分布)的一类噪声。如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。高斯白噪声的二阶矩不相关,一阶矩为常数,是指先后信号在时间上的相关性。

    高斯函数:
    在这里插入图片描述
    注:σ的大小决定了高斯函数的宽度。在这里插入图片描述
    通俗地讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身核邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩膜)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

    高斯核:
      理论上,高斯分布在所有定义域上都有非负值,这就需要一个无限大的卷积核。实际上,仅需要取均值周围3倍标准差内的值,以外部份直接去掉即可。 如下图为一个标准差为1.0的整数值高斯核。
      在这里插入图片描述
    很明显的看出来,上图高斯核矩阵满足二维高斯分布。

    理论上,高斯分布在所有定义域上都有非负值,这就需要一个无限大的卷积核。实际上,仅需要取均值周围3倍标准差内的值,以外部份直接去掉即可。
    高斯滤波的重要两步就是先找到高斯模板然后再进行卷积,模板(mask在查阅中有的地方也称作掩膜或者是高斯核)。所以这个时候需要知道它怎么来?又怎么用?
    举个栗子:
    假定中心点的坐标是(0,0),那么取距离它最近的8个点坐标,为了计算,需要设定σ的值。假定σ=1.5,则模糊半径为1的高斯模板就算如下
    在这里插入图片描述
    这个时候我们我们还要确保这九个点加起来为1(这个是高斯模板的特性),这9个点的权重总和等于0.4787147,因此上面9个值还要分别除以0.4787147,得到最终的高斯模板。
    在这里插入图片描述
    高斯滤波计算
    有了高斯模板,那么高斯滤波的计算便顺风顺水了。
    举个栗子:
    假设现有9个像素点,灰度值(0-255)的高斯滤波计算如下:
    在这里插入图片描述
    将这9个值加起来,就是中心点的高斯滤波的值。
    对所有点重复这个过程,就得到了高斯模糊后的图像。

    高斯滤波步骤
    综上可以总结一下步骤:

    (1)移动相关核的中心元素,使它位于输入图像待处理像素的正上方
    (2)将输入图像的像素值作为权重,乘以相关核
    (3)将上面各步得到的结果相加做为输出
    简单来说就是根据高斯分布得到高斯模板然后做卷积相加的一个过程

    部分转自:https://www.jianshu.com/p/73e6ccbd8f3f

    展开全文
  • JAVA图像处理——高斯模糊高斯模糊: 高斯模糊简单的说就是让图像的像素点取周围的像素点的平均,达到令图片模糊的效果。 当然,简单的取平均值是不太好的,因为一般与像素点距离近的像素点他们的颜色更接近,...
  • 通常,图像处理软件会提供"模糊"(blur)滤镜,使图片产生模糊的效果。 "模糊"的算法有很多种,其中有一种叫做"高斯模糊"(Gaussian Blur)。它将正态分布(又名"高斯分布")用于图像处理。 本文介绍"高斯模糊...
  • 滤波 1.中值滤波 2.平均值滤波 3.高斯滤波 4双边滤波 1.中值滤波这是一种简单的滤波方法,顾名思义,中值就是在参与计算的点中,通过排序,找到中间值。 比如上面的3x3图象矩阵,绿色的点是原图象上的
  • 高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的,都由其本身和邻域内的其他像素经过加权平均后得到。
  • 滤波器作为图像处理课程的重要内容,大致可分为两类,空域滤波器和频率域滤波器。本文主要介绍常用的四种滤波器:中值滤波器、均值滤波器、高斯滤波器、双边滤波器,并基于opencv做出实现。空域的滤波器一般可以通过...
  • 图像处理算法--高斯模糊 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。 高斯模糊相信...
  • 图像处理--高斯滤波

    2013-12-27 10:01:36
    原文http://blog.csdn.net/l_inyi/article/details/8915116 部分内容整理自: http://blog.csdn.net/jianxiong8814/article/details/1562728 ... htt
  • 图像经过灰度化、二处理之后,可能存在有噪音,或者图像的不平稳性导致图像处理过程中有干扰对图像本质理解的频率信息,我们需要将这些噪音、频率信息等干扰处理掉,需要用到平滑处理。高斯平滑是对图片应用一个...
  • Tips:暂时还在学习matlab图像处理,写此小博客梳理相关知识。才疏学浅,还请读者见谅。 图像处理中的高斯滤波,通常来说是通过两步: 1、建立一个高斯模板T  在建立高斯模板时,通过高斯函数(也称正态分布...
  • 滤波器作为图像处理课程的重要内容,大致可分为两类,空域滤波器和频率域滤波器。本文主要介绍常用的四种滤波器:中值滤波器、均值滤波器、高斯滤波器、双边滤波器,并基于opencv做出实现。空域的滤波器一般可以通过...
  • 1、一维高斯函数: a表示得到曲线的高度,b是指曲线在x轴的中心,c指width(与半峰全宽有关),图形如下: ...计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,
  • 高斯噪声 高斯噪声是指高绿密度函数服从高斯分布的一类噪声。特别的,假设一个噪声,它...应用:一些美颜软件、美颜相机上的磨皮和毛玻璃特效基本上都是用的高斯模糊,并且大部分图像处理软件中都有高斯模糊的操作,...
  • 高斯滤波的含义:高斯滤波就是对整幅图像进行加权平均的过程,每一...高斯滤波的作用:高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。 高斯滤波函数 一维高斯分布 二维高斯分...
  • 在旋转后的卷积核中,将输入图像的像素作为权重相乘 第三步各结果的和做为该输入像素对应的输出像素 (2)相关: 移动相关核的中心元素,使它位于输入图像处理像素的正上方 将输入图像...
1 2 3 4 5 ... 20
收藏数 17,468
精华内容 6,987
关键字:

图像处理 平均值 高斯