显示图像直方图
显示图像直方图步骤:
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(); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述