(学习笔记6)BMP位图照片的灰度变换之直方图
来源:互联网 发布:马来西亚海关数据 编辑:程序博客网 时间:2024/05/29 17:37
接着(学习笔记5)来写,注意注意是在(学习笔记5)上去写直方图的。每个学习笔记都是在前一个基础上去写的。
好的废话完了,直接写直方图。
step1.修改菜单栏中灰度变换下直方图的ID,如下图所示:
step2.直方图的显示,我们需要设计一个对话框来在Picture Control控件中显示,所以第二步,我们来设计对话框。
步骤如下截屏所示:
设计的最终界面如下:
接下来一步步去阐述步骤和过程。
修改对话框的ID,和对话框的Caption以及从工具箱中拉入Group Box和Picture Control控件就不用说了,请注意:Group Box中拉进去了两个Picture Control控件。
第一Picture Control的ID修改
第二个Picture Control的ID修改,以及Type,Image修改。
左上角的照片如下:添加资源命名为IDB_BITMAP1
修改“均值”下边的Edit Control的ID
修改“方差”下边的Edit Control的ID
Picture Control还有一个属性需要修改。如下截图:
step3. 响应函数。
afx_msg void OnHistogramDraw();
void Cdemo1View::OnHistogramDraw() { // TODO: Add your command handler code here //获取文档类中m_dib的指针,访问当前DIB数据 Cdemo1Doc *pDoc=GetDocument(); ImageDib *pDib=pDoc->m_dib; //异常判断 if(pDib->m_nBitCount!=8&&pDib->m_nBitCount!=24){ ::MessageBox(0,L"只处理灰度和彩色图像",MB_OK,0); return ; } //直方图绘制对话框 HistogramDrawDlg dlgHist; dlgHist.m_himageDib.ReplaceDib(pDib->GetDimensions(),pDib->m_nBitCount, pDib->m_lpColorTable, pDib->m_pImgData); //显示直方图 dlgHist.DoModal();}
#if !defined(AFX_HISTOGRAMDRAWDLG_H__2CABD0F5_E9B6_4128_9979_64C4DAE89356__INCLUDED_)#define AFX_HISTOGRAMDRAWDLG_H__2CABD0F5_E9B6_4128_9979_64C4DAE89356__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "ImageDib.h"// HistogramDrawDlg.h : header file///////////////////////////////////////////////////////////////////////////////// HistogramDrawDlg dialogclass HistogramDrawDlg : public CDialog{// Constructionpublic: //构造函数 HistogramDrawDlg(CWnd* pParent = NULL); // standard constructor //ImgDib类的对象m_himageDib ImageDib m_himageDib;public: //直方图数组 int m_histArray[256]; //直方图平均值 float m_average; //直方图方差 float m_deviation; //输出图像每像素位数 int m_nBitCountOut; //输出图像位图数据指针 unsigned char * m_pImgDataOut; //输出图像颜色表 LPRGBQUAD m_lpColorTableOut; //输出图像的宽,像素为单位 int m_imgWidthOut; //输出图像的高,像素为单位 int m_imgHeightOut; //输出图像颜色表长度 int m_nColorTableLengthOut; CEdit DEV; CEdit AVE;public: //以像素为单位返回输出图像的宽和高 CSize GetDimensions(); //灰度图像统计直方图 void computeHistGray(); //彩色图像亮度直方图 void computeHistBrightness(); //计算直方图均值 float computeAverage(); //计算直方图方差 float computeDeviation(); //直方图均衡 void histogramAve(); //析构函数 ~HistogramDrawDlg();// Dialog Data //{{AFX_DATA(HistogramDrawDlg) enum { IDD = IDD_DIALOG_Histogram }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(HistogramDrawDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected: // Generated message map functions //{{AFX_MSG(HistogramDrawDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_HISTOGRAMDRAWDLG_H__2CABD0F5_E9B6_4128_9979_64C4DAE89356__INCLUDED_)
// HistogramDrawDlg.cpp : implementation file//#include "stdafx.h"#include "demo1.h"#include "HistogramDrawDlg.h"#include "ImageDib.h"#include "math.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// HistogramDrawDlg dialogHistogramDrawDlg::HistogramDrawDlg(CWnd* pParent /*=NULL*/) : CDialog(HistogramDrawDlg::IDD, pParent){ //{{AFX_DATA_INIT(HistogramDrawDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT for(int i=0;i<256;i++) m_histArray[i]=0; m_average = 0;//均值为0 m_deviation=0;//方差为0 m_pImgDataOut=NULL;//输出图像位图数据指针为空 m_lpColorTableOut=NULL;//输出图像颜色表指针为空 m_nColorTableLengthOut=0;//输出图像颜色表长度为0 m_nBitCountOut=0;//输出图像每像素位数为0 m_imgWidthOut=0;//输出图像的宽为0 m_imgHeightOut=0;//输出图像的高为0}void HistogramDrawDlg::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_STATIC_AveShow, AVE); DDX_Control(pDX, IDC_STATIC_DevShow, DEV); //{{AFX_DATA_MAP(HistogramDrawDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(HistogramDrawDlg, CDialog) //{{AFX_MSG_MAP(HistogramDrawDlg) ON_WM_PAINT() //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// HistogramDrawDlg message handlersBOOL HistogramDrawDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_nBitCountOut=m_himageDib.m_nBitCount; m_imgWidthOut=m_himageDib.m_imgWidth; m_imgHeightOut=m_himageDib.m_imgHeight; //将静态框1移至rect指定位置,用来画直方图 CRect rect; rect=CRect(50,60,300,170); GetDlgItem(IDC_STATIC_Hist)->MoveWindow(&rect); //将颜色提示条移至指定位置 rect=CRect(50,195,300,228); GetDlgItem(IDC_STATIC_GrayColor)->MoveWindow(&rect); // 如果是灰度图像,则调用灰度直方图统计函数 if(m_nBitCountOut==8) computeHistGray(); else//彩色图像则统计亮度直方图 computeHistBrightness(); //计算直方图的均值和方差 float m_ave=computeAverage(); float m_dev=computeDeviation(); //将均值信息显示在均值静态框中 char szStr[10]; sprintf(szStr, "%.2f",m_ave); AVE.SetWindowTextW(CString(szStr)); //SetDlgItemText(IDC_STATIC_AveShow, szStr); //将方差信息显示在方差静态框中 sprintf(szStr, "%.2f", m_dev); //SetDlgItemText(IDC_STATIC_DevShow, szStr); DEV.SetWindowTextW(CString(szStr)); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE}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_histArray[i]>max) max=m_histArray[i]; } DWORD bufTemp[256]; double x=clientRect.Height(); for(int i=0;i<256;i++){ bufTemp[i]=(unsigned long)((float)m_histArray[i]*x/max); } for(int 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(); // Do not call CDialog::OnPaint() for painting messages}HistogramDrawDlg::~HistogramDrawDlg(){ //释放输出图像位图数据缓冲区 if(m_pImgDataOut!=NULL){ delete []m_pImgDataOut; m_pImgDataOut=NULL; } //释放输出图像颜色表 if(m_lpColorTableOut!=NULL){ delete []m_lpColorTableOut; m_lpColorTableOut=NULL; }}/************************************************************************ 函数名称:* GetDimensions()**函数参数:* 无**返回值:* 图像的尺寸,用CSize类型表达**说明:返回输出图像的宽和高***********************************************************************/CSize HistogramDrawDlg::GetDimensions(){ m_imgWidthOut=m_himageDib.m_imgWidth; m_imgHeightOut=m_himageDib.m_imgHeight; if(m_pImgDataOut == NULL) return CSize(0, 0); return CSize(m_imgWidthOut, m_imgHeightOut);}/************************************************************************ 函数名称:* computeHistGray()**说明:灰度图像统计直方图,m_histArray中存放了当前图像的统计数据***********************************************************************/void HistogramDrawDlg::computeHistGray(){ //只处理灰度图像 if(m_nBitCountOut!=8) return; //循环变量 int i,j; //直方图数组清0 for(i=0;i<256;i++) m_histArray[i]=0; //每行像素所占字节数 int lineByte=(m_himageDib.m_imgWidth*m_nBitCountOut/8+3)/4*4; //中间变量 int temp; //统计灰度直方图 for(i=0;i<m_imgHeightOut;i++){ for(j=0;j<m_imgWidthOut;j++){ temp=*(m_himageDib.m_pImgData+i*lineByte+j); m_histArray[temp]++; } }}/************************************************************************ 函数名称:* computeHistBrightness()**说明:彩色图像亮度直方图,m_histArray中存放了当前图像的亮度统计数据***********************************************************************/void HistogramDrawDlg::computeHistBrightness(){ //彩色图像有效 if(m_nBitCountOut!=24) return; //循环变量 int i,j; //直方图数组清0 for(i=0;i<256;i++) m_histArray[i]=0; //每行像素所占字节数 int lineByte=(m_imgWidthOut*m_nBitCountOut/8+3)/4*4; //中间变量 int temp; //统计亮度直方图 for(i=0;i<m_imgHeightOut;i++){ for(j=0;j<m_imgWidthOut;j++){ temp=(int)(0.11**(m_himageDib.m_pImgData+i*lineByte+j*3+0)+0.59**(m_himageDib.m_pImgData+i*lineByte+j*3+1)+0.30**(m_himageDib.m_pImgData+i*lineByte+j*3+2)+0.5); m_histArray[temp]++; } }}/************************************************************************ 函数名称:* computeAverage()**说明:计算直方图均值,直方图的统计特征***********************************************************************/float HistogramDrawDlg::computeAverage(){ int sum=0; for(int i=0;i<256;i++) sum+= i*m_histArray[i]; m_average=(float)sum/(m_himageDib.m_imgWidth*m_himageDib.m_imgHeight); float m_aver=m_average; return m_aver;}/************************************************************************ 函数名称:* computeDeviation()**说明:计算直方图方差,直方图的统计特征***********************************************************************/float HistogramDrawDlg::computeDeviation(){ float deviation=0; for(int i=0;i<256;i++) deviation += (i-m_average)*(i-m_average)*m_histArray[i]; deviation/=(m_himageDib.m_imgWidth*m_himageDib.m_imgHeight); m_deviation=sqrt(deviation); float m_devi=m_deviation; return m_devi;}void HistogramDrawDlg::histogramAve(){ // 只处理灰度 if(m_himageDib.m_nBitCount!=8) return; //释放旧的输出图像缓冲区 if(m_pImgDataOut!=NULL){ delete []m_pImgDataOut; m_pImgDataOut=NULL; } if(m_lpColorTableOut!=NULL){ delete []m_lpColorTableOut; m_lpColorTableOut=NULL; } //输出图像每像素位数与输入图像相同 m_nBitCountOut=m_himageDib.m_nBitCount; //计算颜色表长度 m_nColorTableLengthOut=m_himageDib.ComputeColorTabalLength(m_nBitCountOut); //若有颜色表,输入图像的颜色表与输出图像颜色表相同 if(m_nColorTableLengthOut!=0) { m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut]; memcpy(m_lpColorTableOut,m_himageDib.m_lpColorTable, sizeof(RGBQUAD)*m_nColorTableLengthOut); } //输出图像的宽高,与输入图像相等 m_imgWidthOut=m_himageDib.m_imgWidth; m_imgHeightOut=m_himageDib.m_imgHeight; //输出图像每行像素所占的字节数 int lineByteOut=(m_himageDib.m_imgWidth*m_nBitCountOut/8+3)/4*4; m_pImgDataOut=new unsigned char[lineByteOut*m_himageDib.m_imgHeight]; //循环变量 int i,j; //映射表 double Map[256]; //中间变量 int Sum,temp; //统计灰度直方图 computeHistGray(); //计算映射表 Sum=0; for(i=0;i<256;i++){ Sum+=m_histArray[i]; Map[i]=(double)Sum*255/(m_himageDib.m_imgWidth*m_himageDib.m_imgHeight)+0.5; } //输出数据赋值 for(i=0;i<m_himageDib.m_imgHeight;i++) { for(j=0;j<m_himageDib.m_imgWidth;j++) { temp = *(m_himageDib.m_pImgData+i*lineByteOut+j); *(m_pImgDataOut+i*lineByteOut+j) = (int)Map[temp]; } }}
运行截屏如下:
0 0
- (学习笔记6)BMP位图照片的灰度变换之直方图
- (学习笔记5)BMP位图照片的灰度变换之二值化
- (学习笔记4)BMP位图照片的几何变换
- 数字图像处理学习笔记(1)---位图的读写、几何变换、傅里叶变换、直方图均衡
- 数字图像处理学习笔记(1.0)---位图的读写、几何变换、傅里叶变换、直方图均衡
- 数字图像处理学习笔记(1.1)---位图的读写、几何变换、傅里叶变换、直方图均衡
- 数字图像处理学习笔记(1.2)---位图的读写、几何变换、傅里叶变换、直方图均衡
- 数字图像处理学习笔记(1.3)---位图的读写、几何变换、傅里叶变换、直方图均衡
- opencv学习笔记(九)-灰度直方图
- (学习笔记1)BMP位图的组成
- (学习笔记3)BMP位图的读取与显示
- 灰度图像直方图变换的一些代码
- OpenCV学习笔记(26)灰度直方图 练习
- OpenCV学习笔记(27) 灰度直方图均衡化 练习
- opencv学习笔记(二十七)实例:显示一张灰度图片的直方图
- opencv学习笔记---如何看懂照片的直方图
- Opencv2系列学习笔记4(灰度直方图)
- Opencv2系列学习笔记4(灰度直方图)
- POJ 2187 Beauty Contest
- 我眼中的自动化测试框架设计要点-要让QA不必去写代码
- 《Java程序设计基础》 第8章手记Part 2
- Servlet过滤器
- hdu1051(贪心)
- (学习笔记6)BMP位图照片的灰度变换之直方图
- C++中的private/protected/public
- Python爬虫学习笔记二:百度贴吧网页图片抓取
- POJ2251 - Dungeon Master
- 使用HTML和CSS实现大白
- 结构体成绩统计
- Python简易百度百科爬虫
- 泛型通配符
- 神奇的身高