显示图像直方图

Technorati 标签: VC,直方图

显示图像直方图步骤:

1、 点击ResourceView,右键点击Dialog,选Insert Dialog 在属性对话框中将ID改为ID_HIST,对话框名称改为“直方图”

2、 在工具栏中点“插入”-“新建类”,输入类名,并选Base Class为CDialog,Dialog ID为ID_HIST。这样就将对话框和类联系起来了,在该对话框中拖入一Edit控件,将其ID设为IDC_HISTSHOW;

3、 快捷键“Ctrl+W”,出现MFC ClassWizard对话框,在Messages栏中分别选WM_INITDIALOG和WM_Paint,再点击“Add Function”,即将对话框初始化和画图函数加入对话框类之中。

4、 在Hist.h文件“public:”下面输入如下变量定义: LONG m_lCount[256]; char* m_lpDIBBits; LONG m_lWidth; LONG m_lHeight; int m_iIsDraging; CDlgIntensity(CWnd* pParent = NULL);

5、 打开Hist.cpp程序,在CHist::OnInitDialog()函数中“// TODO: Add extra initialization here”前将如下代码拷贝进去: unsigned char* lpSrc; LONG i; LONG j;

6、 在“// TODO: Add extra initialization here”后将如下代码拷贝进去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CWnd* pWnd=GetDlgItem(IDC_HISTSHOW);
 
 
 CRect rect;
 GetClientRect(rect);
 ClientToScreen(&rect);
 
 for(i=0;i<256;i++)
 {
  m_lCount[i]=0;
 }
 
 LONG lLineBytes;
 
 lLineBytes=WIDTHBYTES(m_lWidth*8);
 
 for(i=0;i<m_lHeight;i++)
 {
  for(j=0;j<m_lWidth;j++)
  {
   lpSrc=(unsigned char*)m_lpDIBBits+lLineBytes*i+j;
 
   m_lCount[*(lpSrc)]++;
  }
 }
 
 m_iIsDraging=0;

 

7、在CHist::OnPaint()函数“CPaintDC dc(this);”前将如下代码拷如其中: CString str; LONG i; LONG lMaxCount=0; LONG m_iLowGray=0; LONG m_iUpGray=255; 在CHist::OnPaint()函数“// TODO: Add your message handler code here”后将如下代码拷如其中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
CWnd* pWnd=GetDlgItem(IDC_ HISTSHOW);
 
 CDC* pDC=pWnd->GetDC();
 pWnd->Invalidate();
 pWnd->UpdateWindow();
 
 pDC->Rectangle(0,0,330,300);
 
 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_SOLID,1,RGB(0,255,0));
 
 CGdiObject* pOldPen=pDC->SelectObject(pPenRed);
 
 pDC->MoveTo(10,10);
 
 pDC->LineTo(10,280);
 
 pDC->LineTo(320,280);
 
 str.Format("0");
 pDC->TextOut(10,283,str);
 str.Format("50");
 pDC->TextOut(60,283,str);
 str.Format("100");
 pDC->TextOut(110,283,str);
 str.Format("150");
 pDC->TextOut(160,283,str);
 str.Format("200");
 pDC->TextOut(210,283,str);
 str.Format("255");
 pDC->TextOut(265,283,str);
 
 for(i=0;i<256;i+=5)
 {
  if((i&1)==0)
  {
   pDC->MoveTo(i+10,280);
   pDC->LineTo(i+10,284);
  }
  else
  {
   pDC->MoveTo(i+10,280);
   pDC->LineTo(i+10,282);
  }
 }
 
    pDC->MoveTo(315,275);
 pDC->LineTo(320,280);
 pDC->LineTo(315,285);
 
 pDC->MoveTo(10,10);
 pDC->LineTo(5,15);
 pDC->MoveTo(10,10);
 pDC->LineTo(15,15);
 
 for(i=m_iLowGray;i<=m_iUpGray;i++)
 {
  if(m_lCount[i]>lMaxCount)
  {
   lMaxCount=m_lCount[i];
  }
 }
 
 pDC->MoveTo(10,25);
 pDC->LineTo(14,25);
 str.Format("%d",lMaxCount);
 pDC->TextOut(11,26,str);
 
 pDC->SelectObject(pPenGreen);
 
 pDC->MoveTo(m_iLowGray+10,25);
 pDC->LineTo(m_iLowGray+10,280);
 
 pDC->MoveTo(m_iUpGray+10,25);
 pDC->LineTo(m_iUpGray+10,280);
 
 pDC->SelectObject(pPenBlue);
 
 if(lMaxCount>0)
 {
  for(i=m_iLowGray;i<=m_iUpGray;i++)
  {
   pDC->MoveTo(i+10,280);
   pDC->LineTo(i+10,281-(int)(m_lCount[i]*256/lMaxCount));
  }
 }
 
 pDC->SelectObject(pOldPen);
 
 delete pPenRed;
 delete pPenBlue;
 delete pPenGreen;

 

8、点开ResourceView中的Menu,出现IDR_MAINFRAME和 IDR_MY111TYPE,双击IDR_MY111TYPE就出现了程序界面,有文件、编辑、查看、窗口、帮助按钮。点“查看”下面的虚线框右键——点“属性”,输入标题(直方图),和ID(大写英文,如ID_VIEW_HIST),这样就将按钮和程序通过ID联系起来了,点击该按钮,就会执行相应的程序。下面为该按钮添加函数:点Ctrl+W ,出现MFC ClassWizard对话框,选Class name为CMy111View,在Object IDs对应的选项中选中设置的ID(如为ID_VIEW_HIST),在Messages选项中选中COMMAND,然后点击“Add Function”按钮,选默认设置,就为ID_VIEW_HIST添加了相应的函数OnViewHist()。该函数在111View.cpp文件中定义,在函数void CMy111View:: OnViewHist()添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// TODO: Add your command handler code here
 CMy111Doc* pDoc=GetDocument();
 
 if(pDoc->m_hDIB==NULL)
 {
  MessageBox("请先打开一幅256色的BMP图像!","系统提示",MB_ICONINFORMATION|MB_OK);
  return;
 }
 
 LPSTR lpDIB;
 LPSTR lpDIBBits;
 
 lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
 
 lpDIBBits=::FindDIBBits(lpDIB);
 
 if(::DIBNumColors(lpDIB)!=256)
 {
  MessageBox("目前只支持查看256色位图灰度直方图!","系统提示",MB_ICONINFORMATION|MB_OK);
 
  ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
 
  return;
 }
 
 BeginWaitCursor();
 
 CHist dlgPara;
 
 dlgPara.m_lpDIBBits=lpDIBBits;
 dlgPara.m_lWidth=::DIBWidth(lpDIB);
 dlgPara.m_lHeight=::DIBHeight(lpDIB);
// dlgPara.m_iLowGray=0;
// dlgPara.m_iUpGray=255;
 
 if(dlgPara.DoModal()!=IDOK)
 {
  return;
 }
 
 ::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
 
 EndWaitCursor();
posted @   微笑的艾米  阅读(1008)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示