实 验 三
【实验名称】 直方图及二值化
【实验内容】
设计直方图程序:程序能显示数字图象的直方图,确定直方图上最小、最大、最有代表性的灰度值,可以交互选择阈值并输出二值化图象,进一步自动确定直方图的谷底,并用适当图象检验程序,同时与Phtoshop的显示结果作比较。
灰度直方图(Gray Level Histogram),就是对于图像的每一个灰度值,求出整个图像中具有该灰度值的像素的个数,并用图形表示出来。在本次实验中主要解决的问题:a最大最小灰度值,就是从小到大,以及从大到小,分别找到第一个包含一个以上像素点的灰度值;b最有代表性的灰度值,是把各灰度值包含的像素点的个数做比较,取出最大的那个值,作为图像的第一波峰点;c二值化处理,把各像素点的灰度值和输入的阈值做比较,小于阈值的灰度值置0,大于阈值的灰度值置255。
【算法分析】
打开BMP图片,得到BMP图片的各种信息,包括高度、宽度,颜色为数等,同时也申请了一块内存区,用于存放RGB位值,可以通过相应方法获得该内存的指针,从而用于统计RGB信息,生成直方图,具体算法如下:
for(int j=0;j trace=dc->GetPixel(i,j); app->color[GetRValue(trace)]++; } 二值化的步骤:先取得原图的数据区指针,然后通过对话框输入阈值,然后所有像素依次循环,具体算法如下: for(int j=0;j ref=dc->GetPixel(i,j); r=GetRValue(ref); last=(int)r/num; dc->SetPixel(i,j,RGB(255*last,255*last,255*last)); } 【实验步骤】 1、在实验二打开bmp文件的基础上,添加直方图和二值化的菜单项和相应的响应函数OnHistogram()和OnEz(); 2、设计用于显示直方图的对话框,并创建相应的对话框类CHistogram;在CHistogram类中添加OnPaint()函数,用于绘制显示直方图。 void CHistogram::OnPaint() { CPaintDC dc(this); // device context for painting CClientDC pDC(this); CImageApp *app=(CImageApp*)AfxGetApp(); pDC.Rectangle(0, 0, 330, 330); CPen pen(PS_SOLID,2,RGB(255,0,0)); CPen *redpen = pDC.SelectObject(&pen); // 绘制坐标轴 pDC.MoveTo(10,10); pDC.LineTo(10, 280); pDC.LineTo(320, 280); // X轴刻度值 CString strTemp; strTemp.Format(\"0\"); pDC.TextOut(10, 283, strTemp); strTemp.Format(\"50\"); pDC.TextOut(60, 283, strTemp); strTemp.Format(\"100\"); pDC.TextOut(110, 283, strTemp); strTemp.Format(\"150\"); pDC.TextOut(160, 283, strTemp); strTemp.Format(\"200\"); pDC.TextOut(210, 283, strTemp); strTemp.Format(\"255\"); pDC.TextOut(265, 283, strTemp); // 绘制X轴刻度 for (int i = 0; i < 256; i += 5){ if ((i & 1) == 0){ // 10的倍数 pDC.MoveTo(i + 10, 280); pDC.LineTo(i + 10, 284); }else{ // 5的奇数倍数 pDC.MoveTo(i + 10, 280); pDC.LineTo(i + 10, 282); } } // 绘制X轴箭头 pDC.MoveTo(315,275); pDC.LineTo(320,280); pDC.LineTo(315,285); // 绘制Y轴箭头 pDC.MoveTo(10,10); pDC.LineTo(5,15); pDC.MoveTo(10,10); pDC.LineTo(15,15); m_max=0;m_min=0;m_pr=0; LONG lMaxCount = 0; for (i = 0; i <= 255; i ++){ if (app->color[i] > lMaxCount){ lMaxCount = app->color[i]; m_pr = i; } } // 输出最大计数值 pDC.MoveTo(10, 25); pDC.LineTo(14, 25); strTemp.Format(\"%d\ pDC.TextOut(11, 26, strTemp); //最大灰度值和最小灰度值 for(i=0; i<=255; i++){ if(app->color[i]!=0){ m_min = i; break; } } for(i=255; i>=0; i--){ if(app->color[i]!=0) { m_max = i; break; } } CPen pen2(PS_SOLID,1,RGB(0,0,255)); CPen *bluepen = pDC.SelectObject(&pen2); for (i = 0; i <= 255; i ++) { pDC.MoveTo(i + 10, 280); pDC.LineTo(i + 10, 281 - (int) (app->color[i] * 256 / lMaxCount)); } UpdateData(FALSE); } 3、设计用于二值化阀值输入的对话框,并创建相应的对话框类CErzhi。在输入阀值按下确定键后,将调用OnEz()函数进行二值化处理,并显示处理后的图像。 【实验结果及分析】 打开一bmp文件及其直方图为: 如上图所示,是对该图片的灰度值分析,统计出的直方图显示,灰度值范围从0到255, 即最小灰度值为0,最大灰度值为255。波峰(最有代表性)的灰度值为135,有1821个像素点。 二值化处理及显示: 对此图片做了二值化处理,得到了上面的图片。可以看到,由于二值化的阈值设置为 126,还可以区分出多数边沿,如果设置的与0比较接近,图片上就会只有很少的部分显示为黑色,甚至区分不出物体的部分边沿。为对比效果,下图给出阈值设置为212时得到的图像。 【实验总结】 通过本次实验,我对直方图和二值化处理有了更深的认识和学习,能通过对图像信息的统计设计并显示出相应的直方图,确定其灰度值,并能交互式实现二值化处理。从直方图中可以明显看出图像的灰度分布,更加清晰的理解了图像像素的含义和属性。PHOTOSHOP的直方图功能在设计上供用户使用查阅有明显优势,在右边可以看到,而图像较小。此次实验还认识到阈值二值化处理是一种可以为突出某些像素而进行的特殊处理,可以根据自己的需要来突出地看到图像中的合适像素。 【参考文献】 1. 杨淑莹编著,《VC++图像处理程序设计(第二版)》,清华大学出版社,2005 2. 赵辉, 叶子青编著,《Visual C++系统开发实例精粹》,人民邮电出版社,2005 3. 谭明金编著,《Visual C++图形编程技巧与实例》,人民邮电出版社,2002 4. 霍宏涛编著,《数字图像处理》,北京理工大学出版社,2002 5. 马平编著,《数字图像处理和压缩》,电子工业出版社,2007 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务