Wavelet2DDlg.cpp
上传用户:whhgrj
上传日期:2013-03-18
资源大小:169k
文件大小:19k
源码类别:

波变换

开发平台:

Visual C++

  1. // Wavelet2DDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Wavelet2D.h"
  5. #include "Wavelet2DDlg.h"
  6. #include "ColorTable.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CAboutDlg dialog used for App About
  14. class CAboutDlg : public CDialog
  15. {
  16. public:
  17. CAboutDlg();
  18. // Dialog Data
  19. //{{AFX_DATA(CAboutDlg)
  20. enum { IDD = IDD_ABOUTBOX };
  21. //}}AFX_DATA
  22. // ClassWizard generated virtual function overrides
  23. //{{AFX_VIRTUAL(CAboutDlg)
  24. protected:
  25. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  26. //}}AFX_VIRTUAL
  27. // Implementation
  28. protected:
  29. //{{AFX_MSG(CAboutDlg)
  30. //}}AFX_MSG
  31. DECLARE_MESSAGE_MAP()
  32. };
  33. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  34. {
  35. //{{AFX_DATA_INIT(CAboutDlg)
  36. //}}AFX_DATA_INIT
  37. }
  38. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  39. {
  40. CDialog::DoDataExchange(pDX);
  41. //{{AFX_DATA_MAP(CAboutDlg)
  42. //}}AFX_DATA_MAP
  43. }
  44. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  45. //{{AFX_MSG_MAP(CAboutDlg)
  46. // No message handlers
  47. //}}AFX_MSG_MAP
  48. END_MESSAGE_MAP()
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CWavelet2DDlg dialog
  51. CWavelet2DDlg::CWavelet2DDlg(CWnd* pParent /*=NULL*/)
  52. : CDialog(CWavelet2DDlg::IDD, pParent)
  53. {
  54. //{{AFX_DATA_INIT(CWavelet2DDlg)
  55. // NOTE: the ClassWizard will add member initialization here
  56. m_bWavelet = FALSE;
  57. m_strBmpFile=_T("Sample.bmp");
  58. m_nDecomposeStage = 1;
  59. m_nFilterLen      = 6;
  60. //}}AFX_DATA_INIT
  61. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  62. m_strFilterFile[0]="h1.dat";
  63. m_strFilterFile[1]="h2.dat";
  64. m_strFilterFile[2]="h3.dat";
  65. m_strFilterFile[3]="h4.dat";
  66. m_strFilterFile[4]="h5.dat";
  67. m_strFilterFile[5]="h6.dat";
  68. m_strFilterFile[6]="h7.dat";
  69. m_strFilterFile[7]="h8.dat";
  70. m_strFilterFile[8]="h9.dat";
  71. m_strFilterFile[9]="h10.dat";
  72. m_pBmpInfo = (BITMAPINFO *)malloc(2048);
  73. if(m_pBmpInfo)
  74. {
  75. m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  76. m_pBmpInfo->bmiHeader.biWidth = m_nImageWidth;
  77. m_pBmpInfo->bmiHeader.biHeight = m_nImageHeight;
  78. m_pBmpInfo->bmiHeader.biPlanes = 1;
  79. m_pBmpInfo->bmiHeader.biBitCount = 8;
  80. m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
  81. m_pBmpInfo->bmiHeader.biSizeImage = 0;
  82. m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
  83. m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
  84. m_pBmpInfo->bmiHeader.biClrUsed = 0;
  85. m_pBmpInfo->bmiHeader.biClrImportant = 0;
  86. for( int k = 0; k < 256; ++k){
  87. m_pBmpInfo->bmiColors[k].rgbBlue = (BYTE)k;
  88. m_pBmpInfo->bmiColors[k].rgbGreen = (BYTE)k;
  89. m_pBmpInfo->bmiColors[k].rgbRed = (BYTE)k;
  90. m_pBmpInfo->bmiColors[k].rgbReserved = 0;
  91. }
  92. }
  93. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  94. }
  95. void CWavelet2DDlg::DoDataExchange(CDataExchange* pDX)
  96. {
  97. CDialog::DoDataExchange(pDX);
  98. //{{AFX_DATA_MAP(CWavelet2DDlg)
  99. DDX_Control(pDX, IDC_EDIT_BMPFILE, m_editBmpFile);
  100. DDX_Control(pDX, IDC_COMBO_FILTERLEN, m_combFilterLen);
  101. DDX_Control(pDX, IDC_COMBO_DECOMPOSESTAGE, m_combDecomposeStage);
  102. //}}AFX_DATA_MAP
  103. }
  104. BEGIN_MESSAGE_MAP(CWavelet2DDlg, CDialog)
  105. //{{AFX_MSG_MAP(CWavelet2DDlg)
  106. ON_WM_SYSCOMMAND()
  107. ON_WM_PAINT()
  108. ON_WM_QUERYDRAGICON()
  109. ON_BN_CLICKED(IDC_BUTTON_WAVELET2D, OnBtnWavelet2D)
  110. ON_BN_CLICKED(IDC_BUTTON_BMPFILE, OnBtnBmpFile)
  111. //}}AFX_MSG_MAP
  112. END_MESSAGE_MAP()
  113. /////////////////////////////////////////////////////////////////////////////
  114. // CWavelet2DDlg message handlers
  115. BOOL CWavelet2DDlg::OnInitDialog()
  116. {
  117. CDialog::OnInitDialog();
  118. // Add "About..." menu item to system menu.
  119. // IDM_ABOUTBOX must be in the system command range.
  120. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  121. ASSERT(IDM_ABOUTBOX < 0xF000);
  122. CMenu* pSysMenu = GetSystemMenu(FALSE);
  123. if (pSysMenu != NULL)
  124. {
  125. CString strAboutMenu;
  126. strAboutMenu.LoadString(IDS_ABOUTBOX);
  127. if (!strAboutMenu.IsEmpty())
  128. {
  129. pSysMenu->AppendMenu(MF_SEPARATOR);
  130. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  131. }
  132. }
  133. // Set the icon for this dialog.  The framework does this automatically
  134. //  when the application's main window is not a dialog
  135. SetIcon(m_hIcon, TRUE); // Set big icon
  136. SetIcon(m_hIcon, FALSE); // Set small icon
  137. // 初始化控件
  138. m_editBmpFile.SetWindowText(m_strBmpFile);
  139. CString strComb;
  140. int k=0;
  141. for(k=0;k<6;k++)
  142.     strComb.Format("%d",k+1);
  143.     m_combDecomposeStage.InsertString(k,strComb);
  144.         m_combDecomposeStage.SetItemData(k,k+1);
  145.         m_combDecomposeStage.SetCurSel(0);
  146. }
  147. for(k=0;k<10;k++)
  148.     strComb.Format("%d",2*(k+1));
  149.     m_combFilterLen.InsertString(k,strComb);
  150.         m_combFilterLen.SetItemData(k,2*(k+1));
  151.         m_combFilterLen.SetCurSel(2);
  152. }
  153. return TRUE;  // return TRUE  unless you set the focus to a control
  154. }
  155. void CWavelet2DDlg::OnSysCommand(UINT nID, LPARAM lParam)
  156. {
  157. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  158. {
  159. CAboutDlg dlgAbout;
  160. dlgAbout.DoModal();
  161. }
  162. else
  163. {
  164. CDialog::OnSysCommand(nID, lParam);
  165. }
  166. }
  167. // If you add a minimize button to your dialog, you will need the code below
  168. //  to draw the icon.  For MFC applications using the document/view model,
  169. //  this is automatically done for you by the framework.
  170. void CWavelet2DDlg::OnPaint() 
  171. {
  172. if (IsIconic())
  173. {
  174. CPaintDC dc(this); // device context for painting
  175. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  176. // Center icon in client rectangle
  177. int cxIcon = GetSystemMetrics(SM_CXICON);
  178. int cyIcon = GetSystemMetrics(SM_CYICON);
  179. CRect rect;
  180. GetClientRect(&rect);
  181. int x = (rect.Width() - cxIcon + 1) / 2;
  182. int y = (rect.Height() - cyIcon + 1) / 2;
  183. // Draw the icon
  184. dc.DrawIcon(x, y, m_hIcon);
  185. }
  186. else
  187. {
  188. if(m_bWavelet)
  189.    OnBtnWavelet2D();
  190. CDialog::OnPaint();
  191. }
  192. }
  193. // The system calls this to obtain the cursor to display while the user drags
  194. //  the minimized window.
  195. HCURSOR CWavelet2DDlg::OnQueryDragIcon()
  196. {
  197. return (HCURSOR) m_hIcon;
  198. }
  199. // 选择原始数据图像文件
  200. void CWavelet2DDlg::OnBtnBmpFile() 
  201. {
  202. CFileDialog BmpFileDlg(TRUE,"bmp","*.bmp");
  203. if(BmpFileDlg.DoModal()==IDOK)
  204. {
  205.    m_bWavelet=FALSE;
  206. m_strBmpFile=BmpFileDlg.GetPathName();
  207.    m_editBmpFile.SetWindowText(m_strBmpFile);
  208. }
  209. }
  210. // “二维小波变换”按钮消息处理函数
  211. // 功能:打开文件,分配内存,进行变换,绘制结果
  212. void CWavelet2DDlg::OnBtnWavelet2D() 
  213. {
  214. CFile BmpFile;
  215. CFileException fe;
  216. // 打开原始图像数据
  217. if(m_strBmpFile.IsEmpty())
  218. {
  219. AfxMessageBox (_T("请选择一个位图(*.bmp)文件!"),MB_ICONINFORMATION|MB_OK,NULL);
  220.     return;
  221. }
  222. if(!BmpFile.Open(m_strBmpFile,CFile::modeRead,&fe))
  223. {
  224. AfxMessageBox (_T("打开文件失败!"),MB_ICONINFORMATION|MB_OK,NULL);
  225.     return;
  226. }
  227. // 读取原始数据图像文件
  228. TRY
  229. {
  230. DIB = ::ReadDIBFile(BmpFile);
  231. }
  232. CATCH (CFileException, eLoad)
  233. {
  234. BmpFile.Abort(); // 读取失败
  235. AfxMessageBox (_T("读取数据失败!"),MB_ICONINFORMATION|MB_OK,NULL);
  236. DIB = NULL;         // 设置DIB为空
  237. return ;
  238. }
  239. END_CATCH
  240.     
  241. // 锁定DIB
  242. lpDIB = (LPSTR)::GlobalLock((HGLOBAL)GetHDIB());
  243. // 得到图像宽度和高度
  244. m_nImageWidth=::DIBWidth(lpDIB);
  245. m_nImageHeight=::DIBHeight(lpDIB);
  246. // 打开待处理图像
  247. // 判断是否是8-bpp位图
  248. if (::DIBNumColors(lpDIB) > 256||m_nImageWidth>400||m_nImageHeight>400)
  249. {
  250. // 提示用户
  251. AfxMessageBox(_T("不是256色位图或者图像过大!") , MB_ICONINFORMATION | MB_OK,NULL);
  252. // 解除锁定
  253. ::GlobalUnlock((HGLOBAL) GetHDIB());
  254. return;
  255. }
  256. // 更改光标形状
  257. BeginWaitCursor();
  258. // 找到DIB图像象素起始位置
  259. lpDIBBits = ::FindDIBBits(lpDIB);
  260. // 得到小波变换所需的层次、滤波器长度等参数
  261. GetParam();
  262. // 获取滤波器参数
  263. if(!GetHn())
  264. return;
  265.     // 绘制原始图像
  266.     DrawOriginalBmp();
  267.     // 给image数组分配内存
  268. if(!GetMemory())
  269. return;
  270. // 将图像数据读入image数组
  271. for(int i=0;i<m_nImageHeight;i++)
  272. for(int j=0;j<m_nImageWidth;j++)
  273.     image[i][j]=(unsigned char)(*((unsigned char *)lpDIBBits+m_nImageWidth*i+j));
  274.      
  275. // 对图像进行二维小波变换
  276. Wavelet2D();
  277. // 绘制二维小波变换后的图像
  278. DrawWavelet2D();
  279. // 释放资源
  280. ReleaseMemory();
  281.   // 解除锁定
  282. ::GlobalUnlock((HGLOBAL) GetHDIB());
  283. // 恢复光标
  284. EndWaitCursor();
  285.     // 设置已进行过小波变换标志
  286. m_bWavelet=TRUE;
  287. }
  288. // 确定退出函数
  289. void CWavelet2DDlg::OnOK() 
  290. {
  291. if(m_pBmpInfo)
  292. free(m_pBmpInfo);
  293. CDialog::OnOK();
  294. }
  295. // 分配小波变换所需内存
  296. BOOL CWavelet2DDlg::GetMemory()
  297. {
  298.     BOOL flag=TRUE;
  299.     image=new double *[m_nImageHeight];
  300. for(int n=0;n<m_nImageHeight;n++)
  301. {
  302. *(image+n)=new double[sizeof(double)*m_nImageWidth];
  303.     if(*(image+n)==NULL)
  304.    flag=FALSE;
  305. }
  306. tempRow=new double[sizeof(double)*m_nImageWidth];
  307. tempCol=new double[sizeof(double)*m_nImageHeight];
  308. if(tempRow==NULL||tempCol==NULL)
  309. flag=FALSE;
  310.     return flag;
  311. }
  312. // 释放资源
  313. void CWavelet2DDlg::ReleaseMemory()
  314. {
  315. for(int k=0;k<m_nImageHeight;k++)
  316.   delete *(image+k);
  317.     delete []image; 
  318. delete tempCol;
  319. delete tempRow;
  320. image=NULL;
  321. tempCol=NULL;
  322. tempRow=NULL;
  323. if(DIB)
  324.    ::GlobalFree((HGLOBAL) DIB);
  325.    DIB=NULL;
  326. }
  327. }
  328. // 得到滤波器参数
  329. BOOL CWavelet2DDlg::GetHn()
  330. {
  331.      int i;
  332.  double temp1;
  333.  FILE *fp1;
  334.  if((fp1=fopen(m_strFilterFile[m_nFilterLen/2-1],"rb+"))==NULL)
  335.  {
  336.     AfxMessageBox("打开Hn数据文件失败!",MB_OK|MB_ICONINFORMATION);
  337. return FALSE;
  338.  }
  339.  for(i=0;i<30;i++)
  340.  h[i]=0;
  341.  for(i=0;i<m_nFilterLen;i++)
  342.  {
  343.     fread(&temp1,sizeof(double),1,fp1);
  344. h[i]=temp1;
  345.  }
  346.  fclose(fp1);
  347.      return TRUE;
  348. }
  349. //返回H算子周期化后得值
  350. double CWavelet2DDlg::HH(int i,int m)
  351. {
  352.      return h[i+m];
  353. }
  354. //返回G算子周期化后的值
  355. double CWavelet2DDlg::GG(int i, int m)
  356. {
  357.      char flag;
  358.  if(i%2)
  359.  flag=-1;
  360.  else
  361.  flag=1;
  362.  return HH(-1*i+1,m)*flag;
  363. }
  364. //H算子周期化过程
  365. BOOL CWavelet2DDlg::HHH(int level,int size)
  366. {
  367.      int len,m,i;
  368.  double temp;
  369.  int sign;
  370.  len=size>>level;
  371.  m=m_nFilterLen/2;
  372.  if((ph=new double[sizeof(double)*len])==NULL)
  373.  {
  374.     AfxMessageBox("H算子内存分配失败!",MB_OK|MB_ICONINFORMATION);
  375. return FALSE;
  376.  }
  377.  for(sign=0;sign<len;sign++)
  378.  {
  379.      temp=0;
  380.  for(i=(-1*m+1);i<=m;i++)
  381.  {
  382.      if(((sign-i)%len)==0)
  383.      temp+=HH(i-1,m);
  384.  }
  385.  ph[sign]=temp;
  386.  }
  387.  return TRUE;
  388. }
  389. // G算子周期化过程
  390. BOOL CWavelet2DDlg::GGG(int level,int size)
  391. {
  392.      int len,m,i;
  393.  double temp;
  394.  int sign;
  395.  len=size>>level;
  396.  m=m_nFilterLen/2;
  397.  if((pg=new double[sizeof(double)*len])==NULL)
  398.  {
  399.     AfxMessageBox("G算子内存分配失败!",MB_OK|MB_ICONINFORMATION);
  400. return FALSE;
  401.  }
  402.  for(sign=0;sign<len;sign++)
  403.  {
  404.      temp=0;
  405.  for(i=(-1*m+3);i<=m+2;i++)
  406.  {
  407.      if(((sign-i)%len)==0)
  408.      temp+=GG(i-1,m);
  409.  }
  410.  pg[sign]=temp;
  411.  }
  412.  return TRUE;
  413. }
  414. // H算子作用于行数据
  415. void CWavelet2DDlg::HOperatorOnRow(int filterlen, int start, int len,int row)
  416. {
  417.      int i,i2,m,k,len1;
  418.  double temp1;
  419.  m=m_nFilterLen/2;
  420.  len1=len>>1;
  421.  for(i=0;i<len1;i++)
  422.  {
  423.      i2=2*i;
  424.  tempRow[i+start]=0;
  425.  if(len>filterlen)
  426.  {
  427.     for(k=i2-len;k<=i2-len+m;k++)
  428. {
  429.     if((k>=0)&&(k<len))
  430. if((temp1=ph[(k-i2+len)%len])!=0)
  431. tempRow[i+start]+=temp1*image[row][k+start];
  432. }
  433. for(k=i2-m+1;k<=i2+m;k++)
  434. {
  435.     if((k>=0)&&(k<len))
  436. if((temp1=ph[(k-i2+len)%len])!=0)
  437. tempRow[i+start]+=temp1*image[row][k+start];
  438. }
  439. for(k=i2+len-m+1;k<=i2+len;k++)
  440. {
  441.     if((k>=0)&&(k<len))
  442. if((temp1=ph[(k-i2+len)%len])!=0)
  443. tempRow[i+start]+=temp1*image[row][k+start];
  444. }
  445.  }
  446.  else
  447.  {
  448.     for(k=0;k<len;k++)
  449. {
  450.     if((temp1=ph[(k-i2+len)%len])!=0)
  451. tempRow[i+start]+=temp1*image[row][k+start];
  452. }
  453.  }
  454.  }
  455. }
  456. // H算子作用于列数据
  457. void CWavelet2DDlg::HOperatorOnCol(int filterlen, int start, int len,int col)
  458. {
  459.  int i,i2,m,k,len1;
  460.  double temp1;
  461.  m=m_nFilterLen/2;
  462.  len1=len>>1;
  463.  for(i=0;i<len1;i++)
  464.  {
  465.      i2=2*i;
  466.  tempCol[i+start]=0;
  467.  if(len>filterlen)
  468.  {
  469.     for(k=i2-len;k<=i2-len+m;k++)
  470. {
  471.     if((k>=0)&&(k<len))
  472. if((temp1=ph[(k-i2+len)%len])!=0)
  473. tempCol[i+start]+=temp1*image[k+start][col];
  474. }
  475. for(k=i2-m+1;k<=i2+m;k++)
  476. {
  477.     if((k>=0)&&(k<len))
  478. if((temp1=ph[(k-i2+len)%len])!=0)
  479. tempCol[i+start]+=temp1*image[k+start][col];
  480. }
  481. for(k=i2+len-m+1;k<=i2+len;k++)
  482. {
  483.     if((k>=0)&&(k<len))
  484. if((temp1=ph[(k-i2+len)%len])!=0)
  485. tempCol[i+start]+=temp1*image[k+start][col];
  486. }
  487.  }
  488.  else
  489.  {
  490.     for(k=0;k<len;k++)
  491. {
  492.     if((temp1=ph[(k-i2+len)%len])!=0)
  493. tempCol[i+start]+=temp1*image[k+start][col];
  494. }
  495.  }
  496.  }
  497. }
  498. // G算子作用于行数据
  499. void CWavelet2DDlg::GOperatorOnRow(int filterlen, int start, int len,int row)
  500. {
  501.  int i,i2,m,k,len1;
  502.  double temp1;
  503.  m=m_nFilterLen/2;
  504.  len1=len>>1;
  505.  for(i=0;i<len1;i++)
  506.  {
  507.      i2=2*i;
  508.  tempRow[i+start+len1]=0;
  509.  if(len>filterlen)
  510.  {
  511.     for(k=i2-len;k<=i2-len+m+2;k++)
  512. {
  513.     if((k>=0)&&(k<len))
  514. if((temp1=pg[(k-i2+len)%len])!=0)
  515. tempRow[i+start+len1]+=temp1*image[row][k+start];
  516. }
  517. for(k=i2-m+3;k<=i2+m+2;k++)
  518. {
  519.     if((k>=0)&&(k<len))
  520. if((temp1=pg[(k-i2+len)%len])!=0)
  521. tempRow[i+start+len1]+=temp1*image[row][k+start];
  522. }
  523. for(k=i2+len-m+3;k<=i2+len;k++)
  524. {
  525.     if((k>=0)&&(k<len))
  526. if((temp1=pg[(k-i2+len)%len])!=0)
  527. tempRow[i+start+len1]+=temp1*image[row][k+start];
  528. }
  529.  }
  530.  else
  531.  {
  532.     for(k=0;k<len;k++)
  533. {
  534.     if((temp1=pg[(k-i2+len)%len])!=0)
  535. tempRow[i+start]+=temp1*image[row][k+start];
  536. }
  537.  }
  538.  }
  539. }
  540. // G算子作用于列数据
  541. void CWavelet2DDlg::GOperatorOnCol(int filterlen, int start, int len,int col)
  542. {
  543.  int i,i2,m,k,len1;
  544.  double temp1;
  545.  m=m_nFilterLen/2;
  546.  len1=len>>1;
  547.  for(i=0;i<len1;i++)
  548.  {
  549.      i2=2*i;
  550.  tempCol[i+start+len1]=0;
  551.  if(len>filterlen)
  552.  {
  553.     for(k=i2-len;k<=i2-len+m+2;k++)
  554. {
  555.     if((k>=0)&&(k<len))
  556. if((temp1=pg[(k-i2+len)%len])!=0)
  557. tempCol[i+start+len1]+=temp1*image[k+start][col];
  558. }
  559. for(k=i2-m+3;k<=i2+m+2;k++)
  560. {
  561.     if((k>=0)&&(k<len))
  562. if((temp1=pg[(k-i2+len)%len])!=0)
  563. tempCol[i+start+len1]+=temp1*image[k+start][col];
  564. }
  565. for(k=i2+len-m+3;k<=i2+len;k++)
  566. {
  567.     if((k>=0)&&(k<len))
  568. if((temp1=pg[(k-i2+len)%len])!=0)
  569. tempCol[i+start+len1]+=temp1*image[k+start][col];
  570. }
  571.  }
  572.  else
  573.  {
  574.     for(k=0;k<len;k++)
  575. {
  576.     if((temp1=pg[(k-i2+len)%len])!=0)
  577. tempCol[i+start+len1]+=temp1*image[k+start][col];
  578. }
  579.  }
  580.  }
  581. }
  582. // 进行第stage层行变换
  583. void CWavelet2DDlg::DecompStageRow(int row, int stage, int numx)
  584. {
  585.      int i,start,end;
  586.  int filterlen,len;
  587.  filterlen=m_nFilterLen;
  588.  len=m_nImageWidth>>stage;
  589.  start=len*numx;
  590.  end=start+len;
  591.  HOperatorOnRow(filterlen,start,len,row); // H算子作用于行
  592.  GOperatorOnRow(filterlen,start,len,row); // G算子作用于行
  593.  for(i=start;i<end;i++)
  594.  image[row][i]=tempRow[i];
  595. }
  596. // 进行第stage层列变换
  597. void CWavelet2DDlg::DecompStageCol(int col, int stage, int numx)
  598. {
  599.      int i,start,end;
  600.  int filterlen,len;
  601.  filterlen=m_nFilterLen;
  602.  len=m_nImageHeight>>stage;
  603.  start=len*numx;
  604.  end=start+len;
  605.  HOperatorOnCol(filterlen,start,len,col);  // H算子作用于列
  606.  GOperatorOnCol(filterlen,start,len,col);  // G算子作用于列
  607.  for(i=start;i<end;i++)
  608.  image[i][col]=tempCol[i];
  609. }
  610. // 二维小波变换
  611. void CWavelet2DDlg::Wavelet2D()
  612. {
  613.      int row,col,stage;
  614.  // 进行第stage层小波变换
  615.  for(stage=0;stage<m_nDecomposeStage;stage++)
  616.  {
  617.      // 初始化H算子和G算子
  618.  if((!HHH(stage,m_nImageWidth))||(!GGG(stage,m_nImageWidth)))
  619.  break;
  620.  else
  621.  // 逐行变换
  622.  for(row=0;row<(m_nImageHeight>>stage);row++)
  623.  {
  624.      DecompStageRow(row,stage,0);  
  625.  }
  626.      if(ph&&pg)      // 释放资源
  627.  {
  628.     delete  ph;
  629. delete  pg;
  630. ph=NULL;
  631. pg=NULL;
  632.  }
  633.       // 初始化H算子和G算子
  634.  if((!HHH(stage,m_nImageHeight))||(!GGG(stage,m_nImageHeight)))
  635.  break;
  636.  else
  637.  // 逐列变换
  638.  for(col=0;col<(m_nImageWidth>>stage);col++)
  639.  {
  640.      DecompStageCol(col,stage,0);
  641.  }
  642.          if(ph&&pg)      // 释放资源
  643.  {
  644.     delete  ph;
  645. delete  pg;
  646. ph=NULL;
  647. pg=NULL;
  648.  }
  649.  }
  650. }
  651. // 绘制原始图像
  652. void CWavelet2DDlg::DrawOriginalBmp()
  653. {
  654. // 得到客户区
  655. CDC* pDC=GetDC();
  656.     CRect RectClient,Workarea;
  657.     GetClientRect(RectClient);
  658. // 锁定DIB
  659. lpDIB = (LPSTR)::GlobalLock((HGLOBAL) GetHDIB());
  660.     // 在对话框右上部分创建绘制原始图像区域
  661. Workarea.left=RectClient.left+(RectClient.right-RectClient.left)/5*2;
  662.     Workarea.right=RectClient.right-10;
  663.     Workarea.top=RectClient.top+10;
  664. Workarea.bottom=RectClient.top+(RectClient.bottom-RectClient.top-10)/2;
  665. // 设置区域背景色为白色
  666. pDC->Rectangle(Workarea);
  667.     pDC->SetBkColor(0x00FFFFFF);
  668. // 绘制原始图像
  669. m_pBmpInfo->bmiHeader.biWidth = m_nImageWidth;
  670.     m_pBmpInfo->bmiHeader.biHeight = m_nImageHeight;
  671. ::StretchDIBits(pDC->GetSafeHdc(), Workarea.left+1, Workarea.top+1, Workarea.Width(),Workarea.Height(),//m_nImageWidth, m_nImageHeight,
  672.                 0, 0, m_nImageWidth, m_nImageHeight, (unsigned char *)lpDIBBits,
  673. (LPBITMAPINFO) m_pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
  674.     // 解除锁定
  675. ::GlobalUnlock((HGLOBAL)GetHDIB());
  676. }
  677. // 绘制二维小波变换后图像
  678. void CWavelet2DDlg::DrawWavelet2D()
  679. {
  680. // 找到图像变换后数据中的最大最小值
  681. double min=image[0][0],max=0;
  682.     for(int a=0;a<m_nImageHeight;a++)
  683.    for(int b=0;b<m_nImageWidth;b++)
  684.    {
  685.    if(image[a][b]>10000)
  686.    image[a][b]=max;
  687.    if(image[a][b]<-10000)
  688.    image[a][b]=min;
  689.    if(max<image[a][b])
  690.           max=image[a][b];
  691.        if(min>image[a][b])
  692.           min=image[a][b];
  693.    }
  694.     // 将图像变换后数据归一化到256级灰度
  695. for(int m=0;m<m_nImageHeight;m++)
  696. for(int n=0;n<m_nImageWidth;n++)
  697. {  
  698.    image[m][n]=(image[m][n]-min)/(max-min)*256.0;
  699.     *((unsigned char *)lpDIBBits+m_nImageWidth*m+n)=(unsigned char )image[m][n];
  700. }
  701. // 得到客户区
  702. CDC* pDC=GetDC();
  703.     CRect RectClient,Workarea;
  704.     GetClientRect(RectClient);
  705. // 锁定DIB
  706. lpDIB = (LPSTR)::GlobalLock((HGLOBAL) GetHDIB());
  707. // 在对话框右下部分创建绘制原始图像区域
  708. Workarea.left=RectClient.left+(RectClient.right-RectClient.left)/5*2;
  709.     Workarea.right=RectClient.right-10;
  710. Workarea.top=RectClient.top+10+(RectClient.bottom-RectClient.top-10)/2;
  711.     Workarea.bottom=RectClient.bottom-10;
  712. // 设置区域背景色为白色 
  713.     pDC->Rectangle(Workarea);
  714.     pDC->SetBkColor(0x00FFFFFF);
  715. // 绘制原始图像
  716. m_pBmpInfo->bmiHeader.biWidth = m_nImageWidth;
  717.     m_pBmpInfo->bmiHeader.biHeight = m_nImageHeight;
  718. ::StretchDIBits(pDC->GetSafeHdc(), Workarea.left+1, Workarea.top+1, Workarea.Width(),Workarea.Height(),//m_nImageWidth, m_nImageHeight,
  719.                 0, 0, m_nImageWidth, m_nImageHeight, (unsigned char *)lpDIBBits,
  720. (LPBITMAPINFO) m_pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
  721. // 解除锁定
  722. ::GlobalUnlock((HGLOBAL)GetHDIB());
  723. }
  724. // 得到小波变换所需的层次、滤波器长度等参数
  725. void CWavelet2DDlg::GetParam()
  726. {
  727. // 得到待分解层次信息
  728. if(m_combDecomposeStage.GetCurSel()==CB_ERR)
  729.    m_nDecomposeStage=1;
  730. else
  731.        m_nDecomposeStage=m_combDecomposeStage.GetItemData(m_combDecomposeStage.GetCurSel());
  732. // 得到滤波器长度
  733. if(m_combFilterLen.GetCurSel()==CB_ERR)
  734.    m_nFilterLen=6;
  735. else
  736.    m_nFilterLen=m_combFilterLen.GetItemData(m_combFilterLen.GetCurSel());
  737. }