灰度直方图

绘制灰度直方图

晚上帮信息院的高中同学做图像处理的实验,里面有一项是编写一个绘制灰度直方图的程序。感觉信息院的实验还是比较接地气。不想咱院的实验…呵呵呵呵呵。看起来都挺高大上的,就是有点假大空。
效果

###绘制灰度直方图の第一步 打开位图文件

	// TODO: 在此添加控件通知处理程序代码

	  static char szFilter[]="位图文件(*.bmp)|*.bmp;*.dib|All Files(*.*)|*.*||";
	  CFileDialog pickfile(true,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
	  if(pickfile.DoModal()==IDOK)
	  {
		  UpdateData(1);
		  myfilename=pickfile.GetPathName();
	  }else
	  {
		  myfilename.Empty();
	  }

	  CBitmap bitmap;
	  /*
	  CRect myrc;
	  mypic.GetWindowRect(&myrc);
	  */
	 hbitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(), 
			myfilename, 
           IMAGE_BITMAP,
		   512,
		   300,
           LR_LOADFROMFILE);   
	  mypic.SetBitmap(hbitmap);
	  getresult();
	  DrawResult();

首先用构造一个CFileDialog类对象获取文件位置。
这里还顺便把它贴到一个图片控件上预览图片了。
然后计算灰度。

##绘制灰度直方图の第二步 计算灰度

所谓灰度就是指亮度。一个白色的点,RGB值0xFFFFFF。那么他的灰度就是0xFF。黑的像素点就是0。 对于RGB分量相同的颜色灰度就是R,G,B的值。这很显然。 那么对于彩色的点,其实并不是想象中的R,G,B分量乘以1/3累加。 人眼对于各种颜色的感觉并不一致,同样强度绿光在人眼看来就比同样强度的蓝光要亮。因此RGB加权值不一样。
具体的东西可以看维基:Gray Scale
这里给出windows下用的公式:
Y=0.299R+0.587G+0.114*B

		CFile myfile;
	if(!myfile.Open(myfilename,CFile::modeRead))
	{
		MessageBox("打开文件错误!");
		return;
	}
	BITMAPFILEHEADER bmpH;
	if (myfile.Read((LPSTR)&bmpH, sizeof(bmpH)) != sizeof(bmpH)) 
	{
		MessageBox("读取文件头错误!");
		return;
	}

	BITMAPINFOHEADER bmpIH;
	if(myfile.Read((LPSTR)&bmpIH,sizeof(bmpIH))!=sizeof(bmpIH))
	{
		MessageBox("读取文件头错误!");
		return;
	}
	myfile.Close();
	CString str;
	str.Format("     %d*%d",bmpIH.biWidth,bmpIH.biHeight);
	T_path.SetWindowTextA(myfilename+str);

	CDC memDC;
	memDC.CreateCompatibleDC(NULL);
	
	HBITMAP hbmp;
	hbmp=(HBITMAP)LoadImage(AfxGetInstanceHandle(), 
			myfilename, 
           IMAGE_BITMAP,
		   bmpIH.biWidth,
		   bmpIH.biHeight,
           LR_LOADFROMFILE);  
	SelectObject(memDC,hbmp);

	for(int i=0;i<256;i++)
		result[i]=0;
	COLORREF cr;
	int gray;
	for(int y=0;y<bmpIH.biHeight;y++)
		for(int x=0;x<bmpIH.biWidth;x++)
		{
			cr=memDC.GetPixel(x,y);
			gray=(0.299*GetRValue(cr)+0.587*GetGValue(cr)+0.114*GetBValue(cr));
			result[gray]++;
		}
	
	

这里面用CFile打开文件,为的是读取位图文件的文件头。在BITMAPINFOHEADER里有图片的大小信息。

然后为省事我就不自己解析bitmap文件了,直接用MFC的工具把它画到内存里。然后直接memDC.GetPixel()获取像素信息了,省事。 不知道她们实验与不允许。

计算灰度,统计灰度分布。

然后绘图:
##绘制灰度直方图の第二步 计算灰度

	CDC* pDC=((CStatic*)GetDlgItem(IDC_STATIC_DRAW))->GetWindowDC();
	CRect mc;
	GetDlgItem(IDC_STATIC_DRAW)->GetWindowRect(&mc);
	pDC->FillSolidRect(0,0,mc.Width(),mc.Height(),RGB(00,00,00));
	//CString str;
	//str.Format("H:%d  W:%d",mc.Height(),mc.Width());
	pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(RGB(250,250,0));
	pDC->TextOutA(0,0,"灰度直方图");

	CPen myPen(PS_SOLID,1,RGB(0,200,0));
	int max=0;
	for(int i=0;i<256;i++)
	{
		if(result[i]>max)
			max=result[i];
	}
	pDC->SelectObject(&myPen);
	int h;
	for(int i=0;i<256;i++)
	{
		if(result[i])
			h=256-(result[i]*256/max);
		else
			h=256;
		pDC->MoveTo(i*2,256);
		pDC->LineTo(i*2,h);
		pDC->MoveTo(i*2+1,256);
		pDC->LineTo(i*2+1,h);
	}

恩,就是画几根线而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值