MFC 画坐标系以及画灰度图像的直方图

1.创建一个对话框类CHistogramdlg,并在类定义一个指向int指针(Imagedata),用于传入统计好的灰度分布数据,一般存储在256的数组中。

2.重载对话框类的OnPaint,并添加代码如下:

void CHistogramdlg::OnPaint()
{
 CPaintDC dc(this);
 CPen* pPenBlue = new CPen;                                  //创建画笔对象

 pPenBlue->CreatePen(PS_SOLID, 2, RGB(0,0,255));     //蓝色画笔

 CPen* pPenBlack = new CPen;                                 //创建画笔对象

 pPenBlack->CreatePen(PS_SOLID, 1, RGB(0,0,0)); //黑色画笔

 //选中黑色画笔,并保存当前画笔

 CGdiObject* pOldPen = dc.SelectObject(pPenBlack);
 int i = 0;
 CString str;
 //绘制坐标系
 CPoint OPos(40,500),NowPos;
 //绘制x坐标轴
 dc.MoveTo(OPos);    
 NowPos.x = 565;
 NowPos.y = 500;
 dc.LineTo(NowPos);
 //绘制箭头
 dc.LineTo(560,495);
 dc.MoveTo(NowPos);
 dc.LineTo(560,505);
 //绘制x轴坐标系数
 for (i = 0;i != 257;i++)
 {
  if (i % 10 == 0)
  {
   dc.MoveTo(OPos.x + 2 * i,OPos.y);
   dc.LineTo(CPoint(OPos.x + 2 * i,OPos.y - 5));
  }
  if (i % 20 == 0)
  {
   str.Format("%d",i);
   dc.TextOut(OPos.x + 2 * i,OPos.y + 1,str);
  }
 }
 //绘制y轴坐标系数
 dc.MoveTo(OPos);
 NowPos.x = OPos.x;
 NowPos.y = 0;
 dc.LineTo(NowPos);
 //绘制箭头
 dc.LineTo(NowPos.x - 5,NowPos.y + 5);
 dc.MoveTo(NowPos);
 dc.LineTo(NowPos.x + 5,NowPos.y + 5);
 //寻找数据数组最大的数据
 int max = 0;
 for (i = 0;i != 256;i++)
 {
  if (max < ImagData[i])
  {
   max = ImagData[i];
  }
 }
 //y轴坐标系数的数据步长
 int Tstep = max / 10;
 //y轴坐标系数的刻度步长
 int Ystep = 500 / 21;
 //显示y坐标的刻度和数据
 for (i = 1;i != 22;i++)
 {
  dc.MoveTo(OPos.x,OPos.y - Ystep * i );
  dc.LineTo(CPoint(OPos.x + 5,OPos.y - Ystep * i));
  if (i % 2 == 0)
  {
   str.Format("%d",Tstep * i / 2);
   dc.TextOut(0,OPos.y - Ystep * i - 10,str);
  }
 }

 //绘制灰度图像的直方图
 dc.SelectObject(pPenBlue); //选择蓝色画笔
 for (i = 0;i != 256;i++)
 {
  NowPos.x = OPos.x + (2 * i);
  NowPos.y = OPos.y;
  dc.MoveTo(NowPos);
  NowPos.y = 500 - 500.0f * 20.0f * ImagData[i] / (max * 21);
  dc.LineTo(NowPos);
 }
 //恢复以前的画笔
 dc.SelectObject(pOldPen);
 delete pPenBlue;
 delete pPenBlack;
}

3 把CHistogramdlg.h头文件加入单文档doc的头文件中

4在单文档中菜单中添加直方图菜单,并添加消息函数,具体代码如下:

//判断图像是否为灰度图像
 if (GrayImage == NULL)
 {
  MessageBox(NULL,"请先把图像转换为灰度图像","操作提示",MB_OK);
  return ;
 }
 int step = GrayImage->widthStep / sizeof(uchar);
 uchar *data = (uchar *)GrayImage->imageData;
 int HistData[256],i = 0,j = 0;
 for (j = 0;j != 256;j++)
 {
  HistData[j] = 0;
 }
 for (i = 0;i != GrayImage->height;i++)
 {
  for (j = 0;j != GrayImage->width;j++)
  {
   HistData[data[i * step + j]]++;
  }
 }
 CHistogramdlg dlg;
 dlg.ImagData = HistData;
 if (dlg.DoModal() != IDOK)
 {
  return;
 }
 delete dlg;

5运行结果:

灰度图像直方图运行结果

 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
/*=============================================== 作者:LXZ-2008 FROM:CUMT 计08级 时间:2012-04-22 功能:能在SDK、MFC编程中实现笛卡尔 坐标系统的绘制,以及曲线,点的绘制。 特性:1.本程序采用面向对象思想设计; 2.具备很好的独立性,随时可以把这两个文件应 用在任意SDK、MFC开发中; 3.有良好的灵活性,扩展性,易用性,在稍微扩 展一下可以绘制任意曲线,图形; 4.具备良好的组合性,符合模块内高内聚,模块 外低耦合的思路; 5.整个程序仅有1300行左右代码,如果嫌代码过 多,可以把原先变量的PROTECTED保护类型打开, 换成PUBLIC,这样去掉GET和SET函数,这个思路 起源于我对J2EE中STRUTS2框架的学习以及对COM 组件技术的了解,它们也是这种思路这时可以省 下几百行代码。 6.当然也会有设计模式的思路在里面。 个人说明: 本程序花了我将近2天的时间编写,尽管开始有点 不想,但是还是觉得有意义,能给广大网友提供益处。 本系统的雏形来自2010年下半年的程序,当时花了 10天时间,弄了3千行代码。在现在看来当时的程序的 执行效率未必比现在的低,但是可维护性糟糕,可拓展 性糟糕,不具备良好的灵活性。需求改变了,代码会大 幅改变。换句话说,现在看来当时的程序是十分糟糕的, 生命周期已经结束。 而在用了面向对象的思想和设计模式,以及一些数 据结构去重新搭建这个系统的时候,代码其实1千多行就 搞定了,时间3-4天,不需要那么多(现在我来弄的话)。 主要起源于自己参与真实的有数十万代码的项目的开发, 这样提高了对程序开发的认识,以及商业程序应该如何 开发。同时也是自己面向对象思想和设计模式学习,对 自身思想的提高。 希望阅读代码的人觉得这些代码是优雅的,这就满 足了,尽管注释少了些,你们自己加吧。 QQ:706625262 E-MAIL:[email protected] 不做商业和技术支持。 声明: 本程序代码未经本人同意,或者未给我MONEY的前提下, 不得用于商业目的,别让我鄙视你。在非商业目的使用 下请注明本人是原创,表学腾讯。 ==================================================*/

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值