⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mathmorphview.cpp

📁 visual c++数字图像与图形处理中的光盘内容
💻 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 + -