直方图图像处理报告
图像处理上机报告学号:班级:姓名:指导老师上机目标一:实现 bmp 图片的直方图的显示。目标分析:要实现目标一,首先需做到的时对 bmp 图片的读取与显示;然后才能对图片进行灰度统计,如果是彩色图片可以先将之灰度化再统计,或者直接对其 R、G、B 三个直方图进行分别显示。在此我做的是选择将彩色图片进行灰度化然后再统计灰度值,实现直方图的显示。大体算法步骤:1、 对 bmp 图读取与显示用的是何兴恒老师的程序(具体分析在下部分) 。2、 如果是彩色图片则对其进行灰度化,然后统计其灰度值。3、 对图片实行灰度化统计后,进行直方图的显示。算法及数据结构:算法步骤 1:Bmp 图的读取显示:GetBmpSize(fname,&dx,&dy) 获取图像大小;UINT *buf=new UINTdx*dy; ReadBmp(fname,dx,dy,buf);申请一块动态内存 buf 大小为 dx*dy 来实现图像读取;MDBUF=buf; mdr->write_video(0,0,dx,dy,buf) ;mdr->swap();将图片放入内存并显示出来。具体函数:onFileOpen() ; 算法步骤 2:彩色图片的灰度化。定义一个 UCHAR 型的指针变量 c 用来指向内存 MDBUF;如 c0、c1 、c2、c3 分别表示的是第一个像素点的 B、 G、R 、A 值。利用灰度化公式 0.11*B+0.59*G+0.30R 来实现。通过实现 dx*dy(图像长宽积)次循环。以下为部分代码:for (j=0;jclear_win();UINT *buf=new UINTdx*dy;ReadBmp(fname,dx,dy,buf);MDBUF=buf;mdr->write_video(0,0,dx,dy,buf);mdr->swap();/MDBUF=buf;int j=0;int k=0;UCHAR *c=(UCHAR *)buf;for(i=0;iwrite_video(500,0,x1,y1,MDBUF);mdr->swap();mdr->winx0=0;/void CMFC_HIST2View:OnHistShow() /显示直方图控件/ TODO: Add your command handler code hereif(MDBUF=NULL)AfxMessageBox("没有图片 !");return;BeginWaitCursor();/ 创建对话框/ 初始化变量/ 显示对话框if (m_dShow.DoModal() != IDOK)/ 返回return;/ 恢复光标EndWaitCursor();/void CDialogHist:OnPaint() /画直方图CPaintDC dc(this); / device context for paintingint i;/ 获取绘制直方图文本框的标签CWnd* pWnd = GetDlgItem(IDC_STATIC_HIST);/ 获取设备上下文CDC* pDC = pWnd->GetDC();pWnd->Invalidate();pWnd->UpdateWindow();/ 创建画笔对象CPen* pPenRed = new CPen;/ 创建红色画笔(用于绘制坐标轴)pPenRed->CreatePen(PS_SOLID, 1, RGB(255,0,0);/ 选入红色画笔,并保存以前的画笔CPen* pOldPen = pDC->SelectObject(pPenRed);/ 绘制坐标轴pDC->MoveTo(10,0);/ 绘制垂直轴pDC->LineTo(10, 280);/ 绘制水平轴pDC->LineTo(320, 280);/绘制 X 轴刻度值CString strTemp;strTemp.Format("0");pDC->TextOut(8, 288, strTemp);strTemp.Format("50");pDC->TextOut(58, 288, strTemp);strTemp.Format("100");pDC->TextOut(105, 288, strTemp);strTemp.Format("150");pDC->TextOut(155, 288, strTemp);strTemp.Format("200");pDC->TextOut(205, 288, strTemp);strTemp.Format("255");pDC->TextOut(260, 288, strTemp);/ 绘制 X 轴刻度for (i = 0; i MoveTo(i + 10, 280);pDC->LineTo(i + 10, 288);else if(i % 10)=0)/ 5 的奇数倍数pDC->MoveTo(i + 10, 280);pDC->LineTo(i + 10, 286);else pDC->MoveTo(i+10,280);pDC->LineTo(i+10,284);/ 绘制 X 轴箭头pDC->MoveTo(315,285);pDC->LineTo(320,280);pDC->LineTo(315,285);/ 绘制 Y 轴箭头pDC->MoveTo(5,5);pDC->LineTo(10,0);pDC->LineTo(15,5);/ 直方图中最大计数值LONG lMaxCount = 0;/ 计算最大计数值for (i = 0; i lMaxCount)/ 更新最大值lMaxCount = m_DHisti;/ 输出最大计数值pDC->MoveTo(10, 10);pDC->LineTo(14, 10);strTemp.Format("%d", lMaxCount);pDC->TextOut(11, 10, strTemp);/ 声名画笔对象CPen* pPenBlue = new CPen;/ 创建蓝色画笔(用于绘制直方图)pPenBlue->CreatePen(PS_SOLID, 1, RGB(0,0,255);/ 选入蓝色画笔pDC->SelectObject(pPenBlue);/ 判断是否存在计数值if(lMaxCount > 0)/ 绘制直方图for (i = 0; i MoveTo(i + 10, 280);pDC->LineTo(i + 10, 281 - (int) (m_DHisti / (lMaxCount/260);/ 恢复以前的画笔pDC->SelectObject(pOldPen);/ 删除新的画笔delete pPenRed;delete pPenBlue;/ TODO: Add your message handler code here/ Do not call CDialog:OnPaint() for painting messages/void CMFC_HIST2View:GetXS(int y,int x)/取得 x、y 点的 RGBA 值int i=x,j=y;if (i=0&&j=0)b0=b1=b2=b3=b4=b6=B00;g0=g1=g2=g3=g4=g6=G00;r0=r1=r2=r3=r4=r6=R00;a0=a1=a2=a3=a4=a6=A00;b5=B01;g5=G01;r5=R01;a5=A01;b7=B10;g7=G10;r7=R10;a7=A10;b8=B11;g8=G11;r8=R11;a8=A11;else if (i=x1&&j=0)b0=b1=b2=b5=b4=b8=B0x1-1;g0=g1=g2=g5=g4=g8=G0x1-1;r0=r1=r2=r5=r4=r8=R0x1-1;a0=a1=a2=a5=a4=a8=A0x1-1;b5=B0x1-2;g5=G0x1-2;r5=R0x1-2;a5=A0x1-2;b7=B1x1-1;g7=G1x1-1;r7=R1x1-1;a7=A1x1-1;b6=B1x1-2;g6=G1x1-2;r6=R1x1-2;a6=A1x1-2;else if (i=0&&j=y1-1)b0=b3=b6=b7=b8=b4=By1-10;g0=g3=g6=g7=g8=g4=Gy1-10;r0=r3=r6=r7=r8=r4=Ry1-10;a0=a3=a6=a7=a8=a4=Ay1-10;b1=By1-20;g1=Gy1-20;r1=Ry1-20;a1=Ay1-20;b2=By1-21;g2=Gy1-21;r2=Ry1-21;a2=Ay1-21;b5=By1-11;g5=Gy1-11;r5=Ry1-11;a5=Ay1-11;else if (i=x1-1&&j=y1-1)b2=b5=b6=b7=b8=b4=By1-1x1-1;g2=g5=g6=g7=g8=g4=Gy1-1x1-1;r2=r5=r6=r7=r8=r4=Ry1-1x1-1;a2=a5=a6=a7=a8=a4=Ay1-1x1-1;b0=By1-2x1-2;g0=Gy1-2x1-2;r0=Ry1-2x1-2;a0=Ay1-2x1-2;b1=By1-2x1-1;g1=Gy1-2x1-1;r1=Ry1-2x1-1;a1=Ay1-2x1-1;b3=By1-1x1-2;g3=Gy1-1x1-2;r3=Ry1-1x1-2;a3=Ay1-1x1-2;else if (j=0&&(i!=0&&i!=x1-1)b0=b1=b2=b4=B0i;g0=g1=g2=g4=G0i;r0=r1=r2=r4=R0i