restore.cpp
上传用户:panpan8800
上传日期:2013-06-29
资源大小:274k
文件大小:21k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. // ************************************************************************
  2. //  文件名:restore.cpp
  3. //
  4. //  图像复原API函数库:
  5. //
  6. //  DIBNoRestriction() - 图像模糊
  7. //  DIBInverseFilter() - 图像逆滤波复原
  8. //  DIBNoiseDegeneration() - 图像模糊加噪
  9. //  DIBWinnerFilter() - 图像维纳滤波
  10. // DIBMotionDegeneration() - 图像运动模糊
  11. // DIBMotionRestore() - 图像运动模糊复原
  12. //
  13. // *************************************************************************
  14. #include "stdafx.h"
  15. #include "GlobalApi.h"
  16. #include "Cdib.h"
  17. #include <math.h>
  18. #include <direct.h>
  19. #include <complex>
  20. using namespace std;
  21. #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
  22. /*************************************************************************
  23.  *
  24.  * 函数名称:
  25.  *   DIBNoRestriction()
  26.  *
  27.  * 参数:
  28.  *   CDib  *pDib       - 指向CDib类的指针
  29.  *
  30.  * 返回值:
  31.  *   BOOL               - 成功返回TRUE,否则返回FALSE。
  32.  *
  33.  * 说明:
  34.  *   该函数用来对DIB图像进行模糊操作。
  35.  *
  36.  ************************************************************************/
  37. BOOL WINAPI DIBNoRestriction(CDib *pDib)
  38. {
  39. // 指向源图像的指针
  40. BYTE * lpSrc;
  41. //图象的宽度和高度
  42. LONG    lWidth;
  43. LONG    lHeight;
  44. // 图像每行的字节数
  45. LONG lLineBytes;
  46. //得到图象的宽度和高度
  47. CSize   SizeDim;
  48. SizeDim = pDib->GetDimensions();
  49. lWidth  = SizeDim.cx;
  50. lHeight = SizeDim.cy;
  51. //得到实际的Dib图象存储大小
  52. CSize   SizeRealDim;
  53. SizeRealDim = pDib->GetDibSaveDim();
  54. // 计算图像每行的字节数
  55. lLineBytes = SizeRealDim.cx;
  56. //图像数据的指针
  57. LPBYTE  lpDIBBits = pDib->m_lpImage;
  58. //循环变量
  59. long i;
  60. long j;
  61. //临时变量
  62. double temp;
  63. // 实际进行付立叶变换的宽度和高度
  64. LONG lW = 1;
  65. LONG lH = 1;
  66. int wp = 0;
  67. int hp = 0;
  68. // 保证离散傅立叶变换的宽度和高度为2的整数次方
  69. while(lW * 2 <= lLineBytes)
  70. {
  71. lW = lW * 2;
  72. wp++;
  73. }
  74. while(lH * 2 <= lHeight)
  75. {
  76. lH = lH * 2;
  77. hp++;
  78. }
  79. //用来存储源图象和变换核的时域数据
  80. complex<double> *pCTSrc,*pCTH;
  81. //用来存储源图象和变换核的频域数据
  82. complex<double>  *pCFSrc,*pCFH;
  83. //图像归一化因子
  84. double MaxNum;
  85. //输入图象的长和宽必须为2的整数倍
  86. if(lW != (int) lLineBytes)
  87. {
  88. return false;
  89. }
  90. if(lH != (int) lHeight)
  91. {
  92. return false;
  93. }
  94. // 为时域和频域的数组分配空间
  95. pCTSrc = new complex<double> [lHeight*lLineBytes];
  96. pCTH   = new complex<double> [lHeight*lLineBytes];
  97. pCFSrc = new complex<double> [lHeight*lLineBytes];
  98. pCFH   = new complex<double> [lHeight*lLineBytes];
  99. // 将数据存入时域数组
  100. for (j = 0; j < lHeight; j++)
  101. {
  102. for(i = 0; i < lLineBytes; i++)
  103. {
  104. // 指向源图像倒数第j行,第i个象素的指针
  105. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  106. pCTSrc[ lLineBytes*j + i ] = complex<double>((double)*lpSrc , 0);
  107. pCFSrc[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  108. if(i < 5 && j < 5)
  109. {
  110. pCTH[ lLineBytes*j + i ] = complex<double>(0.04 , 0.0);
  111. }
  112. else
  113. {
  114. pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  115. }
  116. pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  117. }
  118. }
  119. //对源图像进行FFT
  120. ::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
  121. //对变换核图像进行FFT
  122. ::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
  123. //频域相乘
  124. for (i = 0;i <lHeight*lLineBytes;i++)
  125. {
  126. pCFSrc[i] = pCFSrc[i]*pCFH[i];
  127. }
  128. //对结果图像进行反FFT
  129. IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
  130. //确定归一化因子
  131. MaxNum = 0.0;
  132. for (j = 0;j < lHeight ;j++)
  133. {
  134. for(i = 0;i < lLineBytes ;i++)
  135. {
  136. temp = sqrt(pCTSrc[ lLineBytes*j + i ].real() * pCTSrc[ lLineBytes*j + i ].real()
  137. +pCTSrc[lLineBytes*j + i ].imag() * pCTSrc[ lLineBytes*j +i].imag());
  138. //选择归一化因子
  139. if( MaxNum < temp)
  140. MaxNum = temp;
  141. }
  142. }
  143. //转换为图像
  144. for (j = 0;j < lHeight ;j++)
  145. {
  146. for(i = 0;i < lLineBytes ;i++)
  147. {
  148. // 指向源图像倒数第j行,第i个象素的指针
  149.   lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  150. *lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum);
  151. }
  152. }
  153. //释放存储空间
  154. delete pCTSrc;
  155. delete pCTH;
  156. delete pCFSrc;
  157. delete pCFH;
  158. // 返回
  159. return true;
  160. }
  161. /*************************************************************************
  162.  *
  163.  * 函数名称:
  164.  *   DIBInverseFilter()
  165.  *
  166.  * 参数:
  167.  *   CDib  *pDib       - 指向CDib类的指针
  168.  *
  169.  * 返回值:
  170.  *   BOOL               - 成功返回TRUE,否则返回FALSE
  171.  *
  172.  * 说明:
  173.  *   该函数用来对DIBNoRestriction()生成的DIB图像进行复原操作。
  174.  *
  175.  ************************************************************************/
  176. BOOL WINAPI DIBInverseFilter (CDib *pDib)
  177. {
  178.     // 指向源图像的指针
  179. BYTE * lpSrc;
  180. //图象的宽度和高度
  181. LONG    lWidth;
  182. LONG    lHeight;
  183. // 图像每行的字节数
  184. LONG lLineBytes;
  185. //得到图象的宽度和高度
  186. CSize   SizeDim;
  187. SizeDim = pDib->GetDimensions();
  188. lWidth  = SizeDim.cx;
  189. lHeight = SizeDim.cy;
  190. //得到实际的Dib图象存储大小
  191. CSize   SizeRealDim;
  192. SizeRealDim = pDib->GetDibSaveDim();
  193. // 计算图像每行的字节数
  194. lLineBytes = SizeRealDim.cx;
  195. //图像数据的指针
  196. LPBYTE  lpDIBBits = pDib->m_lpImage;
  197. //循环变量
  198. long i;
  199. long j;
  200. //临时变量
  201. double tempre, tempim, a, b, c, d;
  202. // 实际进行付立叶变换的宽度和高度
  203. LONG lW = 1;
  204. LONG lH = 1;
  205. int wp = 0;
  206. int hp = 0;
  207. // 保证离散傅立叶变换的宽度和高度为2的整数次方
  208. while(lW * 2 <= lLineBytes)
  209. {
  210. lW = lW * 2;
  211. wp++;
  212. }
  213. while(lH * 2 <= lHeight)
  214. {
  215. lH = lH * 2;
  216. hp++;
  217. }
  218. //用来存储源图象和变换核的时域数据
  219. complex<double> *pCTSrc,*pCTH;
  220. //用来存储源图象和变换核的频域数据
  221. complex<double>  *pCFSrc,*pCFH;
  222. //图像归一化因子
  223. double MaxNum;
  224. //输入退化图象的长和宽必须为2的整数倍
  225. if(lW != (int) lLineBytes)
  226. {
  227. return false;
  228. }
  229. if(lH != (int) lHeight)
  230. {
  231. return false;
  232. }
  233. // 为时域和频域的数组分配空间
  234. pCTSrc = new complex<double> [lHeight*lLineBytes];
  235. pCTH   = new complex<double> [lHeight*lLineBytes];
  236. pCFSrc = new complex<double> [lHeight*lLineBytes];
  237. pCFH   = new complex<double> [lHeight*lLineBytes];
  238. // 将退化图象数据存入时域数组
  239. for (j = 0; j < lHeight; j++)
  240. {
  241. for(i = 0; i < lLineBytes; i++)
  242. {
  243. // 指向退化图像倒数第j行,第i个象素的指针
  244. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  245. pCTSrc[ lLineBytes*j + i ] = complex<double>((double)*lpSrc , 0);
  246. pCFSrc[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  247. if(i < 5 && j < 5)
  248. {
  249. pCTH[ lLineBytes*j + i ] = complex<double>(0.04 , 0.0);
  250. }
  251. else
  252. {
  253. pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  254. }
  255. pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  256. }
  257. }
  258. //对退化图像进行FFT
  259. ::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
  260. //对变换核图像进行FFT
  261. ::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
  262. //频域相除
  263. for (i = 0;i <lHeight*lLineBytes;i++)
  264. {
  265. a = pCFSrc[i].real();
  266. b = pCFSrc[i].imag();
  267. c = pCFH[i].real();
  268. d = pCFH[i].imag();
  269. //如果频域值太小,不予考虑
  270. if (c*c + d*d > 1e-3)
  271. {
  272. tempre = ( a*c + b*d ) / ( c*c + d*d );
  273. tempim = ( b*c - a*d ) / ( c*c + d*d );
  274. }
  275. pCFSrc[i]= complex<double>(tempre , tempim);
  276. }
  277. //对复原图像进行反FFT
  278. IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
  279. //确定归一化因子
  280. MaxNum=300;
  281. //转换为复原图像
  282. for (j = 0;j < lHeight ;j++)
  283. {
  284. for(i = 0;i < lLineBytes ;i++)
  285. {
  286. // 指向复原图像倒数第j行,第i个象素的指针
  287.   lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  288. *lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum);
  289. }
  290. }
  291. //释放存储空间
  292. delete pCTSrc;
  293. delete pCTH;
  294. delete pCFSrc;
  295. delete pCFH;
  296. // 返回
  297. return true;
  298. }
  299. /*************************************************************************
  300.  *
  301.  * 函数名称:
  302.  *   DIBNoiseDegeneration()
  303.  *
  304.  * 参数:
  305.  *   CDib  *pDib       - 指向CDib类的指针
  306.  *
  307.  * 返回值:
  308.  *   BOOL               - 模糊加噪操作成功返回TRUE,否则返回FALSE。
  309.  *
  310.  * 说明:
  311.  *   该函数用来对DIB图像进行模糊加噪操作。
  312.  *
  313.  ************************************************************************/
  314. BOOL WINAPI DIBNoiseDegeneration (CDib *pDib)
  315. {
  316. // 指向源图像的指针
  317. BYTE * lpSrc;
  318. //图象的宽度和高度
  319. LONG    lWidth;
  320. LONG    lHeight;
  321. // 图像每行的字节数
  322. LONG lLineBytes;
  323. //得到图象的宽度和高度
  324. CSize   SizeDim;
  325. SizeDim = pDib->GetDimensions();
  326. lWidth  = SizeDim.cx;
  327. lHeight = SizeDim.cy;
  328. //得到实际的Dib图象存储大小
  329. CSize   SizeRealDim;
  330. SizeRealDim = pDib->GetDibSaveDim();
  331. // 计算图像每行的字节数
  332. lLineBytes = SizeRealDim.cx;
  333. //图像数据的指针
  334. LPBYTE  lpDIBBits = pDib->m_lpImage;
  335. //循环变量
  336. long i;
  337. long j;
  338. //转换为图像,加噪
  339. unsigned char NoisePoint;
  340. //临时变量
  341. double temp;
  342. //图像归一化因子
  343. double MaxNum;
  344. // 实际进行付立叶变换的宽度和高度
  345. LONG lW = 1;
  346. LONG lH = 1;
  347. int wp = 0;
  348. int hp = 0;
  349. // 保证离散傅立叶变换的宽度和高度为2的整数次方
  350. while(lW * 2 <= lLineBytes)
  351. {
  352. lW = lW * 2;
  353. wp++;
  354. }
  355. while(lH * 2 <= lHeight)
  356. {
  357. lH = lH * 2;
  358. hp++;
  359. }
  360. //用来存储源图象和变换核的时域数据
  361. complex<double> *pCTSrc,*pCTH;
  362. //用来存储源图象和变换核的频域数据
  363. complex<double>  *pCFSrc,*pCFH;
  364. // 为时域和频域的数组分配空间
  365. pCTSrc = new complex<double> [lHeight*lLineBytes];
  366. pCTH   = new complex<double> [lHeight*lLineBytes];
  367. pCFSrc = new complex<double> [lHeight*lLineBytes];
  368. pCFH   = new complex<double> [lHeight*lLineBytes];
  369. for (j = 0;j < lHeight ;j++)
  370. {
  371. for(i = 0;i < lLineBytes ;i++)
  372. {
  373. // 指向源图像倒数第j行,第i个象素的指针
  374. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  375. // 将象素值存储到时域数组中
  376. pCTSrc[ lLineBytes*j + i ] = complex<double>((double)*lpSrc , 0);
  377. // 频域赋零值
  378. pCFSrc[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  379. // 用来对图象做退化的系统
  380. if(i < 5 && j <5 )
  381. {
  382. pCTH[ lLineBytes*j + i ] = complex<double>(0.04 , 0.0);
  383. }
  384. else
  385. {
  386. pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  387. }
  388. // 频域赋零值
  389. pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  390. }
  391. }
  392. //对源图像进行FFT
  393. ::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
  394. //对变换核图像进行FFT
  395. ::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
  396. //频域相乘
  397. for (i = 0;i <lHeight*lLineBytes;i++)
  398. {
  399. pCFSrc[i] = pCFSrc[i]*pCFH[i];
  400. }
  401. //对结果图像进行反FFT
  402. IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
  403. //确定归一化因子
  404. MaxNum = 0.0;
  405. for (j = 0;j < lHeight ;j++)
  406. {
  407. for(i = 0;i < lLineBytes ;i++)
  408. {
  409. temp = sqrt(pCTSrc[ lLineBytes*j + i ].real() * pCTSrc[ lLineBytes*j + i ].real()
  410. +pCTSrc[lLineBytes*j + i ].imag() * pCTSrc[ lLineBytes*j +i].imag());
  411. //选择归一化因子
  412. if( MaxNum < temp)
  413. MaxNum = temp;
  414. }
  415. }
  416. //生成伪随机数种子
  417. srand((unsigned)time(NULL));
  418. //转换为图像,并加入伪随机噪声
  419. for (j = 0;j < lHeight ;j++)
  420. {
  421. for(i = 0;i < lLineBytes ;i++)
  422. {
  423. // 产生的噪声
  424. NoisePoint = rand()/2048-8;
  425. // 指向源图像倒数第j行,第i个象素的指针
  426.   lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  427. // 时域加噪,存储象素值
  428. *lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum + NoisePoint);
  429. //如果象素值过大,直接赋值255
  430. if(*lpSrc > 255)
  431. *lpSrc = 255 ;
  432. }
  433. }
  434. //释放存储空间
  435. delete pCTSrc;
  436. delete pCTH;
  437. delete pCFSrc;
  438. delete pCFH;
  439. // 返回
  440. return true;
  441. }
  442. /*************************************************************************
  443.  *
  444.  * 函数名称:
  445.  *   DIBWinnerFilter()
  446.  *
  447.  * 参数:
  448.  *   CDib  *pDib       - 指向CDib类的指针
  449.  *
  450.  * 返回值:
  451.  *   BOOL               - 维纳滤波复原操作成功返回TRUE,否则返回FALSE。
  452.  *
  453.  * 说明:
  454.  *   该函数用来对DIB图像进行维纳滤波复原操作。
  455.  *
  456.  ************************************************************************/
  457. BOOL WINAPI DIBWinnerFilter (CDib *pDib)
  458. {
  459. // 指向源图像的指针
  460. BYTE * lpSrc;
  461. //图象的宽度和高度
  462. LONG    lWidth;
  463. LONG    lHeight;
  464. // 图像每行的字节数
  465. LONG lLineBytes;
  466. //得到图象的宽度和高度
  467. CSize   SizeDim;
  468. SizeDim = pDib->GetDimensions();
  469. lWidth  = SizeDim.cx;
  470. lHeight = SizeDim.cy;
  471. //得到实际的Dib图象存储大小
  472. CSize   SizeRealDim;
  473. SizeRealDim = pDib->GetDibSaveDim();
  474. // 计算图像每行的字节数
  475. lLineBytes = SizeRealDim.cx;
  476. //图像数据的指针
  477. LPBYTE  lpDIBBits = pDib->m_lpImage;
  478. //循环变量
  479. long i;
  480. long j;
  481. //临时变量
  482. double temp, tempre, tempim, 
  483. a, b, c, d, norm2;
  484. // 实际进行付立叶变换的宽度和高度
  485. LONG lW = 1;
  486. LONG lH = 1;
  487. int wp = 0;
  488. int hp = 0;
  489. // 保证离散傅立叶变换的宽度和高度为2的整数次方
  490. while(lW * 2 <= lLineBytes)
  491. {
  492. lW = lW * 2;
  493. wp++;
  494. }
  495. while(lH * 2 <= lHeight)
  496. {
  497. lH = lH * 2;
  498. hp++;
  499. }
  500. //用来存储源图象和变换核的时域数据
  501. complex<double> *pCTSrc,*pCTH;
  502. //用来存储源图象和变换核的频域数据
  503. complex<double>  *pCFSrc,*pCFH;
  504. //输入退化图象的长和宽必须为2的整数倍
  505. if(lW != (int) lLineBytes)
  506. {
  507. return false;
  508. }
  509. if(lH != (int) lHeight)
  510. {
  511. return false;
  512. }
  513. // 为时域和频域的数组分配空间
  514. pCTSrc = new complex<double> [lHeight*lLineBytes];
  515. pCTH = new complex<double> [lHeight*lLineBytes];
  516. pCFSrc = new complex<double> [lHeight*lLineBytes];
  517. pCFH = new complex<double> [lHeight*lLineBytes];
  518. // 滤波器加权系数
  519. double *pCFFilter   = new double [lHeight*lLineBytes];
  520. for (j = 0;j < lHeight ;j++)
  521. {
  522. for(i = 0;i < lLineBytes ;i++)
  523. {
  524. // 指向退化图像倒数第j行,第i个象素的指针
  525. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  526. // 将象素值存储到时域数组中
  527. pCTSrc[ lLineBytes*j + i ] = complex<double>((double)*lpSrc , 0);
  528. // 频域赋零值
  529. pCFSrc[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  530. // 退化系统时域及维纳滤波加权系数赋值
  531. if(i < 5 && j <5)
  532. {
  533. pCTH[ lLineBytes*j + i ] = complex<double>(0.04 , 0.0);
  534. pCFFilter[ lLineBytes*j + i ] = 0.5;
  535. }
  536. else
  537. {
  538. pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  539. pCFFilter[ lLineBytes*j + i ] = 0.05;
  540. }
  541. // 频域赋零值
  542. pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
  543. }
  544. }
  545. //对退化图像进行FFT
  546. ::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
  547. //对变换核图像进行FFT
  548. ::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
  549. // 计算M
  550. for (i = 0; i < lHeight * lLineBytes; i++)
  551. {
  552. // 赋值
  553. a = pCFSrc[i].real();
  554. b = pCFSrc[i].imag();
  555. c = pCFH[i].real();
  556. d = pCFH[i].imag();
  557. // |H(u,v)|*|H(u,v)|
  558. norm2 = c * c + d * d;
  559. // |H(u,v)|*|H(u,v)|/(|H(u,v)|*|H(u,v)|+a)
  560. temp  = (norm2 ) / (norm2 + pCFFilter[i]);
  561. {
  562. tempre = ( a*c + b*d ) / ( c*c + d*d );
  563. tempim = ( b*c - a*d ) / ( c*c + d*d );
  564. // 求得f(u,v)
  565. pCFSrc[i]= complex<double>(temp*tempre , temp*tempim);
  566. }
  567. }
  568. //对复原图像进行反FFT
  569. IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
  570. //转换为复原图像
  571. for (j = 0;j < lHeight ;j++)
  572. {
  573. for(i = 0;i < lLineBytes ;i++)
  574. {
  575. // 指向复原图像倒数第j行,第i个象素的指针
  576.   lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
  577. a = pCTSrc[(lLineBytes)*j + i].real();
  578. b = pCTSrc[(lLineBytes)*j + i].imag();
  579. norm2  = a*a + b*b;
  580. norm2  = sqrt(norm2) + 40;
  581. if(norm2 > 255)
  582. norm2 = 255.0;
  583. if(norm2 < 0)
  584. norm2 = 0;
  585. *lpSrc = (unsigned char) (norm2);
  586. }
  587. }
  588. //释放存储空间
  589. delete pCTSrc;
  590. delete pCTH;
  591. delete pCFSrc;
  592. delete pCFH;
  593. delete pCFFilter;
  594. // 返回
  595. return true;
  596. }
  597. /*************************************************************************
  598.  *
  599.  * 函数名称:
  600.  *   DIBMotionDegeneration()
  601.  *
  602.  * 参数:
  603.  *   CDib  *pDib       - 指向CDib类的指针
  604.  *
  605.  * 返回值:
  606.  *   BOOL               - 成功返回TRUE,否则返回FALSE。
  607.  *
  608.  * 说明:
  609.  *   该函数用来对DIB图像模拟由匀速直线运动造成的模糊
  610.  *
  611.  ***********************************************************************
  612.  */
  613. BOOL WINAPI DIBMotionDegeneration(CDib *pDib)
  614. {
  615. // 指向源图像的指针
  616. BYTE * lpSrc;
  617. //图象的宽度和高度
  618. LONG    lWidth;
  619. LONG    lHeight;
  620. // 图像每行的字节数
  621. LONG lLineBytes;
  622. //得到图象的宽度和高度
  623. CSize   SizeDim;
  624. SizeDim = pDib->GetDimensions();
  625. lWidth  = SizeDim.cx;
  626. lHeight = SizeDim.cy;
  627. //得到实际的Dib图象存储大小
  628. CSize   SizeRealDim;
  629. SizeRealDim = pDib->GetDibSaveDim();
  630. // 计算图像每行的字节数
  631. lLineBytes = SizeRealDim.cx;
  632. //图像数据的指针
  633. LPBYTE  lpDIBBits = pDib->m_lpImage;
  634. //循环变量
  635. long iColumn;
  636. long jRow;
  637. //临时变量
  638. int temp,m;
  639. // 临时变量
  640. double p,q;
  641. int nTotTime, nTotLen, nTime;
  642. //总的运动时间10s
  643. nTotTime = 10;
  644. // 总的运动距离10个象素点
  645. nTotLen = 10;
  646. // 摄像机的暴光系数
  647. double B;
  648. B = 0.1;
  649. //用来存储源图象和变换核的时域数据
  650. int *nImageDegener;
  651. // 为时域和频域的数组分配空间
  652. nImageDegener = new int [lHeight*lLineBytes];
  653. // 将数据存入时域数组
  654. for (jRow = 0; jRow < lHeight; jRow++)
  655. {
  656. for(iColumn = 0; iColumn < lLineBytes; iColumn++)
  657. {
  658. temp=0;
  659. // 指向源图像倒数第jRow行,第iColumn个象素的指针
  660. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
  661. // 象素点的象素值积累
  662. for ( nTime = 0; nTime < nTotTime; nTime++ )
  663. {
  664. p = (float)iColumn - (float)(nTotLen)*nTime/nTotTime;
  665. if (p > 0)
  666. {
  667. q = p - floor((double)p);
  668. if(q >= 0.5)
  669. m = (int)ceil((double)p);
  670. else
  671. m = (int)floor((double)p);
  672. // 累加
  673. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m;
  674. temp = temp + *lpSrc;
  675. }
  676. }
  677. // 乘以摄像机的暴光系数
  678. temp = B * temp;
  679. temp=(int)ceil((double)temp);
  680. // 使得temp的取值符合取值范围
  681. if(temp<0)
  682. temp=0;
  683. if(temp>255)
  684. temp=255;
  685. nImageDegener[lLineBytes*jRow + iColumn] = temp;
  686. }
  687. }
  688. //转换为图像
  689. for (jRow = 0;jRow < lHeight ;jRow++)
  690. {
  691. for(iColumn = 0;iColumn < lLineBytes ;iColumn++)
  692. {
  693. // 指向源图像倒数第jRow行,第iColumn个象素的指针
  694.   lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
  695. *lpSrc = nImageDegener[lLineBytes*jRow + iColumn];
  696. }
  697. }
  698. //释放存储空间
  699. delete nImageDegener;
  700. // 返回
  701. return true;
  702. }
  703. /*************************************************************************
  704.  *
  705.  * 函数名称:
  706.  *   DIBMotionRestore()
  707.  *
  708.  * 参数:
  709.  *   CDib  *pDib       - 指向CDib类的指针
  710.  *
  711.  * 返回值:
  712.  *   BOOL               - 成功返回TRUE,否则返回FALSE。
  713.  *
  714.  * 说明:
  715.  *   该函数用来对拟由匀速直线运动造成的模糊图象进行复原
  716.  *
  717.  ***********************************************************************
  718.  */
  719. BOOL WINAPI DIBMotionRestore(CDib *pDib)
  720. {
  721. // 指向源图像的指针
  722. BYTE * lpSrc;
  723. //图象的宽度和高度
  724. LONG    lWidth;
  725. LONG    lHeight;
  726. // 图像每行的字节数
  727. LONG lLineBytes;
  728. //得到图象的宽度和高度
  729. CSize   SizeDim;
  730. SizeDim = pDib->GetDimensions();
  731. lWidth  = SizeDim.cx;
  732. lHeight = SizeDim.cy;
  733. //得到实际的Dib图象存储大小
  734. CSize   SizeRealDim;
  735. SizeRealDim = pDib->GetDibSaveDim();
  736. // 计算图像每行的字节数
  737. lLineBytes = SizeRealDim.cx;
  738. //图像数据的指针
  739. LPBYTE  lpDIBBits = pDib->m_lpImage;
  740. //循环变量
  741. long iColumn;
  742. long jRow;
  743. int i,n,m;
  744. //临时变量
  745. int temp1,temp2,
  746. totalq,q1,q2,z;
  747. double p,q;
  748. // 常量A赋值
  749. int A = 80;
  750. //常量B赋值
  751. int B = 10;
  752. //总的移动距离
  753. int nTotLen=10;
  754. // 图象宽度包含多少个ntotlen
  755. int K=lLineBytes/nTotLen;
  756. int error[10];
  757. //用来存储源图象时域数据
  758. int *nImageDegener;
  759. // 为时域数组分配空间
  760. nImageDegener = new int [lHeight*lLineBytes];
  761. // 将象素存入数组中
  762. for (jRow = 0; jRow < lHeight; jRow++)
  763. {
  764. for(iColumn = 0; iColumn < lLineBytes; iColumn++)
  765. {
  766. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
  767. nImageDegener[lLineBytes*jRow + iColumn] = (*lpSrc);
  768. }
  769. }
  770. for (jRow = 0; jRow < lHeight; jRow++)
  771. {
  772. // 计算error[i]
  773. for(i = 0; i < 10; i++)
  774. {
  775. error[i] = 0;
  776. for(n = 0; n < K; n++)
  777. for(m = 0; m <= n; m++)
  778. {
  779. // 象素是否为一行的开始处
  780. if(i == 0 && m == 0)
  781. {
  782. temp1=temp2=0;
  783. }
  784. // 进行差分运算
  785. else
  786. {
  787. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m*10+i;
  788. temp1=*lpSrc;
  789. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m*10+i-1;
  790. temp2 = *lpSrc;
  791. }
  792. error[i] = error[i] + temp1 - temp2;
  793. }
  794. error[i] = B * error[i] / K;
  795. }
  796. for(iColumn = 0; iColumn < lLineBytes; iColumn++)
  797. {
  798. // 计算m,以及z
  799. m = iColumn / nTotLen;
  800. z = iColumn - m*nTotLen;
  801. // 初始化
  802. totalq = 0;
  803. q = 0;
  804. for(n = 0; n <= m; n++)
  805. {
  806. q1 = iColumn - nTotLen*n;
  807. if(q1 == 0)
  808. q = 0;
  809. // 进行差分运算
  810. else
  811. {
  812. q2 = q1 - 1;
  813. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + q1;
  814. temp1 = *lpSrc;
  815. lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + q2;
  816. temp2 = *lpSrc;
  817. q = (temp1 - temp2) * B;
  818. }
  819. totalq = totalq + q;
  820. }
  821. p = error[z];
  822. // 得到f(x,y)的值
  823. temp1 = totalq + A - p;
  824. // 使得象素的取值符合取值范围
  825. if(temp1 < 0)
  826. temp1 = 0;
  827. if(temp1 > 255)
  828. temp1 = 255;
  829. nImageDegener[lLineBytes*jRow + iColumn] = temp1;
  830. }
  831. }
  832. //转换为图像
  833. for (jRow = 0;jRow < lHeight ;jRow++)
  834. {
  835. for(iColumn = 0;iColumn < lLineBytes ;iColumn++)
  836. {
  837. // 指向源图像倒数第jRow行,第iColumn个象素的指针
  838.   lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
  839. // 存储象素值
  840. *lpSrc = nImageDegener[lLineBytes*jRow + iColumn];
  841. }
  842. }
  843. //释放存储空间
  844. delete nImageDegener;
  845. // 返回
  846. return true;
  847. }
  848. #undef SWAP