📄 mathmorphview.cpp
字号:
// MathMorphView.cpp : implementation of the CMathMorphView class
//
#include "stdafx.h"
#include "MathMorph.h"
#include "MathMorphDoc.h"
#include "MathMorphView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "MathMorphology.h"
#include "MathmorphDialog.h"
/////////////////////////////////////////////////////////////////////////////
// CMathMorphView
IMPLEMENT_DYNCREATE(CMathMorphView, CView)
BEGIN_MESSAGE_MAP(CMathMorphView, CView)
//{{AFX_MSG_MAP(CMathMorphView)
ON_COMMAND(IDM_MATH_MORPH, OnMathMorph)
ON_UPDATE_COMMAND_UI(IDM_MATH_MORPH, OnUpdateMathMorph)
ON_COMMAND(IDM_IMAGE_RESTORE, OnImageRestore)
ON_UPDATE_COMMAND_UI(IDM_IMAGE_RESTORE, OnUpdateImageRestore)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMathMorphView construction/destruction
CMathMorphView::CMathMorphView()
{
// TODO: add construction code here
m_nWidth = 800;
m_nHeight = 600;
m_bMathmorph = FALSE;
m_nOperation = 0;
}
CMathMorphView::~CMathMorphView()
{
}
BOOL CMathMorphView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMathMorphView drawing
void CMathMorphView::OnDraw(CDC* pDC)
{
CMathMorphDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CDib* pDib = pDoc->m_pDib;
if(pDib)
{
BeginWaitCursor();
m_nWidth = (int)pDib->GetWidth();
m_nHeight = (int)pDib->GetHeight();
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap ddb;
ddb.CreateCompatibleBitmap(pDC,m_nWidth,m_nHeight);
CBitmap* pOldBitmap = memDC.SelectObject(&ddb);
pDib->Draw(memDC.m_hDC,0,0,m_nWidth,m_nHeight,
0,0,m_nWidth,m_nHeight,DIB_RGB_COLORS,SRCCOPY);
if(!m_bMathmorph)
pDC->BitBlt(0,0,m_nWidth,m_nHeight,&memDC,0,0,SRCCOPY);
else
Morph(pDC,pDib,0,0,m_nWidth,m_nHeight);//Morph(pDC,pDib,100,100,100,100);
memDC.SelectObject(pOldBitmap);
ddb.DeleteObject();
EndWaitCursor();
}
}
/////////////////////////////////////////////////////////////////////////////
// CMathMorphView diagnostics
#ifdef _DEBUG
void CMathMorphView::AssertValid() const
{
CView::AssertValid();
}
void CMathMorphView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMathMorphDoc* CMathMorphView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMathMorphDoc)));
return (CMathMorphDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
void CMathMorphView::Morph(CDC *pDC, CDib *pDib, int x, int y, int nWidth, int nHeight)
{
ASSERT(pDib);
//限制处理的区域----防止任意填写数据而使用访问无效
if((x > (m_nWidth - 1)) || (y > (m_nHeight - 1))) return ;
//实际处理的宽度和高度
int w = min(nWidth,m_nWidth - x);
int h = min(nHeight,m_nHeight - y);
// 32位颜色数据
DWORD dwSize = m_nWidth * m_nHeight * 4;
//分配全局内存 32位源数据
BYTE* pbyBits32 = new BYTE[dwSize];
if(pbyBits32 == 0) return;
memset(pbyBits32, 0, dwSize);
//CDib类只提供了一个全部数据的函数
pDib->GetDdbData32(pbyBits32);
//形态学处理
CMathMorphology* mm = new CMathMorphology();
//膨胀,腐蚀,开启,关闭,开合成
//也用于水彩画,去噪声,晶化,不能用于形态学梯度
if((m_nOperation < 4) || (m_nOperation == 6) || (m_nOperation == 7))
{
MORPHOLOGYELEMENT* aME = new MORPHOLOGYELEMENT[9];
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
aME[i * 3 + j].x = j;
aME[i * 3 + j].y = i;
aME[i * 3 + j].blue = aME[i * 3 + j].green = aME[i * 3 + j].red = 0;
}
}
mm->SetMorphologyElement(aME,9);
delete[] aME;
}
//用于形态浮雕(提取边缘),检测边界
else if(m_nOperation == 4)
{
/*
MORPHOLOGYELEMENT* aME = new MORPHOLOGYELEMENT[9];
for(int i = 0;i < 3;i++)
for(int j = 0;j < 3;j++)
{
aME[i * 3 + j].x = j;
aME[i * 3 + j].y = i;
}
aME[0].red = aME[1].red = aME[2].red = 64;
aME[0].green = aME[1].green = aME[2].green = 64;
aME[0].blue = aME[1].blue = aME[2].blue = 64;
aME[6].red = aME[7].red = aME[8].red = -64;
aME[6].green = aME[7].green = aME[8].green = -64;
aME[6].blue = aME[7].blue = aME[8].blue = -64;
aME[3].red = aME[5].red = 0;
aME[3].green = aME[5].green = 0;
aME[3].blue = aME[5].blue = 0;
aME[4].red = aME[4].green = aME[4].blue = 128;
mm->SetMorphologyElement(aME,9);
delete[] aME;
*/
/*
MORPHOLOGYELEMENT* aME = new MORPHOLOGYELEMENT[169];
for(int i = 0;i < 13;i++)
for(int j = 0;j < 13;j++)
{
aME[i * 13 + j].x = j;
aME[i * 13 + j].y = i;
aME[i * 13 + j].red = aME[i * 13 + j].green = aME[i * 13 + j].blue = 0;
}
aME[84].red = 128;
aME[84].green = 128;
aME[84].blue = 128;
mm->SetMorphologyElement(aME,169);
delete[] aME;*/
MORPHOLOGYELEMENT* aME = new MORPHOLOGYELEMENT[81];
for(int i = 0;i < 9;i++)
for(int j = 0;j < 9;j++)
{
aME[i * 9 + j].x = j;
aME[i * 9 + j].y = i;
aME[i * 9 + j].red = aME[i * 9 + j].green = aME[i * 9 + j].blue = 0;
}
aME[40].red = 128;
aME[40].green = 128;
aME[40].blue = 128;
mm->SetMorphologyElement(aME,81);
delete[] aME;
}
//用于形态梯化,还可用于提取边缘,平滑和降低噪声
else if(m_nOperation == 5)
{
MORPHOLOGYELEMENT* aME = new MORPHOLOGYELEMENT[9];
for(int i = 0;i < 3;i++)
for(int j = 0;j < 3;j++)
{
aME[i * 3 + j].x = j - 1;
aME[i * 3 + j].y = i - 1;
aME[i * 3 + j].blue = aME[i * 3 + j].green = aME[i * 3 + j].red = 0;
}
/*
aME[0].red = aME[2].red = aME[6].red = aME[8].red = 32;
aME[0].green = aME[2].green = aME[6].green = aME[8].green = 32;
aME[0].blue = aME[2].blue = aME[6].blue = aME[8].blue = 32;
aME[1].red = aME[3].red = aME[5].red = aME[7].red = -32;
aME[1].green = aME[3].green = aME[5].green = aME[7].green = -32;
aME[1].blue = aME[3].blue = aME[5].blue = aME[7].blue = -32;
aME[4].red = aME[4].green = aME[4].blue = 80;
*/
mm->SetMorphologyElement(aME,9);
delete[] aME;
}
if(m_nOperation == 0)
mm->Dilate(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 1)
mm->Erode(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 2)
mm->Open(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 3)
mm->Close(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 4)
mm->PickEdge(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 5)
mm->Gradientize(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 6)
mm->OpenCompose(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
else if(m_nOperation == 7)
mm->Denoise(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
//mm->TopHat(pbyBits32,x,y,w,h,m_nWidth,m_nHeight);
CClientDC dc(this);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
HBITMAP hBitmap = mm->CreateDdb(pDC->m_hDC,m_nWidth,m_nHeight,pbyBits32);
HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hBitmap);
pDC->BitBlt(0,0,m_nWidth,m_nHeight,&memDC,0,0,SRCCOPY);
::DeleteObject(hBitmap);
memDC.SelectObject(hOldBitmap);
delete mm;
delete[] pbyBits32;
ReleaseDC(&dc);
}
// CMathMorphView message handlers
void CMathMorphView::OnMathMorph()
{
// TODO: Add your command handler code here
CMathmorphDialog dlg;
dlg.m_nOperation = m_nOperation;
int responeDlg = dlg.DoModal();
if(responeDlg == IDOK)
{
m_bMathmorph = TRUE;
m_nOperation = dlg.m_nOperation;
Invalidate();
}
}
void CMathMorphView::OnUpdateMathMorph(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_bMathmorph)
pCmdUI ->SetCheck(TRUE);
else
pCmdUI ->SetCheck(FALSE);
}
void CMathMorphView::OnImageRestore()
{
// TODO: Add your command handler code here
m_bMathmorph = FALSE;
Invalidate();
}
void CMathMorphView::OnUpdateImageRestore(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(!m_bMathmorph)
pCmdUI ->SetCheck(TRUE);
else
pCmdUI ->SetCheck(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -