www.pudn.com > Wavelet2D.rar > Wavelet2DDlg.cpp


// Wavelet2DDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "Wavelet2D.h" 
#include "Wavelet2DDlg.h" 
#include "ColorTable.h" 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CAboutDlg dialog used for App About 
 
class CAboutDlg : public CDialog 
{ 
public: 
	CAboutDlg(); 
 
// Dialog Data 
	//{{AFX_DATA(CAboutDlg) 
	enum { IDD = IDD_ABOUTBOX }; 
	//}}AFX_DATA 
 
	// ClassWizard generated virtual function overrides 
	//{{AFX_VIRTUAL(CAboutDlg) 
	protected: 
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 
	//}}AFX_VIRTUAL 
 
// Implementation 
protected: 
	//{{AFX_MSG(CAboutDlg) 
	//}}AFX_MSG 
	DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
	//{{AFX_DATA_INIT(CAboutDlg) 
	//}}AFX_DATA_INIT 
} 
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CAboutDlg) 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
	//{{AFX_MSG_MAP(CAboutDlg) 
		// No message handlers 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CWavelet2DDlg dialog 
 
CWavelet2DDlg::CWavelet2DDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CWavelet2DDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CWavelet2DDlg) 
		// NOTE: the ClassWizard will add member initialization here 
	m_bWavelet = FALSE; 
	m_strBmpFile=_T("Sample.bmp"); 
	m_nDecomposeStage = 1; 
	m_nFilterLen      = 6; 
	//}}AFX_DATA_INIT 
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
	m_strFilterFile[0]="h1.dat"; 
	m_strFilterFile[1]="h2.dat";	 
	m_strFilterFile[2]="h3.dat"; 
	m_strFilterFile[3]="h4.dat"; 
	m_strFilterFile[4]="h5.dat"; 
	m_strFilterFile[5]="h6.dat"; 
	m_strFilterFile[6]="h7.dat"; 
	m_strFilterFile[7]="h8.dat"; 
	m_strFilterFile[8]="h9.dat"; 
	m_strFilterFile[9]="h10.dat"; 
 
	m_pBmpInfo = (BITMAPINFO *)malloc(2048); 
	if(m_pBmpInfo) 
	{ 
		m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
		m_pBmpInfo->bmiHeader.biWidth = m_nImageWidth; 
		m_pBmpInfo->bmiHeader.biHeight = m_nImageHeight; 
		m_pBmpInfo->bmiHeader.biPlanes = 1; 
		m_pBmpInfo->bmiHeader.biBitCount = 8; 
		m_pBmpInfo->bmiHeader.biCompression = BI_RGB; 
		m_pBmpInfo->bmiHeader.biSizeImage = 0; 
		m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0; 
		m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0; 
		m_pBmpInfo->bmiHeader.biClrUsed = 0; 
		m_pBmpInfo->bmiHeader.biClrImportant = 0; 
		for( int k = 0; k < 256; ++k){ 
			m_pBmpInfo->bmiColors[k].rgbBlue = (BYTE)k; 
			m_pBmpInfo->bmiColors[k].rgbGreen = (BYTE)k; 
			m_pBmpInfo->bmiColors[k].rgbRed = (BYTE)k; 
			m_pBmpInfo->bmiColors[k].rgbReserved	= 0; 
		} 
	} 
 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 
 
void CWavelet2DDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CWavelet2DDlg) 
	DDX_Control(pDX, IDC_EDIT_BMPFILE, m_editBmpFile); 
	DDX_Control(pDX, IDC_COMBO_FILTERLEN, m_combFilterLen); 
	DDX_Control(pDX, IDC_COMBO_DECOMPOSESTAGE, m_combDecomposeStage); 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CWavelet2DDlg, CDialog) 
	//{{AFX_MSG_MAP(CWavelet2DDlg) 
	ON_WM_SYSCOMMAND() 
	ON_WM_PAINT() 
	ON_WM_QUERYDRAGICON() 
	ON_BN_CLICKED(IDC_BUTTON_WAVELET2D, OnBtnWavelet2D) 
	ON_BN_CLICKED(IDC_BUTTON_BMPFILE, OnBtnBmpFile) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CWavelet2DDlg message handlers 
 
