灰度直方图

灰度直方图反应图像灰度的统计特性,表达了图像中取不同灰度值的面积或像素数在政府图像中所占的比例,是图像中最基本的信息。

直方图的横坐标是灰度级,一般用r表示,纵坐标是具有该灰度级的像素个数或出现这个灰度级的概率P(rk)(k为下标)。捕获 ;式中,N为一副图像中像素的总数,nk为第k级灰度的像素数,rk表示第k个灰度级,P(rk)则表示该灰度级出现的概率.因为P(rk)给出了对rk出现概率的一个估值,所以直方图提供了原图的灰度值分布情况。

灰度直方图灰度级的分布可以提供图像信息的许多特征,为图像分析提供了一个有力的工具。例如,若直方图密集地分布在很窄的区域之内,说明图像的对比度很低;若直方图有两个峰值,则说明图像中很有可能存在两种不同亮度的区域。

直方图的均值 aver

 

直方图的方差  DIVA


class HistogramDrawDlg : public CDialog
{
	DECLARE_DYNAMIC(HistogramDrawDlg)

public:
	HistogramDrawDlg(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~HistogramDrawDlg();
public: 
    ImageDib m_himageDib ;
	int m_histArry[256] ;
	float m_average  ;
	float m_deviation ;

	int   m_imgWidthOut ;
	int   m_imgHeightOut ;
	int   m_nBitCountOut  ;

	unsigned char * m_pImgDataOut ;
	LPRGBQUAD m_lpColorTableOut ;
	
	int  m_nColorTableLengthOut ;

public: 
	CSize GetDimensions() ; 

	void ComputeHistGray() ;

	float ComputeAverage() ;

	float ComputeDeviation() ;





// 对话框数据
	enum { IDD = IDD_DIALOG_Histogram };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	afx_msg void OnPaint() ; 


	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL OnInitDialog();
	
};


// HistogramDrawDlg.cpp : 实现文件
#include "stdafx.h"
#include "Pic.h"
#include "HistogramDrawDlg.h"
#include "afxdialogex.h"
#include <math.h>


// HistogramDrawDlg 对话框

IMPLEMENT_DYNAMIC(HistogramDrawDlg, CDialog)

HistogramDrawDlg::HistogramDrawDlg(CWnd* pParent /*=NULL*/)
	: CDialog(HistogramDrawDlg::IDD, pParent)
{
	memset(m_histArry , 0 , sizeof(m_histArry)) ;
	m_average = 0.0 ;
	m_deviation = 0.0 ;

	m_nBitCountOut = 0  ;
	m_pImgDataOut = NULL ;
	m_lpColorTableOut = NULL ;

	m_imgWidthOut = 0 ;
	m_imgHeightOut = 0 ;
	m_nColorTableLengthOut = 0 ;
}

HistogramDrawDlg::~HistogramDrawDlg()
{
	if(m_pImgDataOut != NULL){
		delete []m_pImgDataOut ;
		m_pImgDataOut = NULL ;
	}
	if(m_lpColorTableOut != NULL){
		delete []m_lpColorTableOut ;
		m_lpColorTableOut = NULL ;
	}
}

void HistogramDrawDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(HistogramDrawDlg, CDialog)
	ON_WM_PAINT()
END_MESSAGE_MAP()


// HistogramDrawDlg 消息处理程序

CSize HistogramDrawDlg::GetDimensions(){
	  m_imgWidthOut = m_himageDib.m_imgWidth ;
	  m_imgHeightOut = m_himageDib.m_imgHeight ;
	  if(m_pImgDataOut == NULL)  return CSize(0 , 0) ;
	  else  return CSize(m_imgWidthOut , m_imgHeightOut) ;
} 

void  HistogramDrawDlg::ComputeHistGray(){
		if(m_nBitCountOut != 8)  return  ;

		memset(m_histArry , 0 , sizeof(m_histArry)) ;
		int lineByte = (m_himageDib.m_imgWidth * m_nBitCountOut/8 + 3) / 4 * 4 ;

		for(int i = 0 ; i < m_imgHeightOut ; i++){
			for(int j = 0 ; j < m_imgWidthOut ; j++){
				m_histArry[*(m_himageDib.m_pImgData + i * lineByte + j)]++ ;
			}
		}
}

float HistogramDrawDlg::ComputeAverage(){
	  float sum = 0 ; 
	  for(int i = 0 ; i < 256 ; i++){
		    sum += i * m_histArry[i] ;
	  }
	  return m_average = sum / (m_himageDib.m_imgHeight * m_himageDib.m_imgWidth) ; 
}

float HistogramDrawDlg::ComputeDeviation(){
	  float sum = 0 ;
	  for(int i = 0 ; i < 256 ; i++){
		   sum += (i - m_average) * (i - m_average) * m_histArry[i] ;
	  }
	  sum /= (m_himageDib.m_imgWidth * m_himageDib.m_imgHeight) ;
      return m_deviation = sqrt(sum) ;
}


BOOL HistogramDrawDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_nBitCountOut = m_himageDib.m_nBitCount ;
	m_imgHeightOut = m_himageDib.m_imgHeight ;
	m_imgWidthOut = m_himageDib.m_imgWidth ;


