MathEx.cpp
上传用户:gzboli
上传日期:2013-04-10
资源大小:471k
文件大小:14k
源码类别:

图片显示

开发平台:

Visual C++

  1. // MathEx.cpp: implementation of the CMathEx class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "QuickImage.h"
  6. #include "MathEx.h"
  7. #include <math.h>
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. /*
  17. COMPLEX::COMPLEX()
  18. {
  19. re = 0.0;
  20. im = 0.0;
  21. }
  22. COMPLEX::COMPLEX(double real, double image)
  23. {
  24. re = real;
  25. im = image;
  26. }
  27. COMPLEX::COMPLEX(const COMPLEX &c)
  28. {
  29. re = c.re;
  30. im = c.im;
  31. }
  32. COMPLEX::~COMPLEX()
  33. {
  34. }
  35. COMPLEX COMPLEX::operator +(const COMPLEX &c)
  36. {
  37. COMPLEX ret;
  38. ret.re = re + c.re;
  39. ret.im = im + c.im;
  40. return ret;
  41. }
  42. COMPLEX COMPLEX::operator -(const COMPLEX &c)
  43. {
  44. COMPLEX ret;
  45. ret.re = re - c.re;
  46. ret.im = im - c.im;
  47. return ret;
  48. }
  49. COMPLEX COMPLEX::operator *(const COMPLEX &c)
  50. {
  51. COMPLEX ret;
  52. ret.re = re * c.re - im * c.im;
  53. ret.im = re * c.im + im * c.re;
  54. return ret;
  55. }
  56. COMPLEX& COMPLEX::operator =(const COMPLEX &c)
  57. {
  58. re = c.re;
  59. im = c.im;
  60. return *this;
  61. }
  62. BOOL COMPLEX::operator ==(const COMPLEX &c)
  63. {
  64. return ((re == c.re ) && (im == c.im));
  65. }
  66. COMPLEX COMPLEX::operator *(double d)
  67. {
  68. COMPLEX ret;
  69. ret.re = re * d;
  70. ret.im = im * d;
  71. return ret;
  72. }
  73. COMPLEX operator *(double d, const COMPLEX &c)
  74. {
  75. COMPLEX ret;
  76. ret.re = c.re * d;
  77. ret.im = c.im * d;
  78. return ret;
  79. }
  80. */
  81. /*complex add*/
  82. COMPLEX Add(COMPLEX c1, COMPLEX c2)
  83. {
  84. COMPLEX c;
  85. c.re=c1.re+c2.re;
  86. c.im=c1.im+c2.im;
  87. return c;
  88. }
  89. /*complex substract*/
  90. COMPLEX Sub(COMPLEX c1, COMPLEX c2)
  91. {
  92. COMPLEX c;
  93. c.re=c1.re-c2.re;
  94. c.im=c1.im-c2.im;
  95. return c;
  96. }
  97. /*complex multiple*/
  98. COMPLEX Mul(COMPLEX c1, COMPLEX c2)
  99. {
  100. COMPLEX c;
  101. c.re=c1.re*c2.re-c1.im*c2.im;
  102. c.im=c1.re*c2.im+c2.re*c1.im;
  103. return c;
  104. }
  105. CMathEx::CMathEx()
  106. {
  107. }
  108. CMathEx::~CMathEx()
  109. {
  110. }
  111. void CMathEx::MatrixRotate(double *after, const double *before, int row, int col)
  112. {
  113. ASSERT( NULL != after);
  114. ASSERT( NULL != before);
  115. for(int i=0; i<col; i++)
  116. for(int j=0; j<row; j++)
  117. after[i * row + j] = before[j * col + i];
  118. }
  119. void CMathEx::MatrixMutiply
  120. (double *result, const double *left, const double *right, int row, int coll, int colr)
  121. {
  122. ASSERT(NULL != result);
  123. ASSERT(NULL != left);
  124. ASSERT(NULL != right);
  125. int i,j,k;
  126. double *pRes = result;
  127. for(i = 0; i < row * colr; i++, pRes++)
  128. *pRes = 0.0;
  129. for(i = 0; i < row; i++)
  130. for(j = 0; j< colr;j++)
  131. for(k = 0;k< coll ; k++)
  132. result[colr*i+j] += (left[coll*i+k] * right[colr*k+j]);
  133. }
  134. BOOL CMathEx::MatrixConvert(double *result, const double *before, int size)
  135. {
  136. ASSERT(NULL != result);
  137. ASSERT(NULL != before);
  138. int i = size * size * sizeof(double);
  139. HANDLE hHeap = HeapCreate(HEAP_NO_SERIALIZE, i, 0);
  140. if(hHeap == NULL)
  141. {
  142. return FALSE;
  143. }
  144. HeapLock(hHeap);
  145. double *pSubthis = NULL;
  146. pSubthis=(double*)HeapAlloc(hHeap, HEAP_NO_SERIALIZE, i);
  147. if(pSubthis == NULL)
  148. {
  149. HeapUnlock(hHeap);
  150. HeapDestroy(hHeap);
  151. return FALSE;
  152. }
  153. memcpy((void*)pSubthis, (void*)before, i);
  154. double *pRes = result;
  155. for(i=0; i<size * size; i++, pRes++)
  156. *pRes = 1.0;
  157. int k, k2;
  158. int imax;
  159. double dmax;
  160. for(i=0;i<size;i++)
  161. {
  162. //////////////////////////////////////////////////////////////////
  163. imax=i;
  164. dmax=pSubthis[i*size+i];
  165. for(k=i+1;k<size;k++)
  166. if(fabs(pSubthis[k*size+i])>fabs(dmax))
  167. {
  168. dmax=pSubthis[k*size+i];
  169. imax=k;
  170. }
  171. if(fabs(dmax)<1e-30)
  172. {
  173. AfxMessageBox("Can not convert a ill matrix!",MB_ICONERROR);
  174. HeapFree(hHeap,HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS,pSubthis);
  175. pSubthis = NULL;
  176. HeapUnlock(hHeap);
  177. HeapDestroy(hHeap);
  178. return FALSE;
  179. }
  180. if(imax!=i)
  181. for(k=0;k<size;k++)
  182. {
  183. dmax=pSubthis[i*size+k];
  184. pSubthis[i*size+k]=pSubthis[imax*size+k];
  185. pSubthis[imax*size+k]=dmax;
  186. dmax = result[i*size+k];
  187. result[i*size+k] = result[imax*size+k];
  188. result[imax*size+k] = dmax;
  189. }
  190. //此间为列选主元
  191. ////////////////////////////////////////////////////////////////////
  192. dmax= pSubthis[i*size+i];
  193. for(k=i;k<size;k++)
  194. {
  195. imax = i*size+k;
  196. pSubthis[imax] /= dmax;
  197. result[imax] /= dmax;
  198. }
  199. for(k=0; k<i; k++)
  200. {
  201. dmax=pSubthis[k*size+i];
  202. for(k2 = i; k2 < size; k2++)
  203. {
  204. pSubthis[k*size+k2] -= (pSubthis[i*size+k2]*dmax);
  205. result[k*size+k2] -= (result[i*size+k2]*dmax);
  206. }
  207. }
  208. for(k=i+1; k<size; k++)
  209. {
  210. dmax=pSubthis[k*size+i];
  211. for(k2 = i; k2 < size; k2++)
  212. {
  213. pSubthis[k*size+k2] -= (pSubthis[i*size+k2]*dmax);
  214. result[k*size+k2] -= (result[i*size+k2]*dmax);
  215. }
  216. }
  217. }
  218. try
  219. {
  220. HeapFree(hHeap,HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS,pSubthis);
  221. pSubthis = NULL;
  222. HeapUnlock(hHeap);
  223. HeapDestroy(hHeap);
  224. }
  225. catch(CMemoryException *e)
  226. {
  227. char msg[256];
  228. e->GetErrorMessage(msg,255);
  229. e->ReportError();
  230. e->Delete();
  231. return FALSE;
  232. }
  233. return TRUE;
  234. }
  235. void CMathEx::JieFC(double *xsz, int row, int col, double *result)
  236. {
  237. double b,ab1;
  238. int i,j,k,j1,n1,n2,l;
  239. for( i=0; i<row; i++)
  240. {
  241. result[i]=0.0;
  242. b=0.0;
  243. for(j=i; j<row; j++)
  244. {
  245. if(fabs(b)<=fabs(xsz[j * col + i]))
  246. {
  247. b=xsz[j * col + i];
  248. j1=j;
  249. }
  250. }
  251. for(k=i; k<col; k++)
  252. {
  253. ab1 = xsz[j1 * col + k]/b;
  254. xsz[j1 * col + k] = xsz[i * col + k];
  255. xsz[i * col + k] = ab1;
  256. }
  257. n1=i+1;
  258. if(n1<row)
  259. {
  260. for(j=n1; j<row;j++)
  261. {
  262. for(k=n1;k<col;k++)
  263. {
  264. xsz[j * col + k] -= (xsz[j * col + i]*xsz[i * col + k]);
  265. }
  266. }
  267. }
  268. }
  269. result[row-1] = xsz[row * col -1];//xsz[(row-1) * col + col-1];
  270. n2=row-1;
  271. for(i=0;i<n2;i++)
  272. {
  273. l=n2- 1 - i;
  274. result[l]=xsz[l * col -1];
  275. for(j=l + 1; j<row; j++)
  276. {
  277. result[l] -= result[j]*xsz[l * col + j];
  278. }
  279. }
  280. }
  281. BOOL CMathEx::GSXQ(double *x, double *a, double *b, int size)
  282. {
  283. int i, j, k;
  284. double dMax;
  285. int iMax;
  286. BOOL bIll = TRUE;
  287. for(i = 0; i< size; i++)
  288. {
  289. iMax = i;
  290. dMax = x[i * size + i];
  291. for(j = i +1; j< size; j++)
  292. {
  293. if(fabs(dMax) < fabs(a[j * size + i]))
  294. {
  295. dMax = a[j * size + i];
  296. iMax = j;
  297. }
  298. }
  299. if(dMax > -0.00000000001 && dMax < 0.00000000001)
  300. bIll = FALSE;
  301. if(iMax != i)
  302. {
  303. for(j = i; j < size; j++)
  304. {
  305. dMax = a[i * size + j];
  306. a[i * size + j] = a[iMax * size + j];
  307. a[iMax * size + j] = dMax;
  308. }
  309. dMax = b[i];
  310. b[i] = b[iMax];
  311. b[iMax] = dMax;
  312. }
  313. for(j = i +1; j < size; j++)
  314. {
  315. dMax = a[j * size + i] / a[i * size + i];
  316. a[j * size + i] = 0.0;
  317. for(k = i + 1; k< size; k++)
  318. {
  319. a[j * size + k] -= dMax * a[i * size + k];
  320. }
  321. b[j] -= dMax * b[i];
  322. }
  323. }
  324. x[size -1] = b[size -1] / a[size * size -1];
  325. for(k = size - 2; k > -1; k--)
  326. {
  327. dMax = 0.0;
  328. for(j = k + 1; j< size; j++)
  329. {
  330. dMax += a[k * size + j] * x[j];
  331. }
  332. x[k] = (b[k] - dMax) / a[k * size + k];
  333. }
  334. return bIll;
  335. }
  336. BOOL CMathEx::FFT(const COMPLEX *TD, COMPLEX *FD, int power)
  337. {
  338. ASSERT((NULL != TD) && (NULL != FD));
  339. int i, j, k, bfsize, p, iIndex;;
  340. double angle;
  341. int count = 1 << power;//变换点数
  342. double PAI2 = PAI * 2.0;
  343. COMPLEX *W, *X1, *X2, *X = NULL;
  344. W = new COMPLEX[count / 2];
  345. if(NULL == W)
  346. {
  347. printf("Sorry, insufficent memory available!");
  348. return FALSE;
  349. }
  350. X1 = new COMPLEX[count];
  351. if(NULL == X1)
  352. {
  353. delete W;
  354. printf("Sorry, insufficent memory available!");
  355. return FALSE;
  356. }
  357. X2 = new COMPLEX[count];
  358. if(NULL == X2)
  359. {
  360. printf("Sorry, insufficent memory available!");
  361. delete X1;
  362. delete W;
  363. return FALSE;
  364. }
  365. //计算加权系数
  366. for(i = 0; i < count / 2 ; i++)
  367. {
  368. angle = -i * PAI2 / count;
  369. W[i].re = cos(angle);
  370. W[i].im = sin(angle);
  371. }
  372. memcpy(X1, TD, sizeof(COMPLEX) * count);
  373. //蝶形运算
  374. for(k = 0; k < power; k++)
  375. {
  376. for(j = 0; j < 1<<k; j++)
  377. {
  378. bfsize = (1<<(power - k)) / 2;
  379. for(i = 0; i < bfsize; i++)
  380. {
  381. p = j * bfsize * 2;
  382. iIndex = i + p;
  383. X2[iIndex] = Add(X1[iIndex], X1[iIndex + bfsize]);
  384. X2[iIndex + bfsize] = Mul(Sub(X1[iIndex], X1[iIndex + bfsize]),
  385. (W[i * (1 << k)]));
  386. }
  387. }
  388. X = X1;
  389. X1 = X2;
  390. X2 = X;
  391. }
  392. //重新排续
  393. for(j =0 ; j < count; j++)
  394. {
  395. p = 0;
  396. for(i = 0; i < power; i++)
  397. {
  398. if(j & (1<<i))
  399. {
  400. p += 1<<(power - i -1);
  401. }
  402. FD[j] = X1[p];
  403. }
  404. }
  405. delete W;
  406. delete X1;
  407. delete X2;
  408. return TRUE;
  409. }
  410. BOOL CMathEx::IFFT(const COMPLEX *FD, COMPLEX *TD, int power)
  411. {
  412. ASSERT((NULL != TD) && (NULL != FD));
  413. int count = 1 << power;
  414. COMPLEX *x = new COMPLEX[count];
  415. if(NULL == x)
  416. {
  417. printf("Sorry, insufficent memory available!");
  418. return FALSE;
  419. }
  420. memcpy(x, FD, sizeof(COMPLEX) * count);
  421. for(int i =0; i < count; i ++)
  422. {
  423. x[i].im = - x[i].im;
  424. }
  425. FFT(x, TD, power);
  426. for(i =0; i < count; i++)
  427. {
  428. TD[i].re /= count;
  429. TD[i].im = -TD[i].im / count;
  430. }
  431. delete x;
  432. return TRUE;
  433. }
  434. /*******************************************************
  435. DCT()
  436. 参数:
  437. f为时域值
  438. F为频域值
  439. power为2的幂数
  440. 返回值:
  441. 说明:
  442. 本函数利用快速傅立叶变换实现快速离散余弦变换
  443. ********************************************************/
  444. void CMathEx::DCT(double *f, double *F, int power)
  445. {
  446. int i,count;
  447. COMPLEX *X;
  448. double s;
  449. /*计算离散余弦变换点数*/
  450. count=1<<power;
  451. /*分配运算所需存储器*/
  452. X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
  453. /*延拓*/
  454. memset(X,0,sizeof(COMPLEX)*count*2);
  455. /*将时域点写入存储器*/
  456. for(i=0;i<count;i++)
  457. {
  458. X[i].re=f[i];
  459. }
  460. /*调用快速傅立叶变换*/
  461. FFT(X,X,power+1);
  462. /*调整系数*/
  463. s=1/sqrt(count);
  464. F[0]=X[0].re*s;
  465. s*=sqrt(2);
  466. for(i=1;i<count;i++)
  467. {
  468. F[i]=(X[i].re*cos(i*PAI/(count*2))+X[i].im*sin(i*PAI/(count*2)))*s;
  469. }
  470. /*释放存储器*/
  471. free(X);
  472. }
  473. /************************************************************
  474. IDCT()
  475. 参数:
  476. F为频域值
  477. f为时域值
  478. power为2的幂数
  479. 返回值:
  480. 说明:
  481. 本函数利用快速傅立叶反变换实现快速离散反余弦变换
  482. *************************************************************/
  483. void CMathEx::IDCT(double *F, double *f, int power)
  484. {
  485. int i,count;
  486. COMPLEX *X;
  487. double s;
  488. /*计算离散反余弦变换点数*/
  489. count=1<<power;
  490. /*分配运算所需存储器*/
  491. X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
  492. /*延拓*/
  493. memset(X,0,sizeof(COMPLEX)*count*2);
  494. /*调整频域点,写入存储器*/
  495. for(i=0;i<count;i++)
  496. {
  497. X[i].re=F[i]*cos(i*PAI/(count*2));
  498. X[i].im=F[i]*sin(i*PAI/(count*2));
  499. }
  500. /*调用快速傅立叶反变换*/
  501. IFFT(X,X,power+1);
  502. /*调整系数*/
  503. s=1/sqrt(count);
  504. for(i=1;i<count;i++)
  505. {
  506. f[i]=(1-sqrt(2))*s*F[0]+sqrt(2)*s*X[i].re*count*2;
  507. }
  508. /*释放存储器*/
  509. free(X);
  510. }
  511. /**********************************************************
  512. WALh()
  513. 参数:
  514. f为时域值
  515. W为频域值
  516. power为2的幂数
  517. 返回值:
  518. 说明:
  519. 本函数利用快速傅立叶变换实现快速沃尔什-哈达玛变换
  520. *************************************************************/
  521. void CMathEx::WALh(double *f, double *W, int power)
  522. {
  523. int count;
  524. int i,j,k,bfsize,p;
  525. double *X1,*X2,*X;
  526. /*计算快速沃尔什变换点数*/
  527. count=1<<power;
  528. /*分配运算所需存储器*/
  529. X1=(double *)malloc(sizeof(double)*count);
  530. X2=(double *)malloc(sizeof(double)*count);
  531. /*将时域点写入存储器*/
  532. memcpy(X1,f,sizeof(double)*count);
  533. /*蝶形运算*/
  534. for(k=0;k<power;k++)
  535. {
  536. for(j=0;j<1<<k;j++)
  537. {
  538. bfsize=1<<(power-k);
  539. for(i=0;i<bfsize/2;i++)
  540. {
  541. p=j*bfsize;
  542. X2[i+p]=X1[i+p]+X1[i+p+bfsize/2];
  543. X2[i+p+bfsize/2]=X1[i+p]-X1[i+p+bfsize/2];
  544. }
  545. }
  546. X=X1;
  547. X1=X2;
  548. X2=X;
  549. }
  550. /*调整系数*/
  551. // for(i=0;i<count;i++)
  552. // {
  553. // W[i]=X1[i]/count;
  554. // }
  555. for(j=0;j<count;j++)
  556. {
  557. p=0;
  558. for(i=0;i<power;i++)
  559. {
  560. if (j&(1<<i)) p+=1<<(power-i-1);
  561. }
  562. W[j]=X1[p]/count;
  563. }
  564. /*释放存储器*/
  565. free(X1);
  566. free(X2);
  567. }
  568. /*********************************************************************
  569. IWALh()
  570. 参数:
  571. W为频域值
  572. f为时域值
  573. power为2的幂数
  574. 返回值:
  575. 说明:
  576. 本函数利用快速沃尔什-哈达玛变换实现快速沃尔什-哈达玛反变换
  577. **********************************************************************/
  578. void CMathEx::IWALh(double *W, double *f, int power)
  579. {
  580. int i, count;
  581. /*计算快速沃尔什反变换点数*/
  582. count=1<<power;
  583. /*调用快速沃尔什-哈达玛变换*/
  584. WALh(W, f, power);
  585. /*调整系数*/
  586. for(i=0;i<count;i++)
  587. {
  588. f[i] *= count;
  589. }
  590. }
  591. double CMathEx::GetArea(POINT vert, POINT from, POINT to)
  592. {
  593. int dx, dy;
  594. dx = from.x - vert.x;
  595. dy = from.y - vert.y;
  596. double sf = sqrt(double(dx * dx + dy * dy));
  597. double sinf = (0 == dx && 0 == dy) ? 0 : dy / sf;
  598. double cosf = (0 == dx && 0 == dy) ? 0 : dx / sf;
  599. dx = to.x - vert.x;
  600. dy = to.y - vert.y;
  601. double st = sqrt(double(dx * dx + dy * dy));
  602. double sint = (0 == dx && 0 == dy) ? 0 : dy / st;
  603. double cost = (0 == dx && 0 == dy) ? 0 : dx / st;
  604. return sf * (sinf * cost - cosf * sint) * st * 0.5;
  605. }
  606. int CMathEx::compare(const void *arg1, const void *arg2)
  607. {
  608. if(*((float*)arg1) < *((float*)arg2))
  609. return -1;
  610. if(*((float*)arg1) > *((float*)arg2))
  611. return 1;
  612. return 0;
  613. }
  614. BOOL CMathEx::MedianFilter(float *pData, int iWidth, int iHeight)
  615. {
  616. float *pSub = new float[iWidth * 2];
  617. if(NULL == pSub)
  618. {
  619. return FALSE;
  620. }
  621. float *pWin = new float[9];
  622. if(NULL == pWin)
  623. {
  624. delete pWin;
  625. return FALSE;
  626. }
  627. int x, y;
  628. int iRowSize = iWidth * sizeof(float);
  629. int row;
  630. memcpy(&pSub[iWidth], pData, iRowSize);
  631. for(y = 1; y < iHeight -1; y++)
  632. {
  633. memmove(pSub, &pSub[iWidth], iRowSize);
  634. row = y * iWidth;
  635. memcpy(&pSub[iWidth], &pData[row], iRowSize);
  636. for(x = 1; x <  iWidth-1; x++)
  637. {
  638. pWin[0] = pSub[x -1];
  639. pWin[1] = pSub[x];
  640. pWin[2] = pSub[x +1];
  641. pWin[3] = pSub[iWidth + x -1];
  642. pWin[4] = pSub[iWidth + x];
  643. pWin[5] = pSub[iWidth + x +1];
  644. pWin[6] = pData[row + iWidth + x -1];
  645. pWin[7] = pData[row + iWidth + x];
  646. pWin[8] = pData[row + iWidth + x +1];
  647. qsort(pWin, 9, sizeof(float), compare);
  648. pData[row + x] = pWin[4];
  649. }
  650. }
  651. delete pWin;
  652. delete pSub;
  653. return TRUE;
  654. }