本科课程【数字图像处理】实验6 - 取阈值的邻域平均算法

x33g5p2x  于2022-05-27 转载在 其他  
字(2.6k)|赞(0)|评价(0)|浏览(651)

大家好,我是【1+1=王】, 热爱java的计算机(人工智能)渣硕研究生在读。
如果你也对java、人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!!
Good better best, never let it rest, until good is better, and better best.

近期会把自己本科阶段的一些课程设计、实验报告等分享出来,供大家参考,希望对大家有帮助。

博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html

一、 实验目的

1、 掌握图像邻域的概念。
2、 掌握邻域平均法的原理、滤波过程。
3、 掌握在给定阈值时,邻域平均法的滤波过程(又叫做超限邻域平均法)。
4、 掌握灰度空间域运算的基本算法。

二、 实验内容

1. 实验任务

利用邻域平均法,对图像进行滤波给定阈值时利用邻域平均法,对图像进行滤波。完成取阈值的邻域平均法算法,并不断测试阈值,给出测试结果及阈值数值。

2. 程序设计

1) 原理
邻域平均法的思想是用像素及其指定邻域内像素的平均值或加权平均值作为该像素的新值,以便去除突变的像素点,从而滤除一定的噪声。为了解决邻域平均法造成的图像模糊问题,采用阈值法(又叫做超限邻域平均法,如果某个像素的灰度值大于其邻域像素的平均值,且达到一定水平,则判断该像素为噪声,继而用邻域像素的均值取代这一像素值;否则,认为该像素不是噪声点,不予取代),给定阈值设输入图像为

,那么 ,

其中mn表示以 为中心的含M个像素的邻域的平均灰度值,其中s表示以(I,j)为中心的邻域,那么


则取平均值否则就取原始值,这样T为事先给定的一个阈值,需要不断的测试。其中,当结构体元素越大,则平滑效果越好,而T越大,图像就越清晰。

2) 流程
(1) 打开VC++,打开工作空间,在ResourceView中菜单中添加邻域平均法按钮;
(2) 取结构元素为9x9,阈值为一个可变变量,然后对原始图像lpDIBBits进行循环,为了防止越界,循环的ij元素都从4开始,然后循环过程中,使用临时变量sum存储9x9的结构元素的和,将sum除以81,得到一个灰度平均值;
(3) 将平均值进行防止越界的判断,在然后使用条件

,满足则将对应点的值赋值为阈值T否则还是保持原有灰度值不变,最后完成对图像的取阈值的邻域平均处理。

3) 数据输出

分析:当阈值不同时,总是小的噪声先被过滤掉,而大的噪声点需要的阈值减小;当阈值和结构元素都调高时,噪声过滤效果很好,但是同时也损失了原图的部分细节。

三、 实验环境

  1. 操作系统:WINDOWS 10
  2. 开发工具:Visual Studio
  3. 实验设备:PC

源代码

void CAView::OnLinyupingjun() 
{ 
BackForUndo(GetDocument()->GetHDIB());
	// 获取文档
	CADoc* pDoc = GetDocument();
	
	// 指向DIB的指针
	LPSTR lpDIB;
	
	// 锁定DIB
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
	
	// 源图像的宽度和高度
	LONG	lWidth;
	LONG	lHeight;
		
	lWidth=::DIBWidth(lpDIB);/* 获取图像的"宽度"(4的倍数)*/
	lHeight=::DIBHeight(lpDIB)/*获取图像的高度*/;
	
	// 指向DIB象素的指针
	LPBYTE lpDIBBits;
	// 找到源DIB图像象素起始位置
	lpDIBBits = (LPBYTE)::FindDIBBits(lpDIB);

	// 创建新DIB
	HDIB hNewDIB = NULL;
	
	// 更改光标形状
	BeginWaitCursor();

	LPBYTE lpSrc;//每个像素点的指针
	LONG lLineBytes;
	lLineBytes=WIDTHBYTES(lWidth *8);
    long i,j;	// 循环需要的变量
	lpSrc=new unsigned char[lWidth*lHeight];//开辟新的临时空间
	memset(lpSrc,(unsigned char)255,sizeof(unsigned char)*lWidth*lHeight);//初始化
	double sum=0;//灰度值
	double count=81;//要除以的因子
	double Threshold=50;//阈值
  /现在开始在下面编写图像平滑的算法---------------------用非加权算法/
	for( i=4;i<lWidth-4;i++){

		for(int j=4;j<lHeight-4;j++){
			sum=0;//每次将sum清空
			for(int m=-4;m<=4;m++){
//9x9的结构元素
				for(int n=-4;n<=4;n++){
					sum+=1*(*(lpDIBBits+i*lWidth+j+m*lWidth+n));
				}
			}
          //这里得到平均值
			double temp=sum/count; 
			if(temp>=255){temp=255;}//保证在计算的过程中不越界
			else if(temp<=0){temp=0;}
			else{
			temp=temp;
			}
//这里开始引入阈值进行判断
			if( fabs( temp-(*(lpDIBBits+i*lWidth+j)) )>Threshold )			{

			*(lpSrc+i*lWidth+j)=(unsigned char)temp;
			}
			else
			{
			*(lpSrc+i*lWidth+j)=*(lpDIBBits+i*lWidth+j);
			}
		}
	}
 
	memcpy(lpDIBBits, lpSrc, sizeof(unsigned char)*lWidth*lHeight);
	
		// 设置脏标记
		pDoc->SetModifiedFlag(TRUE);
	
		// 更新视图
		pDoc->UpdateAllViews(NULL);
	
	// 解除锁定
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

	// 恢复光标
	EndWaitCursor();	

}

博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html

相关文章