【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

C++ MFC打开图片并进行简单算法处理 一、VS2010 新建一个MFC工程,添加两个picture控件和一个按钮控件。 二、添加变量 1、为两个picture控件添加control变量,类型为CStatic,变量名分别为m_picture1和m_picture2. 2、添加保存图片路径和名称变量,CString类型,变量名strFilePath,strFileName 三、添加按钮消息映射函数 双击“打开图片”按钮进入消息映射函数... 阅读详情

       本文主要讲述基于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/)

【数字图像处理】第5章 图像的噪声抑制 5 图像的噪声抑制 目录(一)噪声与图像噪声的概念(二)图像噪声的抑制方法1)均值滤波器2) 中值滤波器3)边界保持类平滑滤波器① 灰度最小方差平滑滤波器② K近邻(KNN)平滑滤波器③ 对称近邻平滑滤波器 (一)噪声与图像噪声的概念 噪声是不可预测的随机信号。 根据产生来源分类: 外部噪声、内部噪声 根据统计特征是否随时间变化分类: 平稳噪声、非平稳噪声 根据对信号的影响分类: 加性噪声、... 阅读详情

相关推荐

用 VC2010 MFC实现图片二值化、灰度处理

1.新建一个MFC工程,添加两个picture控件和一个按钮控件。 2.添加变量 (1)为两个picture控件添加control变量,类型为CStatic,变量名分别为m_picture1和m_picture2. (2)添加保存图片路径和名称变量,CString类型,变量名strFilePath,strFileName 添加完成如图显示如下: 3.添加函数 (1)双击打开图片按钮,进入消息映射函数,添加以下代码: CFileDialog fileDlg(TRUE, _T(“png”), NULL, 0,

aa1694362883的博客 891

【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解...

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识。希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生。 【数字图像处理】一.MFC详解显示BMP格式图...

weixin_34192816的博客 2905

[Python图像处理] 十七.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算子

图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。通常使用灰度差分法对图像的边缘、轮廓进行处理,将其凸显。本文分别采用Laplacian算子、Robert算子、Prewitt算子和Sobel算子进行图像锐化边缘处理实验。本文主要讲解灰度线性变换,基础性知识希望对您有所帮助。 1.Roberts算子 2.Prewitt算子 3.Sobel算子 4.Laplacian算子 5.总结代码

杨秀璋的专栏 4万+

MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识。希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生。        【数字图像处理】一.MFC详解显示BMP格式图片        【数字图像处理】二.MFC单文档分割窗口显...

ywxk1314的博客 2082

(7-2)图像增强:锐化

锐化滤波器(Sharpening filter)是一种常用的图像处理技术,用于增强图像的边缘和细节,以提高图像的清晰度和视觉效果。但是,如果原始图像的像素值范围本身已经是0到255之间,那么进行归一化可能会导致所有的像素值都变为0,从而得到一片黑色的图像。最后,将锐化后的图像像素值归一化到0到255范围内,并显示原始图像和锐化后的图像。实现了理想高通滤波器。基于梯度的锐化是一种图像增强技术,通过突出图像中的边缘和细节来增强图像的清晰度和锐度。该方法基于图像的梯度信息,利用梯度的变化来增强图像的边缘。

码农三叔 4918

MFC Windows 程序设计[322]之噪声特征流显示gribble1(附源码)

MFC是微软公司提供的一个类库(class libraries),用以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。有很多初学MFC的小伙伴们都觉得MFC比较难学,看书吧,看了就忘了,网上的一些教程又是写的含糊不清,故而学习起来很吃力...... 故此,本专栏亲自研究,实践,由易到难,层层深入,将调试过程中所遭所遇进行详细讲解,注意事项进行一一列举,希望能够帮助到各位初学MFC的小伙伴,避免走弯路,费时费力。......

hnjzfwy的博客 279

数字图像处理|图像的平滑和锐化

彩色图像平滑是一种常见的图像处理技术,旨在减少图像中的噪声和细节,使图像更加平滑和连续。均值滤波是一种简单的平滑方法,它将每个像素的值替换为其周围像素值的平均值,这种方法可以有效地减少噪声,但会导致图像失去细节和锐度;高斯滤波是一种基于高斯函数的平滑方法,它将每个像素的值替换为其周围像素值的加权平均值,这种方法可以在减少噪声的同时保留图像的细节和锐度;中值滤波是一种非线性平滑方法,它将每个像素的值替换为其周围像素值的中值,这种方法可以有效地去除噪声,同时保留图像的细节和锐度。

Sea_Yanwu的博客 3690

rar文件MFC 图像处理之图像增强 图像平滑、高斯平滑、中值滤波、拉普拉斯锐化、Sobel锐化(源码)

该资源主要参考我的博客【【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解,博客地址http://blog.csdn.net/eastmount/article/details/46378783 主要讲述基于VC++6.0 MFC图像处理的应用知识,要通过MFC单文档视图实现显示BMP图片增强,包括图像普通平滑、高斯平滑、不同算子(拉普拉斯 Sobel 高通模板 I P)的图像锐化知识。其中代码中含有详细注释。免费资源,希望能结合原文学习,也期望对你有所帮助,尤其是初学者!By:Eastmount BUG修改见原文

传统图像处理算法总结

HOG算法是一个将图片原始信息最终压缩成一个向量的过程,当我们将一张照片通过HOG算法得到此HOG特征描述符后,相当于我们得到了图片的样本数据,就可以拿来用于机器学习中对模型进行训练,然后结合机器学习模型比如SVM来实现路上行人检测等目的。当然HOG虽然存在维度降低,忽略光照等环境因素的影响,但也存在因梯度使得描述子对噪声敏感的问题。所以可以结合SIFT和LBP算法来对图像进行处理。

ling2828ling的博客 6119

VC开发MFC图像处理系统完美版

图像处理系统是一个典型的图像处理软件,它由图像显示、图像转换、图像处理、字符识别、其他和帮助等几部分组成。  图像显示模块 该模块主要包括显示位图、显示JPEG、显示GIF 3个部分。  图像转换模块 该模块主要包括位图转换为JPEG、JPEG转换为位图、位图转换为GIF,GIF转换为位图4个部分。  图像处理模块 该模块主要包括图像旋转、图像锐化处理、图像反色处理、灰度化处理、线性变换5个部分。  字符识别模块 该模块主要包含手写数字识别。  其他 该模块主要包括设置菜单的固定颜色和随机颜色两个部分。  帮助模块 该模块主要包括软件的版本、开发单位等信息。

豆包大模型API调用两种方法

ps: 因为是自用,所以这里图方便采用硬编码密钥的形式;如果有需求/安全风险,建议参考官方教程设置ARK_API_KEY环境变量的方式。坏处是:看别人的教程走了一大圈弯路hh;基础调用的话方法一就可以满足了,也比较方便快捷,容易上手。将 <Model> 替换为 Endpoint ID即可。创建就按照提示填写信息就行,需要实名认证,有免费额度。绿框框里就是Endpoint ID。

kkkkkkkkkasey的博客 1万+

图像算法八 —— 多种边缘检测算法(Sobel算子、Isotropic Sobel算子、Roberts算子、Prewitt算子、Laplacian算子、Canny算子)介绍及比较

图像算法八 —— 多种边缘检测算法(Sobel算子、Isotropic Sobel算子、Roberts算子、Prewitt算子、Laplacian算子、Canny算子)介绍及比较

weixin_43662553的博客 2万+

ifix5.8连接ab plc的点-通过rslinx

以ifix连接ab plc的点为例 1.先在rslinx上把plc的点导出为opc server 2.使用opc power tool 作为opc client 去连接 3.保存到项目的PDB文件夹下面,并且以节点名命名。 也可以不以节点名命名,系统自动会生成一个以节点名命名的这种文件,就显得很乱。 同时,项目的PDB目录下面必须还得拷过来一个de...

中国智造2025 4095

MFC绘制高次B样条曲线

MFC绘制高次B样条曲线 随着B样条的绘制次数越高,曲线连续性越高,光滑性越好,但是逼近程度变差,局部性质变差,工程中一般使用2、3次B样条。 图示为1-8次的B样条曲线,红色依次加深,次数依次升高。 参考《计算几何算法与实现》–孔令德 实现代码: #pragma once #include"P2.h" class High_Level_BSpline { public: High_Level_BSpline(void); ~High_Level_BSpline(void); public: /

ha0ha0xuexi的博客 1076

华大 HC32F460 DMA数据传输实战:从配置到中断处理的完整指南

本文提供了华大半导体HC32F460微控制器DMA(直接内存访问)功能的完整实战指南。详细解析了DMA的配置流程、中断处理机制以及软件与硬件触发方式,并附有实验代码示例。通过合理使用DMA进行数据传输,可以显著解放CPU资源,提升嵌入式系统的实时性与运行效率。

weixin_29194255的博客 244

【2025CVPR】基于脉冲神经网络的能效目标检测模型:Multi-scale Spiking Detector(MSD)深度解析

本文提出了一种创新的多尺度脉冲神经网络目标检测器(MSD),通过生物启发的ONNB模块和MSDF框架实现了高效准确的目标检测。该模型采用端到端直接训练策略,在COCO数据集上达到62.0%mAP的精度,同时仅需7.8M参数和6.43mJ能耗,较传统方法提升2.8%精度并降低82.9%能耗。实验验证了其在小目标检测和事件数据处理的优越性,为边缘计算应用提供了新范式。

hasakie的博客 1102

(十二)图像的Sobel梯度锐化

图像的Sobel梯度锐化

伯努利 2932

别再死磕Excel了!用Vensim PLE免费版,30分钟搞定你的第一个系统动力学模型

本文介绍如何使用Vensim PLE免费版在30分钟内构建第一个系统动力学模型,无需编程或数学基础。通过个人储蓄增长案例,详细讲解因果回路图绘制、存量流量图创建及方程编写,帮助读者掌握动态系统建模与仿真技巧,适用于理财、项目管理等多种场景。

weixin_29045001的博客 320

MFC增强----任务对话框CTaskDialog类

1 /** 2 注意:从Windows Vista系统才开始支持CTaskDialog类,所以在使用时最好调用 CTaskDialog::IsSupported() 方法做判断 3 同时:CTaskDialog类只对Unicode应用程序可用, 同时要添加头文件:include "afxtaskdialog.h"的支持 4 */ 5 void C...

weixin_34266504的博客 212

从Reset到Read:深入解析Rolling Shutter曝光流水线

本文深入解析Rolling Shutter(卷帘曝光)的工作原理,重点探讨Reset和Read信号在图像传感器中的关键作用。通过Reset-Read流水线机制,详细解释了曝光控制、时序调优及运动伪影补偿等核心技术,帮助读者理解卷帘曝光在高速摄影和动态场景中的应用。

weixin_42531925的博客 249

手把手教你学Simulink——基于Simulink的蚁群算法路径规划仿真建模示例

路径规划是机器人导航系统中的核心任务之一,旨在为机器人找到一条安全且高效的路径,使其能够从起点到达目标点,同时避免与障碍物发生碰撞。在开始之前,需要定义工作环境(例如地图),包括起点、终点以及可能存在的障碍物位置。通过本指南,我们介绍了如何基于Simulink结合MATLAB实现蚁群算法的路径规划仿真建模。

MHD0815的博客 214

图像锐化-拉普拉斯算子 Sobel算子

本文主要介绍图像锐化和边缘检测知识,详细讲解了 Sobel 算子和 Laplacian 算子,并通过小珞珞图像进行边缘轮廓提取。图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。

gqk01的博客 5627

让 ABAP 内表真正释放内存:从 CLEAR、FREE 到打破 Table Sharing 的实战技巧

ABAP内表内存管理的关键在于理解其运行时结构:DELETE操作仅逻辑删除行而不会释放内存,CLEAR或FREE才能真正回收内存。常见的误区包括误判空表状态和忽视内表共享机制。实际应用中,大表筛选后应采用VALUE表达式或逐行插入方式重建表体以释放内存。典型案例显示,正确处理内表内存可显著降低SAP Gateway和批处理程序的内存消耗,提升系统稳定性。开发时需结合调试工具观察内存状态,避免因共享机制导致无效回收。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 305

C++MFC打开图片、彩图,以及对图像进行简单算法处理

MFC 一、新建一个MFC工程,添加两个picture控件和一个按钮控件。 二、添加变量 1、为两个picture控件添加control变量,类型为CStatic,变量名分别为m_picture1和m_picture2. 2、添加保存图片路径和名称变量,CString类型,变量名strFilePath,strFileName 三、添加按钮消息映射函数 双击“打开图片”按钮进入消息映射函数,`在这里添加以下代码: 一、为按钮添加打开文件的功能,并默认打开.png格式的文件,并在打开文件右下角添加文件类型选项。

qq_53955363的博客 5664

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: 【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
下一篇: 《淘宝技术这十年》读书笔记 (四). 分布式时代和中间件
Eastmount
Eastmount 优质创作者: python技术领域 优质创作者: python技术领域 领域专家: 数据科学与机器学习技术领域 领域专家: 数据科学与机器学习技术领域
博客等级 码龄15年 25万+粉丝 873原创
评论 45
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eastmount

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值