        CRect rect;
	rect=CRect(50,60,300,170);
	GetDlgItem(IDC_STATIC_hist)->MoveWindow(&rect);  
	if(m_nBitCountOut == 8) 	ComputeHistGray() ;
	CString str ;
	str.Format(_T("%.2lf") , ComputeAverage() ) ;
	SetDlgItemText(IDC_STATIC_AveShow , str) ;

	str.Format(_T("%.2lf") , ComputeDeviation() ) ;
	SetDlgItemText(IDC_STATIC_DevShow , str) ;

	return TRUE;  // return TRUE unless you set the focus to a control

}


void HistogramDrawDlg::OnPaint(){
	 CPaintDC dc(this); // device context for painting

	// TODO: Add your message handler code here
	//彩色和灰度图像有效
	 if(m_nBitCountOut!= 8 && m_nBitCountOut!= 24) 
		return ;

	//获取直方图绘制静态框的矩形区域
	 CRect clientRect;  
	 GetDlgItem(IDC_STATIC_hist)->GetWindowRect(&clientRect);
	 ScreenToClient(&clientRect);

	 BeginWaitCursor();	    // Draw Back Ground
	//画背景
	 dc.SelectStockObject(NULL_BRUSH);
	 dc.Rectangle(clientRect.left, clientRect.top-5,
		clientRect.right, clientRect.bottom+1);

	//画直方图灰度频率与直方图绘制矩形区域比例关系,画直方图
	 unsigned int max=0;;
	 for(int i=0;i<256;i++){
		if(m_histArry[i]>max)
			max=m_histArry[i];
	 }
	 DWORD bufTemp[256];
	 double x=clientRect.Height();
	 int i ;
	 for(i=0;i<256;i++){
		 bufTemp[i]=(unsigned long)((float)m_histArry[i]*x/max);
	 }
	 for(i=clientRect.left;i<=clientRect.right;i++){
	    dc.MoveTo(i,clientRect.bottom);
	  	dc.LineTo(i,clientRect.bottom-bufTemp[i-clientRect.left]);
	}   

	CString str;
	SetBkMode(dc,1);      //字体背景设为透明
	str.Format(_T("0"));
	dc.TextOut(clientRect.left,clientRect.bottom+1,str);
	str.Format(_T("50"));
	dc.TextOut(clientRect.left+50,clientRect.bottom+1,str);
	str.Format(_T("100"));
	dc.TextOut(clientRect.left+100,clientRect.bottom+1,str);
	str.Format(_T("150"));
	dc.TextOut(clientRect.left+150,clientRect.bottom+1,str);
	str.Format(_T("200"));
	dc.TextOut(clientRect.left+200,clientRect.bottom+1,str);
	str.Format(_T("255"));
	dc.TextOut(clientRect.left+255,clientRect.bottom+1,str);

	EndWaitCursor();


}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值