ImageProcessingView.cpp
上传用户:wangchdtw
上传日期:2014-04-02
资源大小:329k
文件大小:71k
源码类别:

波变换

开发平台:

Visual C++

  1. // ImageProcessingView.cpp : implementation of the CImageProcessingView class
  2. //
  3. #include "stdafx.h"
  4. #include "ImageProcessing.h"
  5. #include "ImageProcessingDoc.h"
  6. #include "ImageProcessingView.h"
  7. #include  "GlobalApi.h"
  8. #include  "DlgCoding.h"
  9. #include <complex>
  10. using namespace std;
  11. #include "DlgHistShow1.h"
  12. #include "DlgSmooth.h"
  13. #include "DlgMedian.h"
  14. #include "DlgEnhColor.h"
  15. #include "DlgEhnLinTrans.h"
  16. #include "DlgReg.h"
  17. #include "DlgRecMatch.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CImageProcessingView
  25. IMPLEMENT_DYNCREATE(CImageProcessingView, CScrollView)
  26. BEGIN_MESSAGE_MAP(CImageProcessingView, CScrollView)
  27. //{{AFX_MSG_MAP(CImageProcessingView)
  28. ON_COMMAND(ID_FFT_2D, OnFft2d)
  29. ON_COMMAND(ID_DFT_2D, OnDft2d)
  30. ON_COMMAND(ID_VIEW_HISTOGRAM, OnViewHistogram)
  31. ON_COMMAND(ID_ENHANCE_SMOOTH, OnEnhanceSmooth)
  32. ON_COMMAND(ID_ENHANCE_MEDIAN, OnEnhanceMedian)
  33. ON_COMMAND(ID_ENHANCE_PSEUDCOLOR, OnEnhancePseudcolor)
  34. ON_COMMAND(ID_TRANS_DWT, OnTransDwt)
  35. ON_COMMAND(ID_TRANS_IDWT, OnTransIdwt)
  36. ON_COMMAND(IDC_ENHANCE_LINTRANS, OnEnhanceLintrans)
  37. ON_COMMAND(IDC_ENHANCE_HISTEQU, OnEnhanceHistequ)
  38. ON_COMMAND(ID_REG_REG, OnRegReg)
  39. ON_COMMAND(IDC_ENHANCE_SHARP, OnEnhanceSharp)
  40. ON_COMMAND(ID_ENHANCE_SMOOTH_FR, OnEnhanceSmoothFr)
  41. ON_COMMAND(IDC_ENHANCE_BUTT_LOW, OnEnhanceButtLow)
  42. ON_COMMAND(IDC_ENHANCE_SHARP_FREQ, OnEnhanceSharpFreq)
  43. ON_COMMAND(IDC_ENHANCE_BUTT_HIGHT, OnEnhanceButtHight)
  44. ON_COMMAND(ID_REGIONSEG_FIX, OnRegionsegFix)
  45. ON_COMMAND(ID_ADA_REGION_SEG, OnAdaRegionSeg)
  46. ON_COMMAND(ID_EDGE_ROBERTS, OnEdgeRoberts)
  47. ON_COMMAND(ID_EDGE_SOBEL, OnEdgeSobel)
  48. ON_COMMAND(ID_EDGE_PREWITT, OnEdgePrewitt)
  49. ON_COMMAND(ID_EDGE_LAPLACE, OnEdgeLaplace)
  50. ON_COMMAND(ID_EDGE_CANNY, OnEdgeCanny)
  51. ON_COMMAND(ID_EDGE_TRACK, OnEdgeTrack)
  52. ON_COMMAND(ID_REGION_GROW, OnRegionGrow)
  53. ON_COMMAND(ID_MOTION_BACKGROUND, OnMotionBackground)
  54. ON_COMMAND(ID_RECOG_MATCH, OnRecogMatch)
  55. ON_COMMAND(ID_CODING_SHANFINO, OnCodingShanfino)
  56. ON_COMMAND(ID_DEGENERATION_INVERSE, OnDegenerationInverse)
  57. ON_COMMAND(ID_DEGENERATION_MOTION, OnDegenerationMotion)
  58. ON_COMMAND(ID_DEGENERATION_Winner, OnDEGENERATIONWinner)
  59. ON_COMMAND(ID_RESTORE_INVERSE, OnRestoreInverse)
  60. ON_COMMAND(ID_RESTORE_MOTION, OnRestoreMotion)
  61. ON_COMMAND(ID_RESTORE_WINNER, OnRestoreWinner)
  62. ON_COMMAND(ID_STREET_FRAMEWORK, OnStreetFramework)
  63. ON_COMMAND(ID_STREET_TRANSFORM, OnStreetTransform)
  64. ON_COMMAND(ID_TRACE, OnTrace)
  65. ON_COMMAND(ID_VIEW_BAYER, OnViewBayer)
  66. ON_COMMAND(ID_VIEW_FloydSteinberg, OnVIEWFloydSteinberg)
  67. ON_COMMAND(ID_OUTLINE, OnOutline)
  68. ON_COMMAND(ID_FRAME_RESTORE, OnFrameRestore)
  69. ON_COMMAND(ID_MOMENT, OnMoment)
  70. ON_COMMAND(ID_BARYCENTERMOMENT, OnBarycentermoment)
  71. ON_COMMAND(ID_ANALYSIS_HOLENUM, OnAnalysisHolenum)
  72. ON_COMMAND(ID_FREQ_DCT, OnFreqDct)
  73. ON_COMMAND(ID_FREQ_HOTELLING, OnFreqHotelling)
  74. ON_COMMAND(ID_FREQ_WALSH, OnFreqWalsh)
  75. ON_COMMAND(ID_CODING_ARITH, OnCodingArith)
  76. ON_COMMAND(ID_CODING_BITPLANE, OnCodingBitplane)
  77. ON_COMMAND(ID_CODING_HUFFMAN, OnCodingHuffman)
  78. ON_COMMAND(ID_CODING_LOADIMG, OnCodingLoadimg)
  79. ON_COMMAND(ID_CODING_WRITEIMG, OnCodingWriteimg)
  80. //}}AFX_MSG_MAP
  81. // Standard printing commands
  82. ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
  83. ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  84. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  85. END_MESSAGE_MAP()
  86. /////////////////////////////////////////////////////////////////////////////
  87. // CImageProcessingView construction/destruction
  88. CImageProcessingView::CImageProcessingView()
  89. {
  90. // 为小波变换设置的参数
  91. // 临时存放小波变换系数内存
  92. m_pDbImage = NULL;
  93. // 设置当前层数
  94. m_nDWTCurDepth = 0;
  95. // 设置小波基紧支集长度
  96. m_nSupp = 1;
  97. }
  98. CImageProcessingView::~CImageProcessingView()
  99. {
  100. // 释放已分配内存
  101. if(m_pDbImage){
  102. delete[]m_pDbImage;
  103. m_pDbImage = NULL;
  104. }
  105. }
  106. BOOL CImageProcessingView::PreCreateWindow(CREATESTRUCT& cs)
  107. {
  108. // TODO: Modify the Window class or styles here by modifying
  109. //  the CREATESTRUCT cs
  110. return CScrollView::PreCreateWindow(cs);
  111. }
  112. /////////////////////////////////////////////////////////////////////////////
  113. // CImageProcessingView drawing
  114. void CImageProcessingView::OnDraw(CDC* pDC)
  115. {
  116. CImageProcessingDoc* pDoc = GetDocument();
  117. ASSERT_VALID(pDoc);
  118. CSize sizeDibDisplay;
  119. if(!pDoc->m_pDibInit->IsEmpty()){
  120. sizeDibDisplay = pDoc->m_pDibInit->GetDimensions();
  121. pDoc->m_pDibInit->Draw(pDC,CPoint(0,0),sizeDibDisplay);
  122. }
  123. }
  124. void CImageProcessingView::OnInitialUpdate()
  125. {
  126. CScrollView::OnInitialUpdate();
  127. CImageProcessingDoc* pDoc = GetDocument();
  128. ASSERT_VALID(pDoc);
  129. CSize sizeTotal = pDoc->m_pDibInit->GetDimensions();
  130. SetScrollSizes(MM_TEXT, sizeTotal);
  131. GetParentFrame()->RecalcLayout();
  132. ResizeParentToFit();
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. // CImageProcessingView printing
  136. BOOL CImageProcessingView::OnPreparePrinting(CPrintInfo* pInfo)
  137. {
  138. // default preparation
  139. return DoPreparePrinting(pInfo);
  140. }
  141. void CImageProcessingView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  142. {
  143. // TODO: add extra initialization before printing
  144. }
  145. void CImageProcessingView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  146. {
  147. // TODO: add cleanup after printing
  148. }
  149. /////////////////////////////////////////////////////////////////////////////
  150. // CImageProcessingView diagnostics
  151. #ifdef _DEBUG
  152. void CImageProcessingView::AssertValid() const
  153. {
  154. CScrollView::AssertValid();
  155. }
  156. void CImageProcessingView::Dump(CDumpContext& dc) const
  157. {
  158. CScrollView::Dump(dc);
  159. }
  160. CImageProcessingDoc* CImageProcessingView::GetDocument() // non-debug version is inline
  161. {
  162. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageProcessingDoc)));
  163. return (CImageProcessingDoc*)m_pDocument;
  164. }
  165. #endif //_DEBUG
  166. /////////////////////////////////////////////////////////////////////////////
  167. // CImageProcessingView message handlers
  168. /*************************************************************************
  169.  *
  170.  * 函数名称:
  171.  *   OnFft2d()
  172.  *
  173.  * 输入参数:
  174.  *   无
  175.  * 
  176.  * 返回值:
  177.  *   无
  178.  *
  179.  * 说明:
  180.  *   运行二维快速傅立叶变换
  181.  *
  182.  *************************************************************************
  183.  */
  184. void CImageProcessingView::OnFft2d() 
  185. {
  186. //图象FFT变换
  187. // 更改光标形状
  188. BeginWaitCursor();
  189. // 循环控制变量
  190. int y;
  191. int x;
  192. // 获得Doc类的指针
  193. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  194. CDib * pDib = pDoc->m_pDibInit;
  195. // 获得图象的头文件信息
  196. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  197. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散傅立叶变换)
  198. if (lpBMIH->biBitCount != 8)
  199. {
  200. // 提示用户
  201. MessageBox("目前只支持256色位图的离散傅立叶变换!", "系统提示" ,
  202. MB_ICONINFORMATION | MB_OK);
  203. // 返回
  204. return;
  205. }
  206. // 图象的宽长
  207. CSize sizeImage ;
  208. int nWidth ;
  209. int nHeight;
  210. // 获得图象的宽长
  211. sizeImage = pDib->GetDimensions() ;
  212. nWidth = sizeImage.cx;
  213. nHeight= sizeImage.cy;
  214. // 临时变量
  215. double dTmpOne;
  216. double  dTmpTwo;
  217. // 傅立叶变换竖直方向点数
  218. int nTransHeight ;
  219. // 傅立叶变换水平方向点数
  220. int nTransWidth  ;
  221. // 计算进行傅立叶变换的点数 (2的整数次幂)
  222. dTmpOne = log(nWidth)/log(2);
  223. dTmpTwo = ceil(dTmpOne)    ;
  224. dTmpTwo = pow(2,dTmpTwo)    ;
  225. nTransWidth = (int) dTmpTwo    ;
  226. // 计算进行傅立叶变换的点数 (2的整数次幂)
  227. dTmpOne = log(nHeight)/log(2);
  228. dTmpTwo = ceil(dTmpOne)    ;
  229. dTmpTwo = pow(2,dTmpTwo)    ;
  230. nTransHeight = (int) dTmpTwo   ;
  231. // 计算图象数据存储每行需要的字节数
  232. // BMP文件的每行数据存储是DWORD对齐的
  233. int nSaveWidth;
  234. nSaveWidth = ( (nWidth << 3) + 31)/32 * 4 ;
  235. // 指向图象数据的指针
  236. LPBYTE lpImage ;
  237. lpImage = pDib->m_lpImage ;
  238. // 图象象素值
  239. unsigned char unchValue;
  240. // 指向时域数据的指针
  241. complex<double> * pCTData ;
  242. // 指向频域数据的指针
  243. complex<double> * pCFData ;
  244. // 分配内存
  245. pCTData=new complex<double>[nTransWidth * nTransHeight];
  246. pCFData=new complex<double>[nTransWidth * nTransHeight];
  247. // 初始化
  248. // 图象数据的宽和高不一定是2的整数次幂,所以pCTData
  249. // 有一部分数据需要补0
  250. for(y=0; y<nTransHeight; y++)
  251. {
  252. for(x=0; x<nTransWidth; x++)
  253. {
  254. pCTData[y*nTransWidth + x]=complex<double>(0,0);
  255. }
  256. }
  257. // 把图象数据传给pCTData
  258. for(y=0; y<nHeight; y++)
  259. {
  260. for(x=0; x<nWidth; x++)
  261. {
  262. unchValue = lpImage[y*nSaveWidth +x];
  263. pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  264. }
  265. }
  266. // 傅立叶正变换
  267. DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
  268. // 临时变量
  269. double dTmp;
  270. for(y=0; y<nHeight; y++)
  271. {
  272. for(x=0; x<nWidth; x++)
  273. {
  274. dTmp = pCFData[y * nTransWidth + x].real() 
  275.    * pCFData[y * nTransWidth + x].real()
  276.  + pCFData[y * nTransWidth + x].imag() 
  277.    * pCFData[y * nTransWidth + x].imag();
  278. dTmp = sqrt(dTmp) ;
  279. // 为了显示,需要对幅度的大小进行伸缩
  280. dTmp /= 100        ;
  281. // 限制图象数据的大小
  282. dTmp = min(dTmp, 255) ;
  283. lpImage[y*nSaveWidth +x] = (unsigned char)(int)dTmp;
  284. }
  285. }
  286. // 为了在屏幕上显示,我们把幅度值大的部分用黑色显示
  287. for(y=0; y<nHeight; y++)
  288. {
  289. for(x=0; x<nWidth; x++)
  290. {
  291. lpImage[y*nSaveWidth +x] = 255 - lpImage[y*nSaveWidth +x];
  292. }
  293. }
  294. // 刷新屏幕
  295. Invalidate();
  296. // 释放内存
  297. delete pCTData;
  298. delete pCFData;
  299. pCTData = NULL;
  300. pCFData = NULL;
  301. // 设置脏标记
  302. pDoc->SetModifiedFlag(TRUE);
  303. // 更新视图
  304. pDoc->UpdateAllViews(NULL);
  305. //  恢复光标形状
  306. EndWaitCursor();
  307. }
  308. /*************************************************************************
  309.  *
  310.  * 函数名称:
  311.  *   OnDft2d()
  312.  *
  313.  * 输入参数:
  314.  *   无
  315.  * 
  316.  * 返回值:
  317.  *   无
  318.  *
  319.  * 说明:
  320.  *   运行二维傅立叶变换
  321.  *
  322.  *************************************************************************
  323.  */
  324. void CImageProcessingView::OnDft2d() 
  325. {
  326. //图象离散傅立叶变换
  327. //提示用户,直接进行离散傅立叶变换的时间很长
  328. MessageBox("没有使用FFT,时间可能很长!", "作者提示" ,
  329. MB_ICONINFORMATION | MB_OK);
  330. //更改光标形状
  331. BeginWaitCursor(); 
  332. // 循环控制变量
  333. int y;
  334. int x;
  335. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  336. CDib * pDib = pDoc->m_pDibInit;
  337. // 获得图象的头文件信息
  338. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  339. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散傅立叶变换)
  340. if (lpBMIH->biBitCount != 8)
  341. {
  342. // 提示用户
  343. MessageBox("目前只支持256色位图的离散傅立叶变换!", "系统提示" ,
  344. MB_ICONINFORMATION | MB_OK);
  345. // 返回
  346. return;
  347. }
  348. //图象的长宽大小
  349. CSize sizeImage = pDib->GetDimensions();
  350. int nWidth = sizeImage.cx ;
  351. int nHeight = sizeImage.cy ;
  352. // 计算图象数据存储每行需要的字节数
  353. // BMP文件的每行数据存储是DWORD对齐的
  354. int nSaveWidth;
  355. nSaveWidth = ( (nWidth << 3) + 31)/32 * 4 ;
  356. // 指向图象数据的指针
  357. LPBYTE lpImage ;
  358. lpImage = pDib->m_lpImage ;
  359. double * pTrRstRpart  = new double [nWidth*nHeight];
  360. double * pTrRstIpart  = new double [nWidth*nHeight];
  361. ::DIBDFT_2D(pDib, pTrRstRpart,pTrRstIpart);
  362. // 临时变量
  363. double dTmp;
  364. for(y=0; y<nHeight; y++)
  365. {
  366. for(x=0; x<nWidth; x++)
  367. {
  368. dTmp = pTrRstRpart[y*nWidth + x] * pTrRstRpart[y*nWidth + x]
  369.  + pTrRstIpart[y*nWidth + x] * pTrRstIpart[y*nWidth + x];
  370. dTmp = sqrt(dTmp) ;
  371. // 为了显示,需要对幅度的大小进行伸缩
  372. dTmp /= 100        ;
  373. // 限制图象数据的大小
  374. dTmp = min(dTmp, 255) ;
  375. lpImage[y*nSaveWidth +x] = (unsigned char)(int)dTmp;
  376. }
  377. }
  378. // 为了在屏幕上显示,我们把幅度值大的部分用黑色显示
  379. for(y=0; y<nHeight; y++)
  380. {
  381. for(x=0; x<nWidth; x++)
  382. {
  383. lpImage[y*nSaveWidth +x] = 255 - lpImage[y*nSaveWidth +x];
  384. }
  385. }
  386. // 释放内存
  387. delete pTrRstRpart;
  388. pTrRstRpart=NULL  ;
  389. delete pTrRstIpart;
  390. pTrRstIpart=NULL  ;
  391. // 设置脏标记
  392. pDoc->SetModifiedFlag(TRUE);
  393. // 更新视图
  394. pDoc->UpdateAllViews(NULL);
  395. // 恢复光标形状
  396. EndWaitCursor(); 
  397. // 刷新屏幕
  398. Invalidate();
  399. }
  400. void CImageProcessingView::OnFreqDct() 
  401. {
  402. // 图象的离散余弦变换
  403. // 更改光标形状
  404. BeginWaitCursor();
  405. // 获取文档
  406. CImageProcessingDoc* pDoc = GetDocument();
  407. //  获得图象CDib类的指针
  408. CDib * pDib = pDoc->m_pDibInit;
  409. // 获得图象的头文件信息
  410. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  411. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散余弦变换)
  412. if (lpBMIH->biBitCount != 8)
  413. {
  414. // 提示用户
  415. MessageBox("目前只支持256色位图的离散余弦变换!", "系统提示" ,
  416. MB_ICONINFORMATION | MB_OK);
  417. // 返回
  418. return;
  419. }
  420. ::DIBDct(pDib);
  421. // 设置脏标记
  422. pDoc->SetModifiedFlag(TRUE);
  423. // 更新视图
  424. pDoc->UpdateAllViews(NULL);
  425.     // 恢复光标
  426. EndWaitCursor();
  427. }
  428. void CImageProcessingView::OnFreqHotelling() 
  429. {
  430. // 图象霍特林变换
  431. // 更改光标形状
  432. BeginWaitCursor();
  433. // 获取文档
  434. CImageProcessingDoc* pDoc = GetDocument();
  435. //  获得图象CDib类的指针
  436. CDib * pDib = pDoc->m_pDibInit;
  437. // 获得图象的头文件信息
  438. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  439. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的离散霍特林变换)
  440. if (lpBMIH->biBitCount != 8)
  441. {
  442. // 提示用户
  443. MessageBox("目前只支持256色位图的离散霍特林变换!", "系统提示" ,
  444. MB_ICONINFORMATION | MB_OK);
  445. // 返回
  446. return;
  447. }
  448. //  图象的霍特林变换
  449. DIBHOTELLING(pDib);
  450. // 设置脏标记
  451. pDoc->SetModifiedFlag(TRUE);
  452. // 更新视图
  453. pDoc->UpdateAllViews(NULL);
  454.     // 恢复光标
  455. EndWaitCursor();
  456. }
  457. void CImageProcessingView::OnFreqWalsh() 
  458. {
  459. // 图象的沃尔什-哈达玛变换
  460. // 更改光标形状
  461. BeginWaitCursor();
  462. // 获取文档
  463. CImageProcessingDoc* pDoc = GetDocument();
  464. //  获得图象CDib类的指针
  465. CDib * pDib = pDoc->m_pDibInit;
  466. // 获得图象的头文件信息
  467. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  468. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的沃尔什-哈达玛变换)
  469. if (lpBMIH->biBitCount != 8)
  470. {
  471. // 提示用户
  472. MessageBox("目前只支持256色位图的离散沃尔什变换!", "系统提示" ,
  473. MB_ICONINFORMATION | MB_OK);
  474. // 返回
  475. return;
  476. }
  477. //  进行沃尔什-哈达玛变换
  478. DIBWalsh(pDib);
  479. // 设置脏标记
  480. pDoc->SetModifiedFlag(TRUE);
  481. // 更新视图
  482. pDoc->UpdateAllViews(NULL);
  483.     // 恢复光标
  484. EndWaitCursor();
  485. }
  486. /*************************************************************************
  487.  *
  488.  * 函数名称:
  489.  *   OnViewHistogram()
  490.  *
  491.  * 输入参数:
  492.  *   无
  493.  * 
  494.  * 返回值:
  495.  *   无
  496.  *
  497.  * 说明:
  498.  *   查看直方图,弹出直方图显示界面
  499.  *
  500.  *************************************************************************
  501.  */
  502. void CImageProcessingView::OnViewHistogram() 
  503. {
  504. // 获取文档
  505. CImageProcessingDoc* pDoc = GetDocument();
  506. // DIB的颜色数目
  507. int nColorTableEntries;
  508. nColorTableEntries = pDoc->m_pDibInit->m_nColorTableEntries;
  509. // 判断是否是8bpp位图(这里只处理8bpp位图)
  510. if ( nColorTableEntries != 256)
  511. {
  512. // 提示用户,不再进行处理
  513. MessageBox("目前只支持查看256色位图灰度直方图!", "系统提示" , MB_ICONINFORMATION | MB_OK);
  514. // 返回
  515. return;
  516. }
  517. // 更改光标形状
  518. BeginWaitCursor();
  519. // 创建对话框
  520. CDlgHistShow dlgHistShow;
  521. // 初始化变量值
  522. dlgHistShow.m_pDib = pDoc->m_pDibInit;
  523. // 显示对话框
  524. if (dlgHistShow.DoModal() != IDOK)
  525. {
  526. // 返回
  527. return;
  528. }
  529. // 恢复光标
  530. EndWaitCursor();
  531. }
  532. /*************************************************************************
  533.  *
  534.  * 函数名称:
  535.  *   OnEnhanceSmooth()
  536.  *
  537.  * 输入参数:
  538.  *   无
  539.  * 
  540.  * 返回值:
  541.  *   无
  542.  *
  543.  * 说明:
  544.  *   对图象进行平滑处理,并弹出平滑模板设置对话框
  545.  *
  546.  *************************************************************************
  547.  */
  548. void CImageProcessingView::OnEnhanceSmooth() 
  549. {
  550. // TODO: Add your command handler code here
  551. // 图像平滑
  552. // 获取文档
  553. CImageProcessingDoc* pDoc = GetDocument();
  554. // 模板高度
  555. int nTempHeight;
  556. // 模板宽度
  557. int nTempWidth;
  558. // 模板系数
  559. double dbTempCoef;
  560. // 模板中心元素X坐标
  561. int nTempCenX;
  562. // 模板中心元素Y坐标
  563. int nTempCenY;
  564. // 模板元素数组
  565. double pdbTemp[25];
  566. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平滑,其它的可以类推)
  567. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  568. //if (::DIBNumColors(lpDIB) != 256)
  569. {
  570. // 提示用户
  571. MessageBox("目前只支持256色位图的平滑!", "系统提示" , 
  572. MB_ICONINFORMATION | MB_OK);
  573. // 返回
  574. return;
  575. }
  576. // 创建对话框
  577. CDlgSmooth dlgSmth;
  578. // 给模板数组赋初值(为平均模板)
  579. pdbTemp[0] = 1.0;
  580. pdbTemp[1] = 1.0;
  581. pdbTemp[2] = 1.0;
  582. pdbTemp[3] = 0.0;
  583. pdbTemp[4] = 0.0;
  584. pdbTemp[5] = 1.0;
  585. pdbTemp[6] = 1.0;
  586. pdbTemp[7] = 1.0;
  587. pdbTemp[8] = 0.0;
  588. pdbTemp[9] = 0.0;
  589. pdbTemp[10] = 1.0;
  590. pdbTemp[11] = 1.0;
  591. pdbTemp[12] = 1.0;
  592. pdbTemp[13] = 0.0;
  593. pdbTemp[14] = 0.0;
  594. pdbTemp[15] = 0.0;
  595. pdbTemp[16] = 0.0;
  596. pdbTemp[17] = 0.0;
  597. pdbTemp[18] = 0.0;
  598. pdbTemp[19] = 0.0;
  599. pdbTemp[20] = 0.0;
  600. pdbTemp[21] = 0.0;
  601. pdbTemp[22] = 0.0;
  602. pdbTemp[23] = 0.0;
  603. pdbTemp[24] = 0.0;
  604. // 初始化对话框变量值
  605. dlgSmth.m_nTemType  = 0;
  606. dlgSmth.m_nSmthTemHeight  = 3;
  607. dlgSmth.m_nSmthTemWidth  = 3;
  608. dlgSmth.m_nSmthTemCenX = 1;
  609. dlgSmth.m_nSmthTemCenY = 1;
  610. dlgSmth.m_dbSmthTemCoef  = (double) (1.0 / 9.0);
  611. dlgSmth.m_pdbTemp = pdbTemp;
  612. // 显示对话框,提示用户设定平移量
  613. if (dlgSmth.DoModal() != IDOK)
  614. {
  615. // 返回
  616. return;
  617. }
  618. // 获取用户设定的平移量
  619. nTempHeight   = dlgSmth.m_nSmthTemHeight;
  620. nTempWidth  = dlgSmth.m_nSmthTemWidth;
  621. nTempCenX = dlgSmth.m_nSmthTemCenX;
  622. nTempCenY = dlgSmth.m_nSmthTemCenY;
  623. dbTempCoef  = dlgSmth.m_dbSmthTemCoef;
  624. // 删除对话框
  625. delete dlgSmth;
  626. // 更改光标形状
  627. BeginWaitCursor();
  628. // 调用Template()函数平滑DIB
  629. if (GeneralTemplate(pDoc->m_pDibInit, nTempWidth, nTempHeight, 
  630. nTempCenX, nTempCenY, pdbTemp, dbTempCoef))
  631. {
  632. // 设置脏标记
  633. pDoc->SetModifiedFlag(TRUE);
  634. // 更新视图
  635. pDoc->UpdateAllViews(NULL);
  636. }
  637. else
  638. {
  639. // 提示用户
  640. MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);
  641. }
  642. // 恢复光标
  643. EndWaitCursor();
  644. }
  645. /*************************************************************************
  646.  *
  647.  * 函数名称:
  648.  *   OnEnhanceMedian()
  649.  *
  650.  * 输入参数:
  651.  *   无
  652.  * 
  653.  * 返回值:
  654.  *   无
  655.  *
  656.  * 说明:
  657.  *   对图象进行中值滤波,并弹出平滑模板设置对话框
  658.  *
  659.  *************************************************************************
  660.  */
  661. void CImageProcessingView::OnEnhanceMedian() 
  662. {
  663. // 中值滤波
  664. // 获取文档
  665. CImageProcessingDoc* pDoc = GetDocument();
  666. // 滤波器的高度
  667. int nFilterHeight;
  668. // 滤波器的宽度
  669. int nFilterWidth;
  670. // 中心元素的X坐标
  671. int nFilterCenX;
  672. // 中心元素的Y坐标
  673. int nFilterCenY;
  674. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平滑,其它的可以类推)
  675. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  676. {
  677. // 提示用户
  678. MessageBox("目前只支持256色位图的平滑!", "系统提示" , 
  679. MB_ICONINFORMATION | MB_OK);
  680. // 返回
  681. return;
  682. }
  683. // 创建对话框
  684. CDlgMedian dlgMedian;
  685. // 初始化变量值
  686. dlgMedian.m_nFilterType = 0;
  687. dlgMedian.m_nFilterHeight = 3;
  688. dlgMedian.m_nFilterWidth = 1;
  689. dlgMedian.m_nFilterCenX = 0;
  690. dlgMedian.m_nFilterCenY = 1;
  691. // 显示对话框,提示用户设定平移量
  692. if (dlgMedian.DoModal() != IDOK)
  693. {
  694. // 返回
  695. return;
  696. }
  697. // 获取用户的设定
  698. nFilterHeight = dlgMedian.m_nFilterHeight;
  699. nFilterWidth = dlgMedian.m_nFilterWidth;
  700. nFilterCenX = dlgMedian.m_nFilterCenX;
  701. nFilterCenY = dlgMedian.m_nFilterCenY;
  702. // 删除对话框
  703. delete dlgMedian;
  704. // 更改光标形状
  705. BeginWaitCursor();
  706. // 调用MedianFilter()函数中值滤波
  707. if (MedianFilter(pDoc->m_pDibInit, nFilterWidth,
  708. nFilterHeight, nFilterCenX, nFilterCenY ))
  709. {
  710. // 设置脏标记
  711. pDoc->SetModifiedFlag(TRUE);
  712. // 更新视图
  713. pDoc->UpdateAllViews(NULL);
  714. }
  715. else
  716. {
  717. // 提示用户
  718. MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);
  719. }
  720. // 恢复光标
  721. EndWaitCursor();
  722. // 设置脏标记
  723. pDoc->SetModifiedFlag(TRUE);
  724. // 更新视图
  725. pDoc->UpdateAllViews(NULL);
  726. }
  727. void CImageProcessingView::OnEnhancePseudcolor() 
  728. {
  729. // 伪彩色编码
  730. // 获取文档
  731. CImageProcessingDoc* pDoc = GetDocument();
  732. // 保存用户选择的伪彩色编码表索引
  733. int nColor;
  734. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平滑,其它的可以类推)
  735. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  736. {
  737. // 提示用户
  738. MessageBox("目前只支持256色位图的伪彩色变换!", "系统提示" , 
  739. MB_ICONINFORMATION | MB_OK);
  740. // 返回
  741. return;
  742. }
  743. // 参数对话框
  744. CDlgEnhColor dlgPara;
  745. // 初始化变量值
  746. if (pDoc->m_nColorIndex >= 0)
  747. {
  748. // 初始选中当前的伪彩色
  749. dlgPara.m_nColor = pDoc->m_nColorIndex;
  750. }
  751. else
  752. {
  753. // 初始选中灰度伪彩色编码表
  754. dlgPara.m_nColor = 0;
  755. }
  756. // 指向名称数组的指针
  757. dlgPara.m_lpColorName = (LPSTR) ColorScaleName;
  758. // 伪彩色编码数目
  759. dlgPara.m_nColorCount = COLOR_SCALE_COUNT;
  760. // 名称字符串长度
  761. dlgPara.m_nNameLen = sizeof(ColorScaleName) / COLOR_SCALE_COUNT;
  762. // 显示对话框,提示用户设定平移量
  763. if (dlgPara.DoModal() != IDOK)
  764. {
  765. // 返回
  766. return;
  767. }
  768. // 获取用户的设定
  769. nColor = dlgPara.m_nColor;
  770. // 删除对话框
  771. delete dlgPara;
  772. // 更改光标形状
  773. BeginWaitCursor();
  774. // 判断伪彩色编码是否改动
  775. if (pDoc->m_nColorIndex != nColor)
  776. {
  777. // 调用ReplaceColorPal()函数变换调色板
  778. ReplaceDIBColorTable(pDoc->m_pDibInit, (LPBYTE)ColorsTable[nColor]);
  779. // 更新调色板
  780. pDoc->m_pDibInit->MakePalette();
  781. // 更新类成员变量
  782. pDoc->m_nColorIndex = nColor;
  783. // 设置脏标记
  784. pDoc->SetModifiedFlag(TRUE);
  785. // 更新视图
  786. pDoc->UpdateAllViews(NULL);
  787. }
  788. // 恢复光标
  789. EndWaitCursor();
  790. }
  791. void CImageProcessingView::OnTransDwt() 
  792. {
  793. // 获得文档类指针
  794. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  795. // 指向图象的指针
  796. CDib * pDib = pDoc->m_pDibInit;
  797. // 更改光标形状
  798. BeginWaitCursor();
  799. // 进行小波变换
  800. int rsl = DIBDWTStep(pDib,0);
  801. // 恢复光标形状
  802. EndWaitCursor();
  803. // 如果小波变换不成功,则直接返回
  804. if (!rsl)
  805. return;
  806. // 设置脏标志
  807. pDoc->SetModifiedFlag(TRUE);
  808. // 更新显示
  809. pDoc->UpdateAllViews(FALSE);
  810. }
  811. void CImageProcessingView::OnTransIdwt() 
  812. {
  813. // 获得文档类指针
  814. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  815. // 指向图象的指针
  816. CDib * pDib = pDoc->m_pDibInit;
  817. // 更改光标形状
  818. BeginWaitCursor();
  819. // 进行小波反变换
  820. int rsl = DIBDWTStep(pDib,1);
  821. // 恢复光标形状
  822. EndWaitCursor();
  823. // 如果小波变换不成功,则直接返回
  824. if (!rsl)
  825. return;
  826. pDoc->UpdateAllViews(FALSE);
  827. // 设置脏标记
  828. pDoc->SetModifiedFlag(TRUE);
  829. // 更新视图
  830. pDoc->UpdateAllViews(NULL);
  831. }
  832. BOOL CImageProcessingView::DIBDWTStep(CDib* pDib, int nInv)
  833. {
  834. // 循环变量
  835. int i, j;
  836. // 获取图象的长度和宽度
  837. int nWidth  = pDib->m_lpBMIH->biWidth;
  838. int nHeight = pDib->m_lpBMIH->biHeight;
  839. // 获取变换的最大层数
  840. int nMaxWLevel = Log2(nWidth);
  841. int nMaxHLevel = Log2(nHeight);
  842. int nMaxLevel;
  843. if (nWidth == 1<<nMaxWLevel && nHeight == 1<<nMaxHLevel)
  844. nMaxLevel = min(nMaxWLevel, nMaxHLevel);
  845. // 获取图象的存储尺寸
  846. CSize sizeImageSave = pDib->GetDibSaveDim();
  847. // 临时变量
  848. double *pDbTemp;
  849. BYTE *pBits;
  850. // 如果小波变换的存储内存还没有分配,则分配此内存
  851. if(!m_pDbImage){
  852. m_pDbImage = new double[nWidth*nHeight];
  853. if (!m_pDbImage) return FALSE;
  854. // 将图象数据放入m_pDbImage中 
  855. for (j=0; j<nHeight; j++)
  856. {
  857. pDbTemp = m_pDbImage + j*sizeImageSave.cx;
  858. pBits = pDib->m_lpImage + (nHeight-1-j)*sizeImageSave.cx;
  859. for (i=0; i<nWidth; i++)
  860. pDbTemp[i] = pBits[i];
  861. }
  862. }
  863. // 进行小波变换(或反变换)
  864. if (!DWTStep_2D(m_pDbImage, nMaxWLevel-m_nDWTCurDepth, nMaxHLevel-m_nDWTCurDepth,
  865. nMaxWLevel, nMaxHLevel, nInv, 1, m_nSupp))
  866. return FALSE;
  867. // 如果是反变换,则当前层数减1
  868. if (nInv)
  869. m_nDWTCurDepth --;
  870. // 否则加1
  871. else
  872. m_nDWTCurDepth ++;
  873. // 然后,将数据拷贝回原CDib中,并进行相应的数据转换
  874. int lfw = nWidth>>m_nDWTCurDepth, lfh = nHeight>>m_nDWTCurDepth;
  875. for (j=0; j<nHeight; j++)
  876. {
  877. pDbTemp = m_pDbImage + j*sizeImageSave.cx;
  878. pBits = pDib->m_lpImage + (nHeight-1-j)*sizeImageSave.cx;
  879. for (i=0; i<nWidth; i++)
  880. {
  881. if (j<lfh && i<lfw)
  882. pBits[i] = FloatToByte(pDbTemp[i]);
  883. else
  884. pBits[i] = BYTE(FloatToChar(pDbTemp[i]) ^ 0x80);
  885. }
  886. }
  887. // 返回
  888. return TRUE;
  889. }
  890. void CImageProcessingView::OnEnhanceLintrans() 
  891. {
  892. // 获取文档
  893. CImageProcessingDoc* pDoc = GetDocument();
  894. // 创建对话框
  895. CDlgEhnLinTrans dlgPara;
  896. // 点1坐标
  897. int nX1;
  898. int nY1;
  899. // 点2坐标
  900. int nX2;
  901. int nY2;
  902. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的灰度拉伸,其它的可以类推)
  903. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  904. {
  905. // 提示用户
  906. MessageBox("目前只支持256色位图的伪彩色变换!", "系统提示" , 
  907. MB_ICONINFORMATION | MB_OK);
  908. // 返回
  909. return;
  910. }
  911. // 初始化变量值
  912. dlgPara.m_nX1 = 50;
  913. dlgPara.m_nY1 = 30;
  914. dlgPara.m_nX2 = 200;
  915. dlgPara.m_nY2 = 220;
  916. // 显示对话框,提示用户设定拉伸位置
  917. if (dlgPara.DoModal() != IDOK)
  918. {
  919. // 返回
  920. return;
  921. }
  922. // 获取用户的设定
  923. nX1 = dlgPara.m_nX1;
  924. nY1 = dlgPara.m_nY1;
  925. nX2 = dlgPara.m_nX2;
  926. nY2 = dlgPara.m_nY2;
  927. // 删除对话框
  928. delete dlgPara;
  929. // 更改光标形状
  930. BeginWaitCursor();
  931. // 调用GrayStretch()函数进行灰度拉伸
  932. GraySegLinTrans(pDoc->m_pDibInit, nX1, nY1, nX2, nY2);
  933. // 设置脏标记
  934. pDoc->SetModifiedFlag(TRUE);
  935. // 更新视图
  936. pDoc->UpdateAllViews(NULL);
  937. // 恢复光标
  938. EndWaitCursor();
  939. }
  940. void CImageProcessingView::OnEnhanceHistequ() 
  941. {
  942. // 直方图均衡
  943. // 获取文档
  944. CImageProcessingDoc* pDoc = GetDocument();
  945. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的直方图均衡,其它的可以类推)
  946. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  947. {
  948. // 提示用户
  949. MessageBox("目前只支持256色位图的伪彩色变换!", "系统提示" , 
  950. MB_ICONINFORMATION | MB_OK);
  951. // 返回
  952. return;
  953. }
  954. // 更改光标形状
  955. BeginWaitCursor();
  956. // 调用HistogramEqualize()函数进行直方图均衡
  957. HistogramEqualize(pDoc->m_pDibInit);
  958. // 设置脏标记
  959. pDoc->SetModifiedFlag(TRUE);
  960. // 更新视图
  961. pDoc->UpdateAllViews(NULL);
  962. // 恢复光标
  963. EndWaitCursor();
  964. }
  965. /*************************************************************************
  966.  *
  967.  * 函数名称:
  968.  *   OnRegReg()
  969.  *
  970.  * 输入参数:
  971.  *   无
  972.  * 
  973.  * 返回值:
  974.  *   无
  975.  *
  976.  * 说明:
  977.  *   该函数实现图象的配准
  978.  *
  979.  *************************************************************************
  980.  */
  981. void CImageProcessingView::OnRegReg() 
  982. {
  983. // 获得文档类句柄
  984. CImageProcessingDoc* pDoc;
  985. pDoc = GetDocument();
  986. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的水平镜像,其它的可以类推)
  987. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  988. {
  989. // 提示用户
  990. MessageBox("目前只支持256色位图的图象配准!", "系统提示" , 
  991. MB_ICONINFORMATION | MB_OK);
  992. // 返回
  993. return;
  994. }
  995. // 打开图象配准对话框
  996. CDlgReg* pDlg=new CDlgReg(NULL,pDoc);
  997. pDlg->DoModal();
  998. delete pDlg;
  999. }
  1000. /*************************************************************************
  1001.  *
  1002.  * 函数名称:
  1003.  *   OnEnhanceSharp()
  1004.  *
  1005.  * 输入参数:
  1006.  *   无
  1007.  * 
  1008.  * 返回值:
  1009.  *   无
  1010.  *
  1011.  * 说明:
  1012.  *   该函数利用Laplacian算子实现图象的锐化
  1013.  *
  1014.  *************************************************************************
  1015.  */
  1016. void CImageProcessingView::OnEnhanceSharp() 
  1017. {
  1018. //更改光标形状
  1019. BeginWaitCursor(); 
  1020. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1021. CDib * pDib = pDoc->m_pDibInit;
  1022. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1023. // 判断是否是8-bpp位图
  1024. if (lpBMIH->biBitCount != 8)
  1025. {
  1026. // 提示用户
  1027. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1028. MB_ICONINFORMATION | MB_OK);
  1029. // 返回
  1030. return;
  1031. }
  1032. // 循环控制变量
  1033. int y;
  1034. int x;
  1035. CSize sizeImage = pDib->GetDimensions();
  1036. int nWidth = sizeImage.cx ;
  1037. int nHeight= sizeImage.cy ;
  1038. int nSaveWidth = pDib->GetDibSaveDim().cx;
  1039. // 开辟内存,存储图象数据,该数据的存储不是DWORD对齐的
  1040. unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
  1041. for(y=0; y<nHeight; y++)
  1042. {
  1043. for(x=0; x<nWidth; x++)
  1044. {
  1045. pUnchImage[y*nWidth+x] = pDib->m_lpImage[y*nSaveWidth+x];
  1046. }
  1047. }
  1048. // 调用LinearSharpen函数进行图象锐化增强
  1049. LinearSharpen(pUnchImage, nWidth, nHeight) ;
  1050. // 增强以后的图象拷贝到pDib中,进行显示
  1051. for(y=0; y<nHeight; y++)
  1052. {
  1053. for(x=0; x<nWidth; x++)
  1054. {
  1055. pDib->m_lpImage[y*nSaveWidth+x] = pUnchImage[y*nWidth+x];
  1056. }
  1057. }
  1058. // 释放内存
  1059. delete []pUnchImage;
  1060. pUnchImage = NULL  ;
  1061. // 恢复光标形状
  1062. EndWaitCursor(); 
  1063. // 设置脏标记
  1064. pDoc->SetModifiedFlag(TRUE);
  1065. // 更新视图
  1066. pDoc->UpdateAllViews(NULL);
  1067. }
  1068. /*************************************************************************
  1069. *
  1070. * 函数名称:
  1071. *   OnEnhanceSmoothFr()
  1072. *
  1073. * 输入参数:
  1074. *   无
  1075. *
  1076. * 返回值:
  1077. *   无
  1078. *
  1079. * 说明:
  1080. *   该函数利用低通滤波实现图象平滑
  1081. *
  1082. ************************************************************************
  1083. */
  1084. void CImageProcessingView::OnEnhanceSmoothFr() 
  1085. {
  1086. // TODO: Add your command handler code here
  1087. //更改光标形状
  1088. BeginWaitCursor(); 
  1089. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1090. CDib * pDib = pDoc->m_pDibInit;
  1091. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1092. // 判断是否是8-bpp位图
  1093. if (lpBMIH->biBitCount != 8)
  1094. {
  1095. // 提示用户
  1096. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1097. MB_ICONINFORMATION | MB_OK);
  1098. // 返回
  1099. return;
  1100. }
  1101. // 循环控制变量
  1102. int y;
  1103. int x;
  1104. CSize sizeImage = pDib->GetDimensions();
  1105. int nWidth = sizeImage.cx ;
  1106. int nHeight= sizeImage.cy ;
  1107. int nSaveWidth = pDib->GetDibSaveDim().cx;
  1108. // 开辟内存,存储图象数据,该数据的存储不是DWORD对齐的
  1109. unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
  1110. for(y=0; y<nHeight; y++)
  1111. {
  1112. for(x=0; x<nWidth; x++)
  1113. {
  1114. pUnchImage[y*nWidth+x] = pDib->m_lpImage[y*nSaveWidth+x];
  1115. }
  1116. }
  1117. // 调用低通滤波函数进行图象增强
  1118. LowPassFilterEnhance(pUnchImage, nWidth, nHeight, nWidth/16) ;
  1119. // 增强以后的图象拷贝到pDib中,进行显示
  1120. for(y=0; y<nHeight; y++)
  1121. {
  1122. for(x=0; x<nWidth; x++)
  1123. {
  1124. pDib->m_lpImage[y*nSaveWidth+x] = pUnchImage[y*nWidth+x];
  1125. }
  1126. }
  1127. // 释放内存
  1128. delete []pUnchImage;
  1129. pUnchImage = NULL  ;
  1130. // 恢复光标形状
  1131. EndWaitCursor(); 
  1132. // 设置脏标记
  1133. pDoc->SetModifiedFlag(TRUE);
  1134. // 更新视图
  1135. pDoc->UpdateAllViews(NULL);
  1136. }
  1137. /*************************************************************************
  1138. *
  1139. * 函数名称:
  1140. *   OnEnhanceButtLow()
  1141. *
  1142. * 输入参数:
  1143. *   无
  1144. *
  1145. * 返回值:
  1146. *   无
  1147. *
  1148. * 说明:
  1149. *   该函数利用Butterworth低通滤波实现图象平滑
  1150. *
  1151. ************************************************************************
  1152. */
  1153. void CImageProcessingView::OnEnhanceButtLow() 
  1154. {
  1155. // TODO: Add your command handler code here
  1156. //更改光标形状
  1157. BeginWaitCursor(); 
  1158. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1159. CDib * pDib = pDoc->m_pDibInit;
  1160. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1161. // 判断是否是8-bpp位图
  1162. if (lpBMIH->biBitCount != 8)
  1163. {
  1164. // 提示用户
  1165. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1166. MB_ICONINFORMATION | MB_OK);
  1167. // 返回
  1168. return;
  1169. }
  1170. // 循环控制变量
  1171. int y;
  1172. int x;
  1173. CSize sizeImage = pDib->GetDimensions();
  1174. int nWidth = sizeImage.cx ;
  1175. int nHeight= sizeImage.cy ;
  1176. int nSaveWidth = pDib->GetDibSaveDim().cx;
  1177. // 开辟内存,存储图象数据,该数据的存储不是DWORD对齐的
  1178. unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
  1179. for(y=0; y<nHeight; y++)
  1180. {
  1181. for(x=0; x<nWidth; x++)
  1182. {
  1183. pUnchImage[y*nWidth+x] = pDib->m_lpImage[y*nSaveWidth+x];
  1184. }
  1185. }
  1186. // 调用ButterWorth低通滤波函数进行图象增强
  1187. ButterWorthLowPass(pUnchImage, nWidth, nHeight, nWidth/2) ;
  1188. // 增强以后的图象拷贝到pDib中,进行显示
  1189. for(y=0; y<nHeight; y++)
  1190. {
  1191. for(x=0; x<nWidth; x++)
  1192. {
  1193. pDib->m_lpImage[y*nSaveWidth+x] = pUnchImage[y*nWidth+x];
  1194. }
  1195. }
  1196. // 释放内存
  1197. delete []pUnchImage;
  1198. pUnchImage = NULL  ;
  1199. // 恢复光标形状
  1200. EndWaitCursor(); 
  1201. // 设置脏标记
  1202. pDoc->SetModifiedFlag(TRUE);
  1203. // 更新视图
  1204. pDoc->UpdateAllViews(NULL);
  1205. }
  1206. /*************************************************************************
  1207. *
  1208. * 函数名称:
  1209. *   OnEnhanceSharpFreq()
  1210. *
  1211. * 输入参数:
  1212. *   无
  1213. *
  1214. * 返回值:
  1215. *   无
  1216. *
  1217. * 说明:
  1218. *   该函数利用高通滤波实现图象增强
  1219. *
  1220. ************************************************************************
  1221. */
  1222. void CImageProcessingView::OnEnhanceSharpFreq() 
  1223. {
  1224. // TODO: Add your command handler code here
  1225. //更改光标形状
  1226. BeginWaitCursor(); 
  1227. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1228. CDib * pDib = pDoc->m_pDibInit;
  1229. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1230. // 判断是否是8-bpp位图
  1231. if (lpBMIH->biBitCount != 8)
  1232. {
  1233. // 提示用户
  1234. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1235. MB_ICONINFORMATION | MB_OK);
  1236. // 返回
  1237. return;
  1238. }
  1239. // 循环控制变量
  1240. int y;
  1241. int x;
  1242. CSize sizeImage = pDib->GetDimensions();
  1243. int nWidth = sizeImage.cx ;
  1244. int nHeight= sizeImage.cy ;
  1245. int nSaveWidth = pDib->GetDibSaveDim().cx;
  1246. // 开辟内存,存储图象数据,该数据的存储不是DWORD对齐的
  1247. unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
  1248. for(y=0; y<nHeight; y++)
  1249. {
  1250. for(x=0; x<nWidth; x++)
  1251. {
  1252. pUnchImage[y*nWidth+x] = pDib->m_lpImage[y*nSaveWidth+x];
  1253. }
  1254. }
  1255. // 调用高通滤波函数进行图象增强
  1256. HighPassFilterEnhance(pUnchImage, nWidth, nHeight, 50) ;
  1257. // 增强以后的图象拷贝到pDib中,进行显示
  1258. for(y=0; y<nHeight; y++)
  1259. {
  1260. for(x=0; x<nWidth; x++)
  1261. {
  1262. pDib->m_lpImage[y*nSaveWidth+x] = pUnchImage[y*nWidth+x];
  1263. }
  1264. }
  1265. // 释放内存
  1266. delete []pUnchImage;
  1267. pUnchImage = NULL  ;
  1268. // 恢复光标形状
  1269. EndWaitCursor(); 
  1270. // 设置脏标记
  1271. pDoc->SetModifiedFlag(TRUE);
  1272. // 更新视图
  1273. pDoc->UpdateAllViews(NULL);
  1274. }
  1275. /*************************************************************************
  1276. *
  1277. * 函数名称:
  1278. *   OnEnhanceButtHight()
  1279. *
  1280. * 输入参数:
  1281. *   无
  1282. *
  1283. * 返回值:
  1284. *   无
  1285. *
  1286. * 说明:
  1287. *   该函数利用Butterworth高通滤波实现图象平滑
  1288. *
  1289. ************************************************************************
  1290. */
  1291. void CImageProcessingView::OnEnhanceButtHight() 
  1292. {
  1293. //更改光标形状
  1294. BeginWaitCursor(); 
  1295. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1296. CDib * pDib = pDoc->m_pDibInit;
  1297. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1298. // 判断是否是8-bpp位图
  1299. if (lpBMIH->biBitCount != 8)
  1300. {
  1301. // 提示用户
  1302. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1303. MB_ICONINFORMATION | MB_OK);
  1304. // 返回
  1305. return;
  1306. }
  1307. // 循环控制变量
  1308. int y;
  1309. int x;
  1310. CSize sizeImage = pDib->GetDimensions();
  1311. int nWidth = sizeImage.cx ;
  1312. int nHeight= sizeImage.cy ;
  1313. int nSaveWidth = pDib->GetDibSaveDim().cx;
  1314. // 开辟内存,存储图象数据,该数据的存储不是DWORD对齐的
  1315. unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
  1316. for(y=0; y<nHeight; y++)
  1317. {
  1318. for(x=0; x<nWidth; x++)
  1319. {
  1320. pUnchImage[y*nWidth+x] = pDib->m_lpImage[y*nSaveWidth+x];
  1321. }
  1322. }
  1323. // 调用ButterWorth高通滤波函数进行图象增强
  1324. ButterWorthHighPass(pUnchImage, nWidth, nHeight, nWidth/2) ;
  1325. // 增强以后的图象拷贝到pDib中,进行显示
  1326. for(y=0; y<nHeight; y++)
  1327. {
  1328. for(x=0; x<nWidth; x++)
  1329. {
  1330. pDib->m_lpImage[y*nSaveWidth+x] = pUnchImage[y*nWidth+x];
  1331. }
  1332. }
  1333. // 释放内存
  1334. delete []pUnchImage;
  1335. pUnchImage = NULL  ;
  1336. // 恢复光标形状
  1337. EndWaitCursor(); 
  1338. // 设置脏标记
  1339. pDoc->SetModifiedFlag(TRUE);
  1340. // 更新视图
  1341. pDoc->UpdateAllViews(NULL);
  1342. }
  1343. /*************************************************************************
  1344. *
  1345. * 函数名称:
  1346. *   OnRegionsegFix()
  1347. *
  1348. * 输入参数:
  1349. *   无
  1350. *
  1351. * 返回值:
  1352. *   无
  1353. *
  1354. * 说明:
  1355. *   实现并行区域分割
  1356. *
  1357. ************************************************************************
  1358. */
  1359. void CImageProcessingView::OnRegionsegFix() 
  1360. {
  1361. // TODO: Add your command handler code here
  1362. //更改光标形状
  1363. BeginWaitCursor(); 
  1364. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1365. CDib * pDib = pDoc->m_pDibInit;
  1366. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1367. // 判断是否是8-bpp位图
  1368. if (lpBMIH->biBitCount != 8)
  1369. {
  1370. // 提示用户
  1371. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1372. MB_ICONINFORMATION | MB_OK);
  1373. // 返回
  1374. return;
  1375. }
  1376. // 调用函数实现固定阈值分割
  1377. RegionSegFixThreshold(pDib,200);
  1378. // 恢复光标形状
  1379. EndWaitCursor(); 
  1380. // 设置脏标记
  1381. pDoc->SetModifiedFlag(TRUE);
  1382. // 更新视图
  1383. pDoc->UpdateAllViews(NULL);
  1384. }
  1385. /*************************************************************************
  1386. *
  1387. * 函数名称:
  1388. *   OnAdaRegionSeg()
  1389. *
  1390. * 输入参数:
  1391. *   无
  1392. *
  1393. * 返回值:
  1394. *   无
  1395. *
  1396. * 说明:
  1397. *   实现自适应区域分割算法
  1398. *
  1399. ************************************************************************
  1400. */
  1401. void CImageProcessingView::OnAdaRegionSeg() 
  1402. {
  1403. // TODO: Add your command handler code here
  1404. //更改光标形状
  1405. BeginWaitCursor(); 
  1406. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1407. CDib * pDib = pDoc->m_pDibInit;
  1408. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1409. // 判断是否是8-bpp位图
  1410. if (lpBMIH->biBitCount != 8)
  1411. {
  1412. // 提示用户
  1413. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1414. MB_ICONINFORMATION | MB_OK);
  1415. // 返回
  1416. return;
  1417. }
  1418. // 自适应区域分割
  1419. RegionSegAdaptive(pDib);
  1420. // 恢复光标形状
  1421. EndWaitCursor(); 
  1422. // 设置脏标记
  1423. pDoc->SetModifiedFlag(TRUE);
  1424. // 更新视图
  1425. pDoc->UpdateAllViews(NULL);
  1426. }
  1427. /*************************************************************************
  1428. *
  1429. * 函数名称:
  1430. *   OnEdgeRoberts()
  1431. *
  1432. * 输入参数:
  1433. *   无
  1434. *
  1435. * 返回值:
  1436. *   无
  1437. *
  1438. * 说明:
  1439. *   实现并行边界分割-Roberts算子
  1440. *
  1441. ************************************************************************
  1442. */
  1443. void CImageProcessingView::OnEdgeRoberts() 
  1444. {
  1445. // TODO: Add your command handler code here
  1446. //更改光标形状
  1447. BeginWaitCursor(); 
  1448. // 循环控制变量
  1449. int y;
  1450. int x;
  1451. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1452. CDib * pDib = pDoc->m_pDibInit;
  1453. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1454. // 判断是否是8-bpp位图
  1455. if (lpBMIH->biBitCount != 8)
  1456. {
  1457. // 提示用户
  1458. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1459. MB_ICONINFORMATION | MB_OK);
  1460. // 返回
  1461. return;
  1462. }
  1463. // 图象的长宽大小
  1464. CSize sizeImage = pDib->GetDimensions();
  1465. int nWidth = sizeImage.cx ;
  1466. int nHeight = sizeImage.cy ;
  1467. // 指向梯度数据的指针
  1468. double * pdGrad;
  1469. // 按照图像的大小开辟内存空间,存储梯度计算的结果
  1470. pdGrad=new double[nHeight*nWidth];
  1471. //图像数据的指针
  1472. LPBYTE  pImageData = pDib->m_lpImage;
  1473. // 图像在计算机在存储中的实际大小
  1474. CSize sizeImageSave = pDib->GetDibSaveDim();
  1475. // 图像在内存中每一行象素占用的实际空间
  1476. int nSaveWidth = sizeImageSave.cx;
  1477. // 应用Roberts算子求梯度
  1478. RobertsOperator(pDib, pdGrad);
  1479. for(y=0; y<nHeight ; y++ )
  1480. for(x=0 ; x<nWidth ; x++ )
  1481. {
  1482. if(*(pdGrad+y*nWidth+x)>50)
  1483. *( pImageData+y*nSaveWidth+x )=0;
  1484. else
  1485. *( pImageData+y*nSaveWidth+x )=255;
  1486. }
  1487.   //释放梯度结果使用的内存空间
  1488. delete pdGrad;
  1489. pdGrad=NULL;
  1490. // 恢复光标形状
  1491. EndWaitCursor(); 
  1492. // 设置脏标记
  1493. pDoc->SetModifiedFlag(TRUE);
  1494. // 更新视图
  1495. pDoc->UpdateAllViews(NULL);
  1496. }
  1497. /*************************************************************************
  1498. *
  1499. * 函数名称:
  1500. *   OnEdgeSobel()
  1501. *
  1502. * 输入参数:
  1503. *   无
  1504. *
  1505. * 返回值:
  1506. *   无
  1507. *
  1508. * 说明:
  1509. *   实现并行边界分割-Sobel算子
  1510. *
  1511. ************************************************************************
  1512. */
  1513. void CImageProcessingView::OnEdgeSobel() 
  1514. {
  1515. // TODO: Add your command handler code here
  1516. //更改光标形状
  1517. BeginWaitCursor(); 
  1518. // 循环控制变量
  1519. int y;
  1520. int x;
  1521. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1522. CDib * pDib = pDoc->m_pDibInit;
  1523. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1524. // 判断是否是8-bpp位图
  1525. if (lpBMIH->biBitCount != 8)
  1526. {
  1527. // 提示用户
  1528. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1529. MB_ICONINFORMATION | MB_OK);
  1530. // 返回
  1531. return;
  1532. }
  1533. // 图象的长宽大小
  1534. CSize sizeImage = pDib->GetDimensions();
  1535. int nWidth = sizeImage.cx ;
  1536. int nHeight = sizeImage.cy ;
  1537. // 指向梯度数据的指针
  1538. double * pdGrad;
  1539. // 按照图像的大小开辟内存空间,存储梯度计算的结果
  1540. pdGrad=new double[nHeight*nWidth];
  1541. //图像数据的指针
  1542. LPBYTE  lpImage = pDib->m_lpImage;
  1543. // 图像在计算机在存储中的实际大小
  1544. CSize sizeImageSave = pDib->GetDibSaveDim();
  1545. // 图像在内存中每一行象素占用的实际空间
  1546. int nSaveWidth = sizeImageSave.cx;
  1547. // 应用Sobel算子求梯度
  1548. SobelOperator(pDib, pdGrad);
  1549. for(y=0; y<nHeight ; y++ )
  1550. for(x=0 ; x<nWidth ; x++ )
  1551. {
  1552. if(*(pdGrad+y*nWidth+x)>50)
  1553. *( lpImage+y*nSaveWidth+x )=0;
  1554. else
  1555. *( lpImage+y*nSaveWidth+x )=255;
  1556. }
  1557.   //释放内存空间
  1558. delete []pdGrad;
  1559. pdGrad=NULL;
  1560. // 恢复光标形状
  1561. EndWaitCursor(); 
  1562. // 设置脏标记
  1563. pDoc->SetModifiedFlag(TRUE);
  1564. // 更新视图
  1565. pDoc->UpdateAllViews(NULL);
  1566. }
  1567. /*************************************************************************
  1568. *
  1569. * 函数名称:
  1570. *   OnEdgePrewitt()
  1571. *
  1572. * 输入参数:
  1573. *   无
  1574. *
  1575. * 返回值:
  1576. *   无
  1577. *
  1578. * 说明:
  1579. *   实现并行边界分割-Prewitt算子
  1580. *
  1581. ************************************************************************
  1582. */
  1583. void CImageProcessingView::OnEdgePrewitt() 
  1584. {
  1585. // TODO: Add your command handler code here
  1586. //更改光标形状
  1587. BeginWaitCursor(); 
  1588. // 循环控制变量
  1589. int y;
  1590. int x;
  1591. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1592. CDib * pDib = pDoc->m_pDibInit;
  1593. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1594. // 判断是否是8-bpp位图
  1595. if (lpBMIH->biBitCount != 8)
  1596. {
  1597. // 提示用户
  1598. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1599. MB_ICONINFORMATION | MB_OK);
  1600. // 返回
  1601. return;
  1602. }
  1603. // 图象的长宽大小
  1604. CSize sizeImage = pDib->GetDimensions();
  1605. int nWidth = sizeImage.cx ;
  1606. int nHeight = sizeImage.cy ;
  1607. // 指向梯度数据的指针
  1608. double * pdGrad;
  1609. // 按照图像的大小开辟内存空间,存储梯度计算的结果
  1610. pdGrad=new double[nHeight*nWidth];
  1611. //图像数据的指针
  1612. LPBYTE  lpImage = pDib->m_lpImage;
  1613. // 图像在计算机在存储中的实际大小
  1614. CSize sizeImageSave = pDib->GetDibSaveDim();
  1615. // 图像在内存中每一行象素占用的实际空间
  1616. int nSaveWidth = sizeImageSave.cx;
  1617. // 应用Prewitt算子求梯度
  1618. PrewittOperator(pDib, pdGrad);
  1619. for(y=0; y<nHeight ; y++ )
  1620. for(x=0 ; x<nWidth ; x++ )
  1621. {
  1622. if(*(pdGrad+y*nWidth+x)>50)
  1623. *( lpImage+y*nSaveWidth+x )=0;
  1624. else
  1625. *( lpImage+y*nSaveWidth+x )=255;
  1626. }
  1627.   //释放内存空间
  1628. delete []pdGrad;
  1629. pdGrad=NULL;
  1630. // 恢复光标形状
  1631. EndWaitCursor(); 
  1632. // 设置脏标记
  1633. pDoc->SetModifiedFlag(TRUE);
  1634. // 更新视图
  1635. pDoc->UpdateAllViews(NULL);
  1636. }
  1637. /*************************************************************************
  1638. *
  1639. * 函数名称:
  1640. *   OnEdgeLaplace()
  1641. *
  1642. * 输入参数:
  1643. *   无
  1644. *
  1645. * 返回值:
  1646. *   无
  1647. *
  1648. * 说明:
  1649. *   实现并行边界分割-拉普拉斯算子
  1650. *
  1651. ************************************************************************
  1652. */
  1653. void CImageProcessingView::OnEdgeLaplace() 
  1654. {
  1655. // TODO: Add your command handler code here
  1656. //更改光标形状
  1657. BeginWaitCursor(); 
  1658. // 循环控制变量
  1659. int y;
  1660. int x;
  1661. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1662. CDib * pDib = pDoc->m_pDibInit;
  1663. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1664. // 判断是否是8-bpp位图
  1665. if (lpBMIH->biBitCount != 8)
  1666. {
  1667. // 提示用户
  1668. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1669. MB_ICONINFORMATION | MB_OK);
  1670. // 返回
  1671. return;
  1672. }
  1673. // 图象的长宽大小
  1674. CSize sizeImage = pDib->GetDimensions();
  1675. int nWidth = sizeImage.cx ;
  1676. int nHeight = sizeImage.cy ;
  1677. // 指向梯度数据的指针
  1678. double * pdGrad;
  1679. // 按照图像的大小开辟内存空间,存储梯度计算的结果
  1680. pdGrad=new double[nHeight*nWidth];
  1681. //图像数据的指针
  1682. LPBYTE  lpImage = pDib->m_lpImage;
  1683. // 图像在计算机在存储中的实际大小
  1684. CSize sizeImageSave = pDib->GetDibSaveDim();
  1685. // 图像在内存中每一行象素占用的实际空间
  1686. int nSaveWidth = sizeImageSave.cx;
  1687. // 应用Laplace算子求梯度
  1688. LaplacianOperator(pDib, pdGrad);
  1689. for(y=0; y<nHeight ; y++ )
  1690. for(x=0 ; x<nWidth ; x++ )
  1691. {
  1692. if(*(pdGrad+y*nWidth+x)>50)
  1693. *( lpImage+y*nSaveWidth+x )=0;
  1694. else
  1695. *( lpImage+y*nSaveWidth+x )=255;
  1696. }
  1697. //释放内存空间
  1698. delete []pdGrad;
  1699. pdGrad=NULL;
  1700. // 恢复光标形状
  1701. EndWaitCursor(); 
  1702. // 设置脏标记
  1703. pDoc->SetModifiedFlag(TRUE);
  1704. // 更新视图
  1705. pDoc->UpdateAllViews(NULL);
  1706. }
  1707. /*************************************************************************
  1708. *
  1709. * 函数名称:
  1710. *   OnEdgeCanny()
  1711. *
  1712. * 输入参数:
  1713. *   无
  1714. *
  1715. * 返回值:
  1716. *   无
  1717. *
  1718. * 说明:
  1719. *   实现并行边界分割-Canny算子
  1720. *
  1721. ************************************************************************
  1722. */
  1723. void CImageProcessingView::OnEdgeCanny() 
  1724. {
  1725. // TODO: Add your command handler code here
  1726. //更改光标形状
  1727. BeginWaitCursor(); 
  1728. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1729. CDib * pDib = pDoc->m_pDibInit;
  1730. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1731. // 判断是否是8-bpp位图
  1732. if (lpBMIH->biBitCount != 8)
  1733. {
  1734. // 提示用户
  1735. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1736. MB_ICONINFORMATION | MB_OK);
  1737. // 返回
  1738. return;
  1739. }
  1740. // 循环控制变量
  1741. int y; 
  1742. int x;
  1743. CSize sizeImage = pDib->GetDimensions();
  1744. int nWidth = sizeImage.cx ;
  1745. int nHeight= sizeImage.cy ;
  1746. int nSaveWidth = pDib->GetDibSaveDim().cx;
  1747. // 开辟内存,存储图象数据
  1748. unsigned char * pUnchImage = new unsigned char[nWidth*nHeight];
  1749. for(y=0; y<nHeight; y++)
  1750. {
  1751. for(x=0; x<nWidth; x++)
  1752. {
  1753. pUnchImage[y*nWidth+x] = pDib->m_lpImage[y*nSaveWidth+x];
  1754. }
  1755. }
  1756. // canny算子计算后的结果
  1757. unsigned char * pUnchEdge = new unsigned char[nWidth*nHeight];
  1758. // 调用canny函数进行边界提取
  1759. Canny(pUnchImage, nWidth, nHeight, 0.4, 0.4, 0.79, pUnchEdge) ;
  1760. for(y=0; y<nHeight; y++)
  1761. {
  1762. for(x=0; x<nWidth; x++)
  1763. {
  1764. pDib->m_lpImage[y*nWidth+x]=(unsigned char)(255-pUnchEdge[y*nWidth+x]);
  1765. }
  1766. }
  1767. delete []pUnchImage;
  1768. pUnchImage = NULL  ;
  1769. delete []pUnchEdge ;
  1770. pUnchEdge = NULL   ;
  1771. // 恢复光标形状
  1772. EndWaitCursor(); 
  1773. // 设置脏标记
  1774. pDoc->SetModifiedFlag(TRUE);
  1775. // 更新视图
  1776. pDoc->UpdateAllViews(NULL);
  1777. }
  1778. /*************************************************************************
  1779. *
  1780. * 函数名称:
  1781. *   OnEdgeTrack()
  1782. *
  1783. * 输入参数:
  1784. *   无
  1785. *
  1786. * 返回值:
  1787. *   无
  1788. *
  1789. * 说明:
  1790. *   实现边界跟踪算法
  1791. *
  1792. ************************************************************************
  1793. */
  1794. void CImageProcessingView::OnEdgeTrack() 
  1795. {
  1796. // TODO: Add your command handler code here
  1797. //更改光标形状
  1798. BeginWaitCursor(); 
  1799. // 获得Doc类的指
  1800. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1801. CDib * pDib = pDoc->m_pDibInit;
  1802. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1803. // 判断是否是8-bpp位图
  1804. if (lpBMIH->biBitCount != 8)
  1805. {
  1806. // 提示用户
  1807. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1808. MB_ICONINFORMATION | MB_OK);
  1809. // 返回
  1810. return;
  1811. }
  1812. // 图像在计算机在存储中的实际大小
  1813. CSize sizeImageSave = pDib->GetDibSaveDim();
  1814. // 图像在内存中每一行象素占用的实际空间
  1815. int nSaveWidth = sizeImageSave.cx;
  1816. // 遍历图象的纵坐标
  1817. int y;
  1818. // 遍历图象的横坐标
  1819. int x;
  1820. // 图象的长宽大小
  1821. CSize sizeImage = pDib->GetDimensions();
  1822. int nWidth = sizeImage.cx ;
  1823. int nHeight = sizeImage.cy ;
  1824. // 指向图像数据的指针
  1825. LPBYTE lpImage ;
  1826. lpImage = pDib->m_lpImage ;
  1827. // 边界跟踪后的结果区域
  1828. unsigned char * pUnEdgeTrack ;
  1829. pUnEdgeTrack = new unsigned char[nWidth * nHeight] ;
  1830. EdgeTrack(pDib, pUnEdgeTrack);
  1831. for(y=0; y<nHeight; y++)
  1832. {
  1833. for(x=0; x<nWidth; x++)
  1834. {
  1835. lpImage[y*nSaveWidth + x] = (unsigned char) (255-pUnEdgeTrack[y*nWidth + x]);
  1836. }
  1837. }
  1838. //释放内存
  1839. delete pUnEdgeTrack;
  1840. pUnEdgeTrack = NULL;
  1841. // 恢复光标形状
  1842. EndWaitCursor(); 
  1843. // 设置脏标记
  1844. pDoc->SetModifiedFlag(TRUE);
  1845. // 更新视图
  1846. pDoc->UpdateAllViews(NULL);
  1847. }
  1848. /*************************************************************************
  1849. *
  1850. * 函数名称:
  1851. *   OnRegionGrow()
  1852. *
  1853. * 输入参数:
  1854. *   无
  1855. *
  1856. * 返回值:
  1857. *   无
  1858. *
  1859. * 说明:
  1860. *   实现区域生长算法
  1861. *
  1862. ************************************************************************
  1863. */
  1864. void CImageProcessingView::OnRegionGrow() 
  1865. {
  1866. // TODO: Add your command handler code here
  1867. //更改光标形状
  1868. BeginWaitCursor(); 
  1869. // 获得Doc类的指
  1870. CImageProcessingDoc * pDoc = (CImageProcessingDoc *)this->GetDocument();
  1871. CDib * pDib = pDoc->m_pDibInit;
  1872. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  1873. // 判断是否是8-bpp位图
  1874. if (lpBMIH->biBitCount != 8)
  1875. {
  1876. // 提示用户
  1877. MessageBox("目前只支持256色位图的图象分割!", "系统提示" ,
  1878. MB_ICONINFORMATION | MB_OK);
  1879. // 返回
  1880. return;
  1881. }
  1882. // 遍历图象的纵坐标
  1883. int y;
  1884. // 遍历图象的横坐标
  1885. int x;
  1886. // 图像在计算机在存储中的实际大小
  1887. CSize sizeImageSave = pDib->GetDibSaveDim();
  1888. // 图像在内存中每一行象素占用的实际空间
  1889. int nSaveWidth = sizeImageSave.cx;
  1890. // 图象的长宽大小
  1891. CSize sizeImage = pDib->GetDimensions();
  1892. int nWidth = sizeImage.cx ;
  1893. int nHeight = sizeImage.cy ;
  1894. // 指向图像数据的指针
  1895. LPBYTE lpImage ;
  1896. lpImage = pDib->m_lpImage ;
  1897. unsigned char * pUnchRgRst = new unsigned char[nWidth * nHeight];
  1898. // 初始化
  1899. memset(pUnchRgRst, 0 , sizeof(unsigned char)*nWidth*nHeight );
  1900. RegionGrow(pDib, pUnchRgRst);
  1901. for(y=0; y<nHeight; y++)
  1902. for(x=0; x<nWidth; x++)
  1903. {
  1904. lpImage[y*nSaveWidth + x] =(unsigned char) (255-pUnchRgRst[y*nWidth+x] );
  1905. }
  1906. // 释放内存
  1907. delete []pUnchRgRst;
  1908. pUnchRgRst = NULL  ;
  1909. // 恢复光标形状
  1910. EndWaitCursor(); 
  1911. // 设置脏标记
  1912. pDoc->SetModifiedFlag(TRUE);
  1913. // 更新视图
  1914. pDoc->UpdateAllViews(NULL);
  1915. }
  1916. /*************************************************************************
  1917.  *
  1918.  * 函数名称:
  1919.  *   OnMotionBackground()
  1920.  *
  1921.  * 输入参数:
  1922.  *   无
  1923.  * 
  1924.  * 返回值:
  1925.  *   无
  1926.  *
  1927.  * 说明:
  1928.  *   该函数根据运动图象提取其中的静止背景。其中运动图象要求为bmp文件,并按
  1929.  *顺序排列。
  1930.  *
  1931.  *************************************************************************
  1932.  */
  1933. void CImageProcessingView::OnMotionBackground() 
  1934. {
  1935. // 提取背景成功标志
  1936. BOOL bFlag;
  1937. // 获取文档指针
  1938. CImageProcessingDoc* pDoc;
  1939. pDoc = GetDocument();
  1940. // 获得当前打开文件的文件路径名
  1941. CString strPathName;
  1942. strPathName = pDoc->GetPathName();
  1943. // 序列的总帧数
  1944. int nTotalFrameNum = 20;
  1945. // 图象的宽度
  1946. int nImageWidth;
  1947. nImageWidth = pDoc->m_pDibInit->m_lpBMIH->biWidth;
  1948. // 图象的高度
  1949. int nImageHeight;
  1950. nImageHeight = pDoc->m_pDibInit->m_lpBMIH->biHeight;
  1951. // 图象的静止背景
  1952. unsigned char* pUnchBackGround;
  1953. pUnchBackGround = new unsigned char[nImageWidth*nImageHeight];
  1954. // 更改光标形状
  1955. BeginWaitCursor();
  1956. // 调用GetBackground函数提取静止背景
  1957. bFlag = GetBackground(strPathName, nTotalFrameNum, nImageWidth,nImageHeight, pUnchBackGround);
  1958. if(bFlag == FALSE){
  1959. return;
  1960. }
  1961. // 将背景设置为当前显示图象
  1962. LPBYTE lpTemp;
  1963. lpTemp = pDoc->m_pDibInit->m_lpImage;
  1964. // 将数据拷贝到图象中
  1965. memcpy(lpTemp, (LPBYTE)pUnchBackGround, nImageWidth*nImageHeight);
  1966. // 恢复光标形状
  1967. EndWaitCursor(); 
  1968. // 释放已分配内存
  1969. delete[]pUnchBackGround;
  1970. pUnchBackGround = NULL;
  1971. // 设置脏标记
  1972. pDoc->SetModifiedFlag(TRUE);
  1973. // 更新视图
  1974. pDoc->UpdateAllViews(NULL);
  1975. }
  1976. /*************************************************************************
  1977.  *
  1978.  * 函数名称:
  1979.  *   OnRecogMatch()
  1980.  *
  1981.  * 输入参数:
  1982.  *   无
  1983.  * 
  1984.  * 返回值:
  1985.  *   无
  1986.  *
  1987.  * 说明:
  1988.  *   根据图象模板,在待匹配的图象中找到匹配的位置
  1989.  *
  1990.  *************************************************************************
  1991.  */
  1992. void CImageProcessingView::OnRecogMatch() 
  1993. {
  1994. CImageProcessingDoc* pDoc;
  1995. pDoc = GetDocument();
  1996. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的水平镜像,其它的可以类推)
  1997. if(pDoc->m_pDibInit->m_nColorTableEntries != 256)
  1998. {
  1999. // 提示用户
  2000. MessageBox("目前只支持256色位图的图象配准!", "系统提示" , 
  2001. MB_ICONINFORMATION | MB_OK);
  2002. // 返回
  2003. return;
  2004. }
  2005. // 打开图象识别对话框
  2006. CDlgRecMatch* pDlg = new CDlgRecMatch(NULL, pDoc);
  2007. pDlg->DoModal();
  2008. delete pDlg;
  2009. }
  2010. void CImageProcessingView::OnDegenerationInverse() 
  2011. {
  2012. // 图象的模糊
  2013. // 更改光标形状
  2014. BeginWaitCursor();
  2015. // 获取文档
  2016. CImageProcessingDoc* pDoc = GetDocument();
  2017. //  获得图象CDib类的指针
  2018. CDib * pDib = pDoc->m_pDibInit;
  2019. // 获得图象的头文件信息
  2020. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2021. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的图象模糊)
  2022. if (lpBMIH->biBitCount != 8)
  2023. {
  2024. // 提示用户
  2025. MessageBox("目前只支持256色位图的图象模糊!", "系统提示" ,
  2026. MB_ICONINFORMATION | MB_OK);
  2027. // 返回
  2028. return;
  2029. }
  2030. ::DIBNoRestriction(pDib);
  2031. // 设置脏标记
  2032. pDoc->SetModifiedFlag(TRUE);
  2033. // 更新视图
  2034. pDoc->UpdateAllViews(NULL);
  2035.     // 恢复光标
  2036. EndWaitCursor();
  2037. }
  2038. void CImageProcessingView::OnRestoreInverse() 
  2039. {
  2040. // 图象的逆滤波
  2041. // 更改光标形状
  2042. BeginWaitCursor();
  2043. // 获取文档
  2044. CImageProcessingDoc* pDoc = GetDocument();
  2045. //  获得图象CDib类的指针
  2046. CDib * pDib = pDoc->m_pDibInit;
  2047. // 获得图象的头文件信息
  2048. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2049. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的逆滤波)
  2050. if (lpBMIH->biBitCount != 8)
  2051. {
  2052. // 提示用户
  2053. MessageBox("目前只支持256色位图的逆滤波!", "系统提示" ,
  2054. MB_ICONINFORMATION | MB_OK);
  2055. // 返回
  2056. return;
  2057. }
  2058. ::DIBInverseFilter(pDib);
  2059. // 设置脏标记
  2060. pDoc->SetModifiedFlag(TRUE);
  2061. // 更新视图
  2062. pDoc->UpdateAllViews(NULL);
  2063.     // 恢复光标
  2064. EndWaitCursor();
  2065. }
  2066. void CImageProcessingView::OnDegenerationMotion() 
  2067. {
  2068. // 图象的运动模糊
  2069. // 更改光标形状
  2070. BeginWaitCursor();
  2071. // 获取文档
  2072. CImageProcessingDoc* pDoc = GetDocument();
  2073. //  获得图象CDib类的指针
  2074. CDib * pDib = pDoc->m_pDibInit;
  2075. // 获得图象的头文件信息
  2076. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2077. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的运动模糊)
  2078. if (lpBMIH->biBitCount != 8)
  2079. {
  2080. // 提示用户
  2081. MessageBox("目前只支持256色位图的运动模糊!", "系统提示" ,
  2082. MB_ICONINFORMATION | MB_OK);
  2083. // 返回
  2084. return;
  2085. }
  2086. ::DIBMotionDegeneration(pDib);
  2087. // 设置脏标记
  2088. pDoc->SetModifiedFlag(TRUE);
  2089. // 更新视图
  2090. pDoc->UpdateAllViews(NULL);
  2091.     // 恢复光标
  2092. EndWaitCursor();
  2093. }
  2094. void CImageProcessingView::OnRestoreMotion() 
  2095. {
  2096. // 运动模糊图象复原
  2097. // 更改光标形状
  2098. BeginWaitCursor();
  2099. // 获取文档
  2100. CImageProcessingDoc* pDoc = GetDocument();
  2101. //  获得图象CDib类的指针
  2102. CDib * pDib = pDoc->m_pDibInit;
  2103. // 获得图象的头文件信息
  2104. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2105. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的运动模糊复原)
  2106. if (lpBMIH->biBitCount != 8)
  2107. {
  2108. // 提示用户
  2109. MessageBox("目前只支持256色位图的运动模糊复原!", "系统提示" ,
  2110. MB_ICONINFORMATION | MB_OK);
  2111. // 返回
  2112. return;
  2113. }
  2114. ::DIBMotionRestore(pDib);
  2115. // 设置脏标记
  2116. pDoc->SetModifiedFlag(TRUE);
  2117. // 更新视图
  2118. pDoc->UpdateAllViews(NULL);
  2119.     // 恢复光标
  2120. EndWaitCursor();
  2121. }
  2122. void CImageProcessingView::OnDEGENERATIONWinner() 
  2123. {
  2124. // 图象的加噪模糊
  2125. // 更改光标形状
  2126. BeginWaitCursor();
  2127. // 获取文档
  2128. CImageProcessingDoc* pDoc = GetDocument();
  2129. //  获得图象CDib类的指针
  2130. CDib * pDib = pDoc->m_pDibInit;
  2131. // 获得图象的头文件信息
  2132. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2133. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的加噪模糊)
  2134. if (lpBMIH->biBitCount != 8)
  2135. {
  2136. // 提示用户
  2137. MessageBox("目前只支持256色位图的加噪模糊!", "系统提示" ,
  2138. MB_ICONINFORMATION | MB_OK);
  2139. // 返回
  2140. return;
  2141. }
  2142. ::DIBNoiseDegeneration(pDib);
  2143. // 设置脏标记
  2144. pDoc->SetModifiedFlag(TRUE);
  2145. // 更新视图
  2146. pDoc->UpdateAllViews(NULL);
  2147.     // 恢复光标
  2148. EndWaitCursor();
  2149. }
  2150. void CImageProcessingView::OnRestoreWinner() 
  2151. {
  2152. // 图象的维纳滤波
  2153. // 更改光标形状
  2154. BeginWaitCursor();
  2155. // 获取文档
  2156. CImageProcessingDoc* pDoc = GetDocument();
  2157. //  获得图象CDib类的指针
  2158. CDib * pDib = pDoc->m_pDibInit;
  2159. // 获得图象的头文件信息
  2160. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2161. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的维纳滤波)
  2162. if (lpBMIH->biBitCount != 8)
  2163. {
  2164. // 提示用户
  2165. MessageBox("目前只支持256色位图的维纳滤波!", "系统提示" ,
  2166. MB_ICONINFORMATION | MB_OK);
  2167. // 返回
  2168. return;
  2169. }
  2170. ::DIBWinnerFilter(pDib);
  2171. // 设置脏标记
  2172. pDoc->SetModifiedFlag(TRUE);
  2173. // 更新视图
  2174. pDoc->UpdateAllViews(NULL);
  2175.     // 恢复光标
  2176. EndWaitCursor();
  2177. }
  2178. void CImageProcessingView::OnMoment() 
  2179. {
  2180. // 图象的pq阶力矩
  2181. // 更改光标形状
  2182. BeginWaitCursor();
  2183. // 获取文档
  2184. CImageProcessingDoc* pDoc = GetDocument();
  2185. //  获得图象CDib类的指针
  2186. CDib * pDib = pDoc->m_pDibInit;
  2187. // 获得图象的头文件信息
  2188. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2189. // 判断是否是8-bpp位图
  2190. if (lpBMIH->biBitCount != 8)
  2191. {
  2192. // 提示用户
  2193. MessageBox("目前只支持256色位图!", "系统提示" ,
  2194. MB_ICONINFORMATION | MB_OK);
  2195. // 返回
  2196. return;
  2197. }
  2198. ::DIBMOMENT(pDib);
  2199.     // 恢复光标
  2200. EndWaitCursor();
  2201. }
  2202. void CImageProcessingView::OnBarycentermoment() 
  2203. {
  2204. // 图象的重心矩
  2205. // 更改光标形状
  2206. BeginWaitCursor();
  2207. // 获取文档
  2208. CImageProcessingDoc* pDoc = GetDocument();
  2209. //  获得图象CDib类的指针
  2210. CDib * pDib = pDoc->m_pDibInit;
  2211. // 获得图象的头文件信息
  2212. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2213. // 判断是否是8-bpp位图
  2214. if (lpBMIH->biBitCount != 8)
  2215. {
  2216. // 提示用户
  2217. MessageBox("目前只支持256色位图!", "系统提示" ,
  2218. MB_ICONINFORMATION | MB_OK);
  2219. // 返回
  2220. return;
  2221. }
  2222. ::DIBBARYCENTERMOMENT(pDib);
  2223. // 恢复光标
  2224. EndWaitCursor();
  2225. }
  2226. void CImageProcessingView::OnAnalysisHolenum() 
  2227. {
  2228. // 消去二值图象中小于阈值面积的区域
  2229. // 更改光标形状
  2230. BeginWaitCursor();
  2231. // 获取文档
  2232. CImageProcessingDoc* pDoc = GetDocument();
  2233. //  获得图象CDib类的指针
  2234. CDib * pDib = pDoc->m_pDibInit;
  2235. // 获得图象的头文件信息
  2236. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2237. // 判断是否是8-bpp位图
  2238. if (lpBMIH->biBitCount != 8)
  2239. {
  2240. // 提示用户
  2241. MessageBox("目前只支持256色位图的图象!", "系统提示" ,
  2242. MB_ICONINFORMATION | MB_OK);
  2243. // 返回
  2244. return;
  2245. }
  2246. ::DIBHOLENUMBER(pDib);
  2247. // 设置脏标记
  2248. pDoc->SetModifiedFlag(TRUE);
  2249. // 更新视图
  2250. pDoc->UpdateAllViews(NULL);
  2251.     // 恢复光标
  2252. EndWaitCursor();
  2253. }
  2254. void CImageProcessingView::OnStreetFramework() 
  2255. {
  2256. // 街区距离骨架提取
  2257. // 更改光标形状
  2258. BeginWaitCursor();
  2259. // 获取文档
  2260. CImageProcessingDoc* pDoc = GetDocument();
  2261. //  获得图象CDib类的指针
  2262. CDib * pDib = pDoc->m_pDibInit;
  2263. // 获得图象的头文件信息
  2264. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2265. // 判断是否是8-bpp位图
  2266. if (lpBMIH->biBitCount != 8)
  2267. {
  2268. // 提示用户
  2269. MessageBox("目前只支持256色位图!", "系统提示" ,
  2270. MB_ICONINFORMATION | MB_OK);
  2271. // 返回
  2272. return;
  2273. }
  2274. ::DIBFREAMEWORK(pDib);
  2275. // 设置脏标记
  2276. pDoc->SetModifiedFlag(TRUE);
  2277. // 更新视图
  2278. pDoc->UpdateAllViews(NULL);
  2279.     // 恢复光标
  2280. EndWaitCursor();
  2281. }
  2282. void CImageProcessingView::OnStreetTransform() 
  2283. {
  2284. // 二值图象的街区距离变换
  2285. // 更改光标形状
  2286. BeginWaitCursor();
  2287. // 获取文档
  2288. CImageProcessingDoc* pDoc = GetDocument();
  2289. //  获得图象CDib类的指针
  2290. CDib * pDib = pDoc->m_pDibInit;
  2291. // 获得图象的头文件信息
  2292. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2293. // 判断是否是8-bpp位图(
  2294. if (lpBMIH->biBitCount != 8)
  2295. {
  2296. // 提示用户
  2297. MessageBox("目前只支持256色位图!", "系统提示" ,
  2298. MB_ICONINFORMATION | MB_OK);
  2299. // 返回
  2300. return;
  2301. }
  2302. ::DIBSTREETDIS(pDib);
  2303. // 设置脏标记
  2304. pDoc->SetModifiedFlag(TRUE);
  2305. // 更新视图
  2306. pDoc->UpdateAllViews(NULL);
  2307.     // 恢复光标
  2308. EndWaitCursor();
  2309. }
  2310. void CImageProcessingView::OnFrameRestore() 
  2311. {
  2312. // 街区距离骨架复原
  2313. // 更改光标形状
  2314. BeginWaitCursor();
  2315. // 获取文档
  2316. CImageProcessingDoc* pDoc = GetDocument();
  2317. //  获得图象CDib类的指针
  2318. CDib * pDib = pDoc->m_pDibInit;
  2319. // 获得图象的头文件信息
  2320. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2321. // 判断是否是8-bpp位图
  2322. if (lpBMIH->biBitCount != 8)
  2323. {
  2324. // 提示用户
  2325. MessageBox("目前只支持256色位图!", "系统提示" ,
  2326. MB_ICONINFORMATION | MB_OK);
  2327. // 返回
  2328. return;
  2329. }
  2330. ::DIBCHESSBOARDDISRESTORE(pDib);
  2331. // 设置脏标记
  2332. pDoc->SetModifiedFlag(TRUE);
  2333. // 更新视图
  2334. pDoc->UpdateAllViews(NULL);
  2335.     // 恢复光标
  2336. EndWaitCursor();
  2337. }
  2338. void CImageProcessingView::OnTrace() 
  2339. {
  2340. // 二值图象边界跟踪
  2341. // 更改光标形状
  2342. BeginWaitCursor();
  2343. // 获取文档
  2344. CImageProcessingDoc* pDoc = GetDocument();
  2345. //  获得图象CDib类的指针
  2346. CDib * pDib = pDoc->m_pDibInit;
  2347. // 获得图象的头文件信息
  2348. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2349. // 判断是否是8-bpp位图
  2350. if (lpBMIH->biBitCount != 8)
  2351. {
  2352. // 提示用户
  2353. MessageBox("目前只支持256色位图!", "系统提示" ,
  2354. MB_ICONINFORMATION | MB_OK);
  2355. // 返回
  2356. return;
  2357. }
  2358. ::DIBTrace(pDib);
  2359. // 设置脏标记
  2360. pDoc->SetModifiedFlag(TRUE);
  2361. // 更新视图
  2362. pDoc->UpdateAllViews(NULL);
  2363.     // 恢复光标
  2364. EndWaitCursor();
  2365. }
  2366. void CImageProcessingView::OnOutline() 
  2367. {
  2368. // 二值图象边界提取
  2369. // 更改光标形状
  2370. BeginWaitCursor();
  2371. // 获取文档
  2372. CImageProcessingDoc* pDoc = GetDocument();
  2373. //  获得图象CDib类的指针
  2374. CDib * pDib = pDoc->m_pDibInit;
  2375. // 获得图象的头文件信息
  2376. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2377. // 判断是否是8-bpp位图
  2378. if (lpBMIH->biBitCount != 8)
  2379. {
  2380. // 提示用户
  2381. MessageBox("目前只支持256色位图!", "系统提示" ,
  2382. MB_ICONINFORMATION | MB_OK);
  2383. // 返回
  2384. return;
  2385. }
  2386. ::DIBOUTLINE(pDib);
  2387. // 设置脏标记
  2388. pDoc->SetModifiedFlag(TRUE);
  2389. // 更新视图
  2390. pDoc->UpdateAllViews(NULL);
  2391.     // 恢复光标
  2392. EndWaitCursor();
  2393. }
  2394. void CImageProcessingView::OnViewBayer() 
  2395. {
  2396. // Bayer抖动法显示图象
  2397. // 更改光标形状
  2398. BeginWaitCursor();
  2399. // 获取文档
  2400. CImageProcessingDoc* pDoc = GetDocument();
  2401. //  获得图象CDib类的指针
  2402. CDib * pDib = pDoc->m_pDibInit;
  2403. // 获得图象的头文件信息
  2404. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2405. // 判断是否是8-bpp位图
  2406. if (lpBMIH->biBitCount != 8)
  2407. {
  2408. // 提示用户
  2409. MessageBox("目前只支持256色位图!", "系统提示" ,
  2410. MB_ICONINFORMATION | MB_OK);
  2411. // 返回
  2412. return;
  2413. }
  2414. ::LimbPatternBayer(pDib);
  2415. // 设置脏标记
  2416. pDoc->SetModifiedFlag(TRUE);
  2417. // 更新视图
  2418. pDoc->UpdateAllViews(NULL);
  2419.     // 恢复光标
  2420. EndWaitCursor();
  2421. }
  2422. void CImageProcessingView::OnVIEWFloydSteinberg() 
  2423. {
  2424. // Floyd-Steinberg抖动法显示图象
  2425. // 更改光标形状
  2426. BeginWaitCursor();
  2427. // 获取文档
  2428. CImageProcessingDoc* pDoc = GetDocument();
  2429. //  获得图象CDib类的指针
  2430. CDib * pDib = pDoc->m_pDibInit;
  2431. // 获得图象的头文件信息
  2432. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2433. // 判断是否是8-bpp位图
  2434. if (lpBMIH->biBitCount != 8)
  2435. {
  2436. // 提示用户
  2437. MessageBox("目前只支持256色位图!", "系统提示" ,
  2438. MB_ICONINFORMATION | MB_OK);
  2439. // 返回
  2440. return;
  2441. }
  2442. ::DitherFloydSteinberg(pDib);
  2443. // 设置脏标记
  2444. pDoc->SetModifiedFlag(TRUE);
  2445. // 更新视图
  2446. pDoc->UpdateAllViews(NULL);
  2447.     // 恢复光标
  2448. EndWaitCursor();
  2449. }
  2450. void CImageProcessingView::OnCodingHuffman() 
  2451. {
  2452. // 哈夫曼编码表
  2453. // 获取文档
  2454. CImageProcessingDoc * pDoc = GetDocument();
  2455. // 指向源图象象素的指针
  2456. unsigned char * lpSrc;
  2457. // 图象的高度和宽度
  2458. LONG lHeight;
  2459. LONG lWidth;
  2460. // 图象每行的字节数
  2461. LONG lLineBytes;
  2462. // 图象象素总数
  2463. LONG lCountSum;
  2464. // 循环变量
  2465. LONG i;
  2466. LONG j;
  2467. // 数组指针用来保存各个灰度值出现概率
  2468. double * dProba;
  2469. // 当前图象颜色数目
  2470. int nColorNum;
  2471. //  获得图象CDib类的指针
  2472. CDib * pDib = pDoc->m_pDibInit;
  2473. //图象数据的指针
  2474. LPBYTE  lpDIBBits = pDib->m_lpImage;
  2475. // 头文件信息
  2476. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2477. // 判断是否是8-bpp位图(只处理8-bpp位图的霍夫曼编码)
  2478. if (lpBMIH->biBitCount != 8)
  2479. {
  2480. // 提示用户
  2481. MessageBox("目前只支持256色位图的霍夫曼编码!", "系统提示" ,
  2482. MB_ICONINFORMATION | MB_OK);
  2483. // 返回
  2484. return;
  2485. }
  2486. // 更改光标形状
  2487. BeginWaitCursor();
  2488. /********************************************************************
  2489.    开始计算各个灰度级出现的概率
  2490.    如果需要对指定的序列进行哈夫曼编码,
  2491.    只要将这一步改成给各个灰度级概率赋值即可
  2492. **********************************************************************
  2493. */
  2494. //  由头文件信息得到图象的比特数,从而得到颜色信息
  2495. nColorNum = (int)pow(2,lpBMIH->biBitCount);
  2496. // 分配内存
  2497. dProba = new double[nColorNum];
  2498. //得到图象的宽度和高度
  2499. CSize   SizeDim;
  2500. SizeDim = pDib->GetDimensions();
  2501. lWidth = SizeDim.cx;
  2502. lHeight = SizeDim.cy;
  2503. // 计算图象象素总数
  2504. lCountSum = lHeight * lWidth;
  2505. //得到实际的Dib图象存储大小
  2506. CSize   SizeRealDim;
  2507. SizeRealDim = pDib->GetDibSaveDim();
  2508. // 计算图象每行的字节数
  2509. lLineBytes = SizeRealDim.cx;
  2510. // 赋零值
  2511. for (i = 0; i < nColorNum; i ++)
  2512. {
  2513. dProba[i] = 0.0;
  2514. }
  2515. // 计算各个灰度值的计数
  2516. for (i = 0; i < lHeight; i ++)
  2517. {
  2518. for (j = 0; j < lWidth; j ++)
  2519. {
  2520. // 指向图象指针
  2521. lpSrc = lpDIBBits + lLineBytes * i + j;
  2522. // 计数加1
  2523. dProba[*(lpSrc)] = dProba[*(lpSrc)] + 1;
  2524. }
  2525. }
  2526. // 计算各个灰度值出现的概率
  2527. for (i = 0; i < nColorNum; i ++)
  2528. {
  2529. dProba[i] = dProba[i] / (FLOAT)lCountSum;
  2530. }
  2531. /***************************************************
  2532.  构建霍夫曼编码的码表
  2533.  并用对话框显示霍夫曼码表
  2534. ****************************************************/
  2535. // 创建对话框
  2536. CDlgHuffman dlgCoding;
  2537. // 初始化变量值
  2538. dlgCoding.dProba = dProba;
  2539. dlgCoding.nColorNum = nColorNum;
  2540. // 显示对话框
  2541. dlgCoding.DoModal();
  2542. // 恢复光标
  2543. EndWaitCursor();
  2544. }
  2545. void CImageProcessingView::OnCodingShanfino() 
  2546. {
  2547. // 香农-弗诺编码表
  2548. // 获取文档
  2549. CImageProcessingDoc * pDoc = GetDocument();
  2550. // 指向源图象象素的指针
  2551. unsigned char * lpSrc;
  2552. // 图象的高度
  2553. LONG lHeight;
  2554. LONG lWidth;
  2555. // 图象每行的字节数
  2556. LONG lLineBytes;
  2557. // 获取当前DIB颜色数目
  2558. int nColorNum;
  2559. // 图象象素总数
  2560. LONG lCountSum;
  2561. // 循环变量
  2562. LONG i;
  2563. LONG j;
  2564. // 保存各个灰度值出现概率的数组指针
  2565. double * dProba;
  2566. //  获得图象CDib类的指针
  2567. CDib * pDib = pDoc->m_pDibInit;
  2568. //图象数据的指针
  2569. LPBYTE  lpDIBBits = pDib->m_lpImage;
  2570. // 头文件信息
  2571. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2572. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的香农-费诺编码)
  2573. if (lpBMIH->biBitCount != 8)
  2574. {
  2575. // 提示用户
  2576. MessageBox("目前只支持256色位图的香农-费诺编码!", "系统提示" ,
  2577. MB_ICONINFORMATION | MB_OK);
  2578. // 返回
  2579. return;
  2580. }
  2581. // 更改光标形状
  2582. BeginWaitCursor();
  2583. /******************************************************************************
  2584. // 开始计算各个灰度级出现的概率
  2585. //
  2586. // 如果需要对指定的序列进行香农-弗诺编码,
  2587. //只要将这一步改成给各个灰度级概率赋值即可
  2588. *****************************************************************************
  2589. */
  2590. //  灰度值总数的计算
  2591. nColorNum = (int)pow(2,lpBMIH->biBitCount);
  2592. // 分配内存
  2593. dProba = new double[nColorNum];
  2594. //得到图象的宽度和高度
  2595. CSize   SizeDim;
  2596. SizeDim = pDib->GetDimensions();
  2597. lWidth = SizeDim.cx;
  2598. lHeight = SizeDim.cy;
  2599. // 计算图象象素总数
  2600. lCountSum = lHeight * lWidth;
  2601. //得到实际的Dib图象存储大小
  2602. CSize   SizeRealDim;
  2603. SizeRealDim = pDib->GetDibSaveDim();
  2604. // 计算图象每行的字节数
  2605. lLineBytes = SizeRealDim.cx;
  2606. // 计算图象象素总数
  2607. lCountSum = lHeight * lWidth;
  2608. // 重置计数为0
  2609. for (i = 0; i < nColorNum; i ++)
  2610. {
  2611. dProba[i] = 0.0;
  2612. }
  2613. // 计算各个灰度值的计数(对于非256色位图,此处给数组dProba赋值方法将不同)
  2614. for (i = 0; i < lHeight; i ++)
  2615. {
  2616. for (j = 0; j < lWidth; j ++)
  2617. {
  2618. // 指向图象指针
  2619. lpSrc = lpDIBBits + lLineBytes * i + j;
  2620. // 计数加1
  2621. dProba[*(lpSrc)] = dProba[*(lpSrc)]+ 1;
  2622. }
  2623. }
  2624. // 计算各个灰度值出现的概率
  2625. for (i = 0; i < nColorNum; i ++)
  2626. {
  2627. dProba[i] /= (double)lCountSum;
  2628. }
  2629. /***************************************************
  2630.  构建香农-费诺编码的码表
  2631.  并用对话框显示香农-费诺码表
  2632. ****************************************************/
  2633. // 创建对话框
  2634. CDlgShannon dlgPara;
  2635. // 初始化变量值
  2636. dlgPara.m_dProba = dProba;
  2637. dlgPara.m_nColorNum = nColorNum;
  2638. // 显示对话框
  2639. dlgPara.DoModal();
  2640. //释放内存
  2641. delete dProba;
  2642. // 恢复光标
  2643. EndWaitCursor();
  2644. }
  2645. void CImageProcessingView::OnCodingArith() 
  2646. {
  2647. CDlgArith dlgCoding;
  2648. // 显示对话框
  2649. dlgCoding.DoModal();
  2650. }
  2651. void CImageProcessingView::OnCodingBitplane() 
  2652. {
  2653. // 创建对话框
  2654. CDlgBitPlane dlgCoding;
  2655. // 显示对话框
  2656. dlgCoding.DoModal();
  2657. BYTE bBitNum = dlgCoding.m_BItNumber;
  2658. // 获取文档
  2659. CImageProcessingDoc * pDoc = GetDocument();
  2660. //  获得图象CDib类的指针
  2661. CDib * pDib = pDoc->m_pDibInit;
  2662. // 头文件信息
  2663. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2664. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的位平面分解)
  2665. if (lpBMIH->biBitCount != 8)
  2666. {
  2667. // 提示用户
  2668. MessageBox("目前只支持256色位图的位平面分解!", "系统提示" ,
  2669. MB_ICONINFORMATION | MB_OK);
  2670. // 返回
  2671. return;
  2672. }
  2673. DIBBITPLANE(pDib,bBitNum);
  2674. // 设置脏标记
  2675. pDoc->SetModifiedFlag(TRUE);
  2676. // 更新视图
  2677. pDoc->UpdateAllViews(NULL);
  2678. }
  2679. void CImageProcessingView::OnCodingWriteimg() 
  2680. {
  2681. // 对当前图象进行DPCM编码(存为IMG格式文件)
  2682. // 获取文档
  2683. CImageProcessingDoc * pDoc = GetDocument();
  2684. //  获得图象CDib类的指针
  2685. CDib * pDib = pDoc->m_pDibInit;
  2686. //图象数据的指针
  2687. LPBYTE  lpDIBBits = pDib->m_lpImage;
  2688. // 头文件信息
  2689. LPBITMAPINFOHEADER lpBMIH=pDib->m_lpBMIH;
  2690. // 判断是否是8-bpp位图(处理8-bpp位图的DPCM编码)
  2691. if (lpBMIH->biBitCount != 8)
  2692. {
  2693. // 提示用户
  2694. MessageBox("目前只支持256色位图的DPCM编码!", "系统提示" ,
  2695. MB_ICONINFORMATION | MB_OK);
  2696. // 返回
  2697. return;
  2698. }
  2699. // 更改光标形状
  2700. BeginWaitCursor();
  2701. // 文件保存路径
  2702. CString strFilePath;
  2703. // 获取原始文件名
  2704. strFilePath = pDoc->GetPathName();
  2705. // 更改后缀为IMG
  2706. if (strFilePath.Right(4).CompareNoCase(".BMP") == 0)
  2707. {
  2708. strFilePath = strFilePath.Left(strFilePath.GetLength()-3) + "IMG";
  2709. }
  2710. else
  2711. {
  2712. strFilePath += ".IMG";
  2713. }
  2714. // 创建SaveAs对话框
  2715. CFileDialog dlg(FALSE, "IMG", strFilePath, 
  2716. OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
  2717.             "IMG图象文件 (*.IMG) | *.IMG|所有文件 (*.*) | *.*||", NULL);
  2718. // 提示用户选择保存的路径
  2719. if (dlg.DoModal() != IDOK)
  2720. {
  2721. // 恢复光标
  2722. EndWaitCursor();
  2723. return;
  2724. }
  2725. // 获取用户指定的文件路径
  2726. strFilePath = dlg.GetPathName();
  2727. // CFile和CFileException对象
  2728. CFile file;
  2729. CFileException fe;
  2730. // 尝试创建指定的IMG文件
  2731. if (!file.Open(strFilePath, CFile::modeCreate |
  2732.   CFile::modeReadWrite | CFile::shareExclusive, &fe))
  2733. {
  2734. MessageBox("打开指定IMG文件时失败!", "系统提示" , 
  2735. MB_ICONINFORMATION | MB_OK);
  2736. return;
  2737. }
  2738. // 调用WRITE2IMG()函数将当前的DIB保存为IMG文件
  2739. if (::WRITE2IMG(pDib, file))
  2740. {
  2741. MessageBox("成功保存为IMG文件!", "系统提示" , 
  2742. MB_ICONINFORMATION | MB_OK);
  2743. }
  2744. else
  2745. {
  2746. MessageBox("保存为IMG文件失败!", "系统提示" , 
  2747. MB_ICONINFORMATION | MB_OK);
  2748. }
  2749. // 恢复光标
  2750. EndWaitCursor();
  2751. }
  2752. void CImageProcessingView::OnCodingLoadimg() 
  2753. {
  2754. // 读入IMG文件
  2755. // 获取文档
  2756. CImageProcessingDoc * pDoc = GetDocument();
  2757. //  获得图象CDib类的指针
  2758. CDib * pDib = pDoc->m_pDibInit;
  2759. // 文件路径
  2760. CString strFilePath;
  2761. // 创建Open对话框
  2762. CFileDialog dlg(TRUE, "PCX", NULL,
  2763. OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
  2764. "IMG图象文件 (*.PCX) | *.IMG|所有文件 (*.*) | *.*||", NULL);
  2765. // 提示用户选择保存的路径
  2766. if (dlg.DoModal() != IDOK)
  2767. {
  2768. // 返回
  2769. return;
  2770. }
  2771. // 获取用户指定的文件路径
  2772. strFilePath = dlg.GetPathName();
  2773. // CFile和CFileException对象
  2774. CFile file;
  2775. CFileException fe;
  2776. // 尝试打开指定的PCX文件
  2777. if (!file.Open(strFilePath, CFile::modeRead | CFile::shareDenyWrite, &fe))
  2778. {
  2779. // 提示用户
  2780. MessageBox("打开指定PCX文件时失败!", "系统提示" , 
  2781. MB_ICONINFORMATION | MB_OK);
  2782. // 返回
  2783. return;
  2784. }
  2785. // 更改光标形状
  2786. BeginWaitCursor();
  2787. // 调用LOADIMG()函数读取指定的IMG文件
  2788. BOOL Succ = LOADIMG(pDib, file);
  2789. if (Succ == TRUE)
  2790. {
  2791. // 提示用户
  2792. MessageBox("成功读取IMG文件!", "系统提示" , 
  2793. MB_ICONINFORMATION | MB_OK);
  2794. }
  2795. else
  2796. {
  2797. // 提示用户
  2798. MessageBox("读取IMG文件失败!", "系统提示" , 
  2799. MB_ICONINFORMATION | MB_OK);
  2800. }
  2801. // 更新视图
  2802. pDoc->UpdateAllViews(NULL);
  2803. // 恢复光标
  2804. EndWaitCursor();
  2805. }