BOOL CWavelet2DDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	// Add "About..." menu item to system menu. 
 
	// IDM_ABOUTBOX must be in the system command range. 
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
	ASSERT(IDM_ABOUTBOX < 0xF000); 
 
	CMenu* pSysMenu = GetSystemMenu(FALSE); 
	if (pSysMenu != NULL) 
	{ 
		CString strAboutMenu; 
		strAboutMenu.LoadString(IDS_ABOUTBOX); 
		if (!strAboutMenu.IsEmpty()) 
		{ 
			pSysMenu->AppendMenu(MF_SEPARATOR); 
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
		} 
	} 
 
	// Set the icon for this dialog.  The framework does this automatically 
	//  when the application's main window is not a dialog 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	 
	// 初始化控件 
	m_editBmpFile.SetWindowText(m_strBmpFile); 
	CString strComb; 
	int k=0; 
	for(k=0;k<6;k++) 
	{  
	    strComb.Format("%d",k+1); 
	    m_combDecomposeStage.InsertString(k,strComb); 
        m_combDecomposeStage.SetItemData(k,k+1); 
        m_combDecomposeStage.SetCurSel(0); 
	} 
	for(k=0;k<10;k++) 
	{  
	    strComb.Format("%d",2*(k+1)); 
	    m_combFilterLen.InsertString(k,strComb); 
        m_combFilterLen.SetItemData(k,2*(k+1)); 
        m_combFilterLen.SetCurSel(2); 
	} 
	 
	return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
void CWavelet2DDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
	if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
	{ 
		CAboutDlg dlgAbout; 
		dlgAbout.DoModal(); 
	} 
	else 
	{ 
		CDialog::OnSysCommand(nID, lParam); 
	} 
} 
 
// If you add a minimize button to your dialog, you will need the code below 
//  to draw the icon.  For MFC applications using the document/view model, 
//  this is automatically done for you by the framework. 
 
void CWavelet2DDlg::OnPaint()  
{ 
	if (IsIconic()) 
	{ 
		CPaintDC dc(this); // device context for painting 
 
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
 
		// Center icon in client rectangle 
		int cxIcon = GetSystemMetrics(SM_CXICON); 
		int cyIcon = GetSystemMetrics(SM_CYICON); 
		CRect rect; 
		GetClientRect(&rect); 
		int x = (rect.Width() - cxIcon + 1) / 2; 
		int y = (rect.Height() - cyIcon + 1) / 2; 
 
		// Draw the icon 
		dc.DrawIcon(x, y, m_hIcon); 
	} 
	else 
	{ 
		if(m_bWavelet) 
		   OnBtnWavelet2D(); 
		CDialog::OnPaint(); 
	} 
} 
 
// The system calls this to obtain the cursor to display while the user drags 
//  the minimized window. 
HCURSOR CWavelet2DDlg::OnQueryDragIcon() 
{ 
	return (HCURSOR) m_hIcon; 
} 
 
// 选择原始数据图像文件 
void CWavelet2DDlg::OnBtnBmpFile()  
{ 
	CFileDialog BmpFileDlg(TRUE,"bmp","*.bmp"); 
	if(BmpFileDlg.DoModal()==IDOK) 
	{ 
	   m_bWavelet=FALSE; 
		m_strBmpFile=BmpFileDlg.GetPathName(); 
	   m_editBmpFile.SetWindowText(m_strBmpFile); 
	}	 
} 
 
// “二维小波变换”按钮消息处理函数 
// 功能:打开文件,分配内存,进行变换,绘制结果 
void CWavelet2DDlg::OnBtnWavelet2D()  
{ 
	CFile BmpFile; 
	CFileException fe; 
	// 打开原始图像数据 
	if(m_strBmpFile.IsEmpty()) 
	{	 
		AfxMessageBox (_T("请选择一个位图(*.bmp)文件!"),MB_ICONINFORMATION|MB_OK,NULL); 
	    return; 
	} 
	if(!BmpFile.Open(m_strBmpFile,CFile::modeRead,&fe)) 
	{	 
		AfxMessageBox (_T("打开文件失败!"),MB_ICONINFORMATION|MB_OK,NULL); 
	    return; 
	} 
	// 读取原始数据图像文件 
	TRY 
	{ 
		DIB = ::ReadDIBFile(BmpFile); 
	} 
	CATCH (CFileException, eLoad) 
	{		 
		BmpFile.Abort();	// 读取失败			 
		AfxMessageBox (_T("读取数据失败!"),MB_ICONINFORMATION|MB_OK,NULL);		 
		DIB = NULL;         // 设置DIB为空 
		return ; 
	} 
	END_CATCH	 
     
	// 锁定DIB 
	lpDIB = (LPSTR)::GlobalLock((HGLOBAL)GetHDIB()); 
	// 得到图像宽度和高度 
	m_nImageWidth=::DIBWidth(lpDIB); 
	m_nImageHeight=::DIBHeight(lpDIB); 
 
	// 打开待处理图像 
	// 判断是否是8-bpp位图 
	if (::DIBNumColors(lpDIB) > 256||m_nImageWidth>400||m_nImageHeight>400) 
	{ 
		// 提示用户 
		AfxMessageBox(_T("不是256色位图或者图像过大!") , MB_ICONINFORMATION | MB_OK,NULL); 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) GetHDIB()); 
		return; 
	} 
 
	// 更改光标形状 
	BeginWaitCursor(); 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	// 得到小波变换所需的层次、滤波器长度等参数 
	GetParam();	 
	// 获取滤波器参数 
	if(!GetHn()) 
		return; 
    // 绘制原始图像 
    DrawOriginalBmp(); 
    // 给image数组分配内存 
	if(!GetMemory())	 
		return; 
	// 将图像数据读入image数组 
	for(int i=0;i>level; 
	 m=m_nFilterLen/2; 
	 if((ph=new double[sizeof(double)*len])==NULL) 
	 { 
	    AfxMessageBox("H算子内存分配失败!",MB_OK|MB_ICONINFORMATION); 
		return FALSE; 
	 } 
	 for(sign=0;sign>level; 
	 m=m_nFilterLen/2; 
	 if((pg=new double[sizeof(double)*len])==NULL) 
	 { 
	    AfxMessageBox("G算子内存分配失败!",MB_OK|MB_ICONINFORMATION); 
		return FALSE; 
	 } 
	 for(sign=0;sign>1; 
	 for(i=0;ifilterlen) 
		 { 
		    for(k=i2-len;k<=i2-len+m;k++) 
			{ 
			    if((k>=0)&&(k=0)&&(k=0)&&(k>1; 
	 for(i=0;ifilterlen) 
		 { 
		    for(k=i2-len;k<=i2-len+m;k++) 
			{ 
			    if((k>=0)&&(k=0)&&(k=0)&&(k>1; 
	 for(i=0;ifilterlen) 
		 { 
		    for(k=i2-len;k<=i2-len+m+2;k++) 
			{ 
			    if((k>=0)&&(k=0)&&(k=0)&&(k>1; 
	 for(i=0;ifilterlen) 
		 { 
		    for(k=i2-len;k<=i2-len+m+2;k++) 
			{ 
			    if((k>=0)&&(k=0)&&(k=0)&&(k>stage; 
	 start=len*numx; 
	 end=start+len; 
	 HOperatorOnRow(filterlen,start,len,row); // H算子作用于行 
	 GOperatorOnRow(filterlen,start,len,row); // G算子作用于行 
	 for(i=start;i>stage; 
	 start=len*numx; 
	 end=start+len; 
	 HOperatorOnCol(filterlen,start,len,col);  // H算子作用于列 
	 GOperatorOnCol(filterlen,start,len,col);  // G算子作用于列 
	 for(i=start;i>stage);row++) 
			 { 
			     DecompStageRow(row,stage,0);   
			 } 
	     if(ph&&pg)      // 释放资源 
		 { 
		    delete  ph; 
			delete  pg; 
			ph=NULL; 
			pg=NULL; 
		 } 
    	 // 初始化H算子和G算子 
		 if((!HHH(stage,m_nImageHeight))||(!GGG(stage,m_nImageHeight))) 
			 break; 
		 else 
			 // 逐列变换 
			 for(col=0;col<(m_nImageWidth>>stage);col++) 
			 { 
			     DecompStageCol(col,stage,0); 
			 } 
         if(ph&&pg)      // 释放资源 
		 { 
		    delete  ph; 
			delete  pg; 
			ph=NULL; 
			pg=NULL; 
		 } 
	 } 
} 
 
// 绘制原始图像 
void CWavelet2DDlg::DrawOriginalBmp() 
{ 
	// 得到客户区 
	CDC* pDC=GetDC(); 
    CRect RectClient,Workarea; 
    GetClientRect(RectClient); 
	 
	// 锁定DIB 
	lpDIB = (LPSTR)::GlobalLock((HGLOBAL) GetHDIB()); 
 
    // 在对话框右上部分创建绘制原始图像区域 
	Workarea.left=RectClient.left+(RectClient.right-RectClient.left)/5*2; 
    Workarea.right=RectClient.right-10; 
    Workarea.top=RectClient.top+10; 
	Workarea.bottom=RectClient.top+(RectClient.bottom-RectClient.top-10)/2; 
 
	// 设置区域背景色为白色 
	pDC->Rectangle(Workarea); 
    pDC->SetBkColor(0x00FFFFFF);	 
 
	// 绘制原始图像 
	m_pBmpInfo->bmiHeader.biWidth = m_nImageWidth; 
    m_pBmpInfo->bmiHeader.biHeight = m_nImageHeight; 
	::StretchDIBits(pDC->GetSafeHdc(), Workarea.left+1, Workarea.top+1, Workarea.Width(),Workarea.Height(),//m_nImageWidth, m_nImageHeight, 
	                0, 0, m_nImageWidth, m_nImageHeight, (unsigned char *)lpDIBBits, 
					(LPBITMAPINFO) m_pBmpInfo, DIB_RGB_COLORS, SRCCOPY);	 
    // 解除锁定 
	::GlobalUnlock((HGLOBAL)GetHDIB()); 
 
} 
 
// 绘制二维小波变换后图像 
void CWavelet2DDlg::DrawWavelet2D() 
{ 
	// 找到图像变换后数据中的最大最小值 
	double min=image[0][0],max=0; 
    for(int a=0;a10000) 
			   image[a][b]=max; 
		   if(image[a][b]<-10000) 
			   image[a][b]=min; 
		   if(maximage[a][b]) 
	          min=image[a][b]; 
	   } 
 
    // 将图像变换后数据归一化到256级灰度 
	for(int m=0;mRectangle(Workarea); 
    pDC->SetBkColor(0x00FFFFFF); 
 
	// 绘制原始图像 
	m_pBmpInfo->bmiHeader.biWidth = m_nImageWidth; 
    m_pBmpInfo->bmiHeader.biHeight = m_nImageHeight; 
	::StretchDIBits(pDC->GetSafeHdc(), Workarea.left+1, Workarea.top+1, Workarea.Width(),Workarea.Height(),//m_nImageWidth, m_nImageHeight, 
	                0, 0, m_nImageWidth, m_nImageHeight, (unsigned char *)lpDIBBits, 
					(LPBITMAPINFO) m_pBmpInfo, DIB_RGB_COLORS, SRCCOPY);	 
 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL)GetHDIB()); 
} 
 
// 得到小波变换所需的层次、滤波器长度等参数 
void CWavelet2DDlg::GetParam() 
{ 
	// 得到待分解层次信息 
	if(m_combDecomposeStage.GetCurSel()==CB_ERR) 
	   m_nDecomposeStage=1; 
	else 
   	   m_nDecomposeStage=m_combDecomposeStage.GetItemData(m_combDecomposeStage.GetCurSel()); 
		 
	// 得到滤波器长度 
	if(m_combFilterLen.GetCurSel()==CB_ERR) 
	   m_nFilterLen=6; 
	else 
	   m_nFilterLen=m_combFilterLen.GetItemData(m_combFilterLen.GetCurSel()); 
}