📄 histogram1.cpp
字号:
// Histogram1.cpp : implementation file
//
/**********************************************************************
* Copyright (c) 2003, Medical Image Processing Lab, Sichuan University
* All rights reserved.
*
* 文件名称:Equalize.cpp
* 摘 要:图像直方图CHistogram的源文件
*
* 当前版本:1.1
* 作 者:jian wei zhang
* 完成日期:2004年10月30日
************************************************************************/
#include "stdafx.h"
#include "photostar.h"
#include "Histogram1.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHistogram dialog
CHistogram::CHistogram(CWnd* pParent /*=NULL*/)
: CDialog(CHistogram::IDD, pParent)
{
//{{AFX_DATA_INIT(CHistogram)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CHistogram::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHistogram)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHistogram, CDialog)
//{{AFX_MSG_MAP(CHistogram)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHistogram message handlers
BOOL CHistogram::ShowHistogram()
{
if (DoModal()!=IDOK)
{
return FALSE;
}
return TRUE;
}
BOOL CHistogram::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT(m_pImageObject != NULL); //声明m_pImageObject不得为空
CImageObject* pImageObject = m_pImageObject;
//**********获取图像的像素区指针和各种参数,这段代码是通用的****************
int nWidth = pImageObject->GetWidth(); //取得图像的宽度
int nHeight = pImageObject->GetHeight(); //取得图像的高度
int nNumBits = pImageObject->GetNumBits();//取得图像的位数
int nWidthBytes; //图像每行所占的字节数
char *pBuffer = (char *) pImageObject->GetDIBPointer( &nWidthBytes );
if( pBuffer == NULL ) return(FALSE);
BITMAPFILEHEADER *pBFH; //图像文件头指针
BITMAPINFOHEADER *pBIH; //图像信息头指针
RGBQUAD *pRGBPalette; //图像调色板指针
unsigned char *pBits; //像素区的首指针
int nNumColors = pImageObject->GetNumColors();
pBFH = (BITMAPFILEHEADER *) pBuffer;
pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
pRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
//pBits就是我们所必须要的像素指针!!!
//*************初始化类的其他数据成员********************
int nSize = 1<<nNumBits;
int k = 0;
long* plCount=NULL;
switch (nNumBits)
{
case 8:
//根据图像的位数分配相应的内存
plCount = new long[nSize];
m_pfDistr = new float[nSize];
if ((m_pfDistr==NULL) || (plCount==NULL))
{
return FALSE;
}
//清零
for (k=0; k<nSize; k++)
{
plCount[k] = 0;
m_pfDistr[k] = 0;
}
break;
case 16:
break;
case 24:
break;
default:
break;
}
//********************计算直方图********************
int i, j;
for (j=0; j<nHeight; j++)
{
for (i=0; i<nWidth; i++)
{
plCount[pBits[(nHeight-1-j)*nWidthBytes + i]] ++;
//注意取图像中(i, j )点像素的方式!!!!!
}
}
long lTotalCount = (long)nHeight * nWidth;
for (k=0; k<256; k++)
{
m_pfDistr[k] = plCount[k] / (float)lTotalCount;
}
delete [] plCount;
plCount = NULL;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CHistogram::OnPaint()
{
CPaintDC dc(this); // device context for painting
// 获取绘制坐标的文本框
CWnd* pWnd = GetDlgItem(IDC_COORD);
CDC* pDC = pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
RECT rect;
pWnd->GetClientRect(&rect);
pDC->Rectangle(rect.left, rect.top, rect.right, rect.bottom);
int rcWidth = rect.right - rect.left;
int rcHeight = rect.bottom - rect.top;
// 创建画笔对象
CPen* pPenRed = new CPen; //红笔
pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* pPenBlue = new CPen; //蓝笔
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));
CPen* pPenGreen = new CPen; //绿笔
pPenGreen->CreatePen(PS_DOT,1,RGB(0,255,0));
// 选中当前红色画笔,并保存以前的画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenRed);
// 绘制坐标轴
pDC->MoveTo(15, 15);
pDC->LineTo(15, rcHeight - 15);
pDC->LineTo(rcWidth-15, rcHeight -15);
// 绘制纵轴箭头
pDC->MoveTo(15, 15);
pDC->LineTo(15, 5);
pDC->LineTo(13, 10);
pDC->MoveTo(15, 5);
pDC->LineTo(17, 10);
//绘制横轴箭头
pDC->MoveTo(rcWidth-15, rcHeight -15);
pDC->LineTo(rcWidth-5, rcHeight -15);
pDC->LineTo(rcWidth-10, rcHeight -13);
pDC->MoveTo(rcWidth-5, rcHeight -15);
pDC->LineTo(rcWidth-10, rcHeight -17);
// 写X轴刻度值
pDC->SetBkMode(TRANSPARENT);
CString str = _T("");
str.Format("0");
pDC->TextOut(5, rcHeight-17, str);
str.Format("Gray level");
pDC->TextOut((int)(rcWidth/2 - 20), rcHeight-15, str);
pDC->MoveTo(rcWidth-15, rcHeight -15);
pDC->LineTo(rcWidth-15, rcHeight -20);
str.Format("255");
pDC->TextOut(rcWidth-25, rcHeight-15, str);
// 计算最大概率密度值
float fMaxDistr = 0;
for (int i=0; i<256; i++)
{
// 判断是否大于当前最大值
if (m_pfDistr[i] > fMaxDistr)
{
// 更新最大值
fMaxDistr = m_pfDistr[i];
}
}
//写Y轴刻度
pDC->MoveTo(15, 15);
pDC->LineTo(20, 15);
str.Format("%f", fMaxDistr);
pDC->TextOut(20, 8, str);
// 恢复以前的画笔
pDC->SelectObject(pOldPen);
// 绘制直方图
for (i=0; i<256; i ++)
{
pDC->MoveTo(i+15, rcHeight-15);
pDC->LineTo(i+15, rcHeight-15- (int)(m_pfDistr[i]/fMaxDistr*(rcHeight-30)));
}
// 删除新的画笔
delete pPenRed;
delete pPenBlue;
delete pPenGreen;
// Do not call CDialog::OnPaint() for painting messages
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -