您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 公司方案 > MFC对话框绘制灰度直方图
MFC对话框绘制灰度直方图一.程序运行结果该篇文章主要是在上一篇文章基础上进行的讲解,其中当打开一张BMP图像后,点击”直方图“-》”显示原图直方图“如下。二.灰度直方图原理什么是灰度直方图?灰度直方图(histogram)是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映图像中每种灰度出现的频率。横坐标是灰度级,纵坐标是灰度级出现的频率。对于连续图像,平滑地从中心的高灰度级变化到边缘的低灰度级。直方图定义为:其中A(D)为阈值面积函数:为一幅连续图像中被具有灰度级D的所有轮廓线所包围的面积。对于离散函数,固定ΔD为1,则:H(D)=A(D)-A(D+1)色彩直方图是高维直方图的特例,它统计色彩的出现频率,即色彩概率分布信息。通常这需要一定的量化过程,将色彩分成若干互不重叠的种类。一般不直接在RGB色彩空间中统计,而是在将亮度分离出来后,对代表色彩部分的信息进行统计,如在HSI空间的HS子空间、YUV空间的UV子空间,以及其它反映人类视觉特点的彩色空间表示中进行。其中直方图的计算方法如下:依据定义,若图像具有L(通常L=256,即8位灰度级)级灰度,则大小为MxN的灰度图像f(x,y)的灰度直方图hist[0…L-1]可用如下计算获得。1、初始化hist[k]=0;k=0,…,L-12、统计hist[f(x,y)]++;x=0,…,M-1,y=0,…,N-13、归一化hist[f(x,y)]/=M*N那么说了这么多,直方图究竟有什么作用呢?在使用轮廓线确定物体边界时,通过直方图更好的选择边界阈值,进行阈值化处理;对物体与背景有较强对比的景物的分割特别有用;简单物体的面积和综合光密度IOD可以通过图像的直方图求得。三.程序实现1.建立直方图对话框第一步:创建Dialog将视图切换到ResourceView界面,选中Dialog右键鼠标新建一个Dialog,并新建一个名为IDD_DIALOG_ZFT,设置成下图对话框。右键添加属性如下:对话框-原始直方图-IDD_DIALOG_ZFT组框-RGB-IDC_STATIC_RGB图像-框架-IDC_STATIC_KJ-蚀刻(重点:有它才能添加直方图在此处,注意GetDlgItem()函数中是IDC而不是IDD对话框)添加蚀刻线(图像蚀刻形成的直线)形如图中的3个矩形框,并添加静态文本:Red、Green、Blue、红、绿、蓝、像素、平均灰度、中值灰度、标准差;这些静态文本都是IDC_STATIC且为默认属性添加红色4个值(Static)、绿色4个值、蓝色4个值,分别为:IDC_STATIC_XS_RED(GREENBLUE)对应像素XSIDC_STATIC_PJHD_RED(GREENBLUE)对应平均灰度PJHDIDC_STATIC_ZZHD_RED(GREEDBLUE)对应中值灰度ZZHDIDC_STATIC_BZC_RED(GREENBLUE)对应标准差BZC第二步:建立类向导MFCClassWizard(1)在对话框资源模板空白区双击鼠标(Ctrl+W),创建一个新类,命名为CImageZFTDlg会自动生成它的.h和.cpp文件。在类向导中选中类名CImageZFTDlg,IDs为CImageZFTDlg,WM_INITDIALOG建立这个函数用于初始化。(2)打开类向导,选择MemberVariables页面,添加如下变量,类型均为CString。像素m_redXS、m_greenXS、m_blueXS标准差m_redBZC、m_greeenBZC、m_blueBZC平均灰度m_redPJHD、m_greenPJHD、m_bluePJHD中值灰度m_redZZHD、m_greenZZHD、m_blueZZHD(3)在View.cpp中添加直方图的头文件#inlcudeImageZFTDlg.h第三步:设置菜单栏调用直方图对话框(1)将视图切换到ResourceView界面,选中Menu,在IDR_MAINFRAM中添加菜单项“直方图”,菜单属性中选择“弹出”,在“直方图”中添加子菜单“显示原图直方图”。(2)设置其属性为ID_ZFT_YT(显示直方图原图),同时建立类向导,选择ID_ZFT_YT(IDs),通过COMMAND建立显示直方图函数OnZftYt()。第四步:添加代码及计算4个值在ImageProcessingView.cpp中添加如下代码,注释中有如何求平均灰度、中值灰度和标准差的消息算法过程。[cpp]viewplaincopy1.//引用显示直方图头文件2.#includeImageZFTDlg.h3.#includemath.h4.5./*全局变量在TestZFTDlg.cpp中引用用extern*/6.intRed[256],Green[256],Blue[256];7.8./**************************************************/9./*添加直方图显示功能,并在直方图下方显示相关信息10./*如平均灰度、中值灰度、标准差和像素总数11./*ID_ZFT_YT:直方图原图显示12./**************************************************/13.voidCImageProcessingView::OnZftYt()14.{15.if(numPicture==0){16.AfxMessageBox(载入图片后才能显示原图直方图!,MB_OK,0);17.return;18.}19.AfxMessageBox(显示原图直方图!,MB_OK,0);20.CImageZFTDlgdlg;21.22.//打开临时的图片23.FILE*fpo=fopen(BmpName,rb);24.fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);25.fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);26.27.inti,j;28.for(j=0;j256;j++){//定义数组并清零29.Red[j]=0;30.Green[j]=0;31.Blue[j]=0;32.}33.34.//计算4个数据35.unsignedcharred,green,blue;36.intIntRed,IntGreen,IntBlue;//强制转换37.doublesumRedHD=0,sumGreenHD=0,sumBlueHD=0;//记录像素总的灰度值和38.for(i=0;im_nImage/3;i++)39.{40.fread(&red,sizeof(char),1,fpo);41.IntRed=int(red);42.sumRedHD=sumRedHD+IntRed;43.if(IntRed=0&&IntRed256)Red[IntRed]++;//像素0-255之间44.45.fread(&green,sizeof(char),1,fpo);46.IntGreen=int(green);47.sumGreenHD=sumGreenHD+IntGreen;48.if(IntGreen=0&&IntGreen256)Green[IntGreen]++;49.50.fread(&blue,sizeof(char),1,fpo);51.IntBlue=int(blue);52.sumBlueHD=sumBlueHD+IntBlue;53.if(IntBlue=0&&IntBlue256)Blue[IntBlue]++;54.}55.fclose(fpo);56.57.//像素:int型转换为CString型58.dlg.m_redXS.Format(%d,m_nImage);59.dlg.m_greenXS.Format(%d,m_nImage);60.dlg.m_blueXS.Format(%d,m_nImage);61.62.//平均灰度值:计算24位bmp图片的灰度值,我是记录RGB中的所有平均值63.floatpinRedHD,pinGreenHD,pinBlueHD;64.pinRedHD=sumRedHD*3/m_nImage;65.pinGreenHD=sumGreenHD*3/m_nImage;//平均灰度=总灰度/总像素66.pinBlueHD=sumBlueHD*3/m_nImage;67.68.dlg.m_redPJHD.Format(%.2f,pinRedHD);69.dlg.m_greenPJHD.Format(%.2f,pinGreenHD);70.dlg.m_bluePJHD.Format(%.2f,pinBlueHD);71.72./****************************************************************/73./*中值灰度:算法重点(黄凯大神提供)74./*中值灰度:所有像素中的中位数,应该所有像素排序找到中间的灰度值75./*算法:num[256]记录各灰度出现次数,sum+=num[i],找到sum=总像素/276./****************************************************************/77.intsumRedZZHD=0,sumGreenZZHD=0,sumBlueZZHD=0;78.intredZZHD,greenZZHD,blueZZHD;79.for(i=0;i256;i++)80.{81.sumRedZZHD=sumRedZZHD+Red[i];82.if(sumRedZZHD=m_nImage/6)//m_nImage被分成3份RGB并且sum=总像素/283.{84.redZZHD=i;85.break;86.}87.}88.for(i=0;i256;i++)89.{90.sumGreenZZHD=sumGreenZZHD+Green[i];91.if(sumGreenZZHD=m_nImage/6)//m_nImage被分成3份RGB并且sum=总像素/292.{93.greenZZHD=i;94.break;95.}96.}97.for(i=0;i256;i++)98.{99.sumBlueZZHD=sumBlueZZHD+Blue[i];100.if(sumBlueZZHD=m_nImage/6)//m_nImage被分成3份RGB并且sum=总像素/2101.{102.blueZZHD=i;103.break;104.}105.}106.107.dlg.m_redZZHD.Format(%d,redZZHD);108.dlg.m_greenZZHD.Format(%d,greenZZHD);109.dlg.m_blueZZHD.Format(%d,blueZZHD);110.111./******************************************************************/112./*标准差:标准差=方差的算术平方根113./*方差s^2=[(x1-x)^2+(x2-x)^2+......(xn-x)^2]/n114./*算法:不用开m_nImage数组进行计算用num[256]中数进行115./*方差=(平均灰度-i)*(平均灰度-i)*Red[i]有Red[i]个灰度值为i的数116./******************************************************************/117.floatredBZC,greenBZC,blueBZC;//标准差118.doubleredFC=0,greenFC=0,blueFC=0;//方差119.for(i=0;i256;i++)120.{121.redFC=redFC+(pi
本文标题:MFC对话框绘制灰度直方图
链接地址:https://www.777doc.com/doc-2888501 .html