PinYuLuBoDib.cpp
上传用户:hnhlzg
上传日期:2013-10-19
资源大小:289k
文件大小:22k
源码类别:

数学计算

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "windowsx.h"
  3. #include "math.h"
  4. #include "PinYuLuBoDib.h"
  5. #include "malloc.h"
  6. #include "MainFrm.h"
  7. #include "DSplitView.h"
  8. #include "Cdib.h"
  9. #define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4) 
  10. #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
  11. #define pi 3.14159265359
  12.  
  13.  
  14. PinYuLuBoDib::PinYuLuBoDib()
  15. {
  16. }
  17. PinYuLuBoDib::~PinYuLuBoDib()
  18. {
  19. }
  20. CNumber PinYuLuBoDib::Add(CNumber c1,CNumber c2)
  21. {
  22. CNumber c;
  23. c.re=c1.re+c2.re;
  24. c.im=c1.im+c2.im;
  25. return c;
  26. }
  27. CNumber PinYuLuBoDib::Sub(CNumber c1,CNumber c2)
  28. {
  29. CNumber c;
  30. c.re=c1.re-c2.re;
  31. c.im=c1.im-c2.im;
  32. return c;
  33. }
  34. CNumber PinYuLuBoDib::Mul(CNumber c1,CNumber c2)
  35. {
  36. CNumber c;
  37. c.re=c1.re*c2.re-c1.im*c2.im;
  38. c.im=c1.re*c2.im+c2.re*c1.im;
  39. return c;
  40. }
  41. ///////////////////////////////////////////////////
  42. //此函数实现快速傅立叶变换
  43. //参数t、f分别是指向时域和频域的指针,power是2的幂数
  44. ///////////////////////////////////////////////////
  45. void PinYuLuBoDib::QFC(CNumber* t,CNumber* f,int power)
  46. {
  47. long count;//傅立叶变换点数
  48. int i,j,k,p,bfsize;
  49. CNumber *w,*x,*a,*b;//复数结构类型的指针变量,其中w指向加权系数
  50. double angle;//计算加权系数所用的角度值
  51. count=1<<power;//计算傅立叶变换点数
  52. //分配所需运算空间
  53. w=new CNumber[count/2];
  54. a=new CNumber[count];
  55. b=new CNumber[count];
  56. //计算加权系数
  57. for(i=0;i<count/2;i++)
  58. {
  59. angle=-i*pi*2/count;
  60. w[i].re=cos(angle);
  61. w[i].im=sin(angle);
  62. }
  63. memcpy(a,t,sizeof(CNumber)*count);
  64. //采用频率分解法进行蝶形运算
  65. for(k=0;k<power;k++)
  66. {
  67. for(j=0;j<1<<k;j++)
  68. {
  69. bfsize=1<<(power-k);
  70. for(i=0;i<bfsize/2;i++)
  71. {
  72. p=j*bfsize;
  73. b[i+p]=Add(a[i+p],a[i+p+bfsize/2]);
  74. b[i+p+bfsize/2]=Mul(Sub(a[i+p],a[i+p+bfsize/2]),w[i*(1<<k)]);
  75. }
  76. }
  77. x=a;
  78. a=b;
  79. b=x;
  80. }
  81. //将乱序的变换序列重新排序
  82. for(j=0;j<count;j++)
  83. {
  84. p=0;
  85. for(i=0;i<power;i++)
  86. {
  87. if(j&(1<<i))
  88. p+=1<<(power-i-1);
  89. }
  90. f[j]=a[p];
  91. }
  92. //释放存储器空间
  93. delete w;
  94. delete a;
  95. delete b;
  96. }
  97. ///////////////////////////////////////////////
  98. //此函数用来实现图象的傅立叶变换
  99. //两次调用快速傅立叶变换QFC()实现二维傅立叶变换
  100. ///////////////////////////////////////////////
  101. void PinYuLuBoDib::QuickFourier()
  102. {
  103. LPBYTE  p_data, p;//指向原图象数据区指针
  104. int width,height;//原图象的宽度和高度       
  105. long w=1,h=1;//进行傅立叶变换的宽度和高度(2的整数次方)
  106. int wp=0,hp=0;//迭代次数
  107. int i,j;
  108. double temp;//中间变量
  109. CNumber *t,*f;
  110.     if(this->byBitCount==8) //灰度图像
  111.    p_data=this->GetData();//指向原图象数据区
  112. else //24位真彩色
  113.    p_data=this->GetData2();
  114. width=this->GetWidth();//得到图象宽度
  115. height=this->GetHeight();//得到图象高度
  116.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  117. while(w*2<=width)//计算进行傅立叶变换的宽度(2的整数次方)
  118. {
  119. w*=2;
  120. wp++;
  121. }
  122. while(h*2<=height)//计算进行傅立叶变换的高度(2的整数次方)
  123. {
  124. h*=2;
  125. hp++;
  126. }
  127. t=new CNumber[w*h];//分配存储器空间
  128. f=new CNumber[w*h];
  129. for(j=0;j<h;j++)
  130. {
  131. for(i=0;i<w;i++)
  132. {
  133. p=p_data+lLineBytes*(height-j-1)+i;//指向第i行第j列象素
  134. t[i+w*j].re=*(p);//给时域赋值
  135. t[i+w*j].im=0;
  136. }
  137. }
  138. for(j=0;j<h;j++)//在垂直方向上进行快速傅立叶变换
  139. {
  140. QFC(&t[w*j],&f[w*j],wp);
  141. }
  142. for(j=0;j<h;j++)//转换变换结果
  143. {
  144. for(i=0;i<w;i++)
  145. {
  146. t[j+h*i]=f[i+w*j];
  147. }
  148. }
  149. for(j=0;j<w;j++)//水平方向进行快速傅立叶变换
  150. {
  151. QFC(&t[j*h],&f[j*h],hp);
  152. }
  153. for(j=0;j<h;j++)
  154. {
  155. for(i=0;i<w;i++)
  156. {
  157. temp=sqrt(f[i*h+j].re*f[i*h+j].re+f[i*h+j].im*f[i*h+j].im)/100;
  158. if(temp>255)
  159. temp=255;
  160. p=p_data+lLineBytes*(height-(j<h/2?j+h/2:j-h/2)-1)+
  161. (i<w/2?i+w/2:i-w/2);//将变换后的原点移到中心
  162. *(p)=(BYTE)(temp);
  163. }
  164. }
  165. delete t;
  166. delete f;
  167. }
  168. ///////////////////////////////////////////////
  169. //此函数用来实现图象的傅立叶变换(没有对处理后的显示结果进行平移)
  170. //两次调用快速傅立叶变换QFC()实现二维傅立叶变换
  171. ///////////////////////////////////////////////
  172. void PinYuLuBoDib::FirstQuickFourier()
  173. {
  174. LPBYTE  p_data,p;//指向原图象数据区指针
  175. int width,height;//原图象的宽度和高度       
  176. long w=1,h=1;//进行傅立叶变换的宽度和高度(2的整数次方)
  177. int wp=0,hp=0;//迭代次数
  178. int i,j;
  179. double temp;//中间变量
  180. CNumber *t,*f;
  181.     if(this->byBitCount==8)//灰度图像
  182.    p_data=this->GetData();//指向原图象数据区
  183. else//24位真彩色
  184.    p_data=this->GetData2();
  185. width=this->GetWidth();//得到图象宽度
  186. height=this->GetHeight();//得到图象高度
  187.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  188. while(w*2<=width)//计算进行傅立叶变换的宽度(2的整数次方)
  189. {
  190. w*=2;
  191. wp++;
  192. }
  193. while(h*2<=height)//计算进行傅立叶变换的高度(2的整数次方)
  194. {
  195. h*=2;
  196. hp++;
  197. }
  198. t=new CNumber[w*h];//分配存储器空间
  199. f=new CNumber[w*h];
  200. for(j=0;j<h;j++)
  201. {
  202. for(i=0;i<w;i++)
  203. {
  204. p=p_data+lLineBytes*(height-j-1)+i;//指向第i行第j列象素
  205. t[i+w*j].re=*(p);//给时域赋值
  206. t[i+w*j].im=0;
  207. }
  208. }
  209. for(j=0;j<h;j++)//在垂直方向上进行快速傅立叶变换
  210. {
  211. QFC(&t[w*j],&f[w*j],wp);
  212. }
  213. for(j=0;j<h;j++)//转换变换结果
  214. {
  215. for(i=0;i<w;i++)
  216. {
  217. t[j+h*i]=f[i+w*j];
  218. }
  219. }
  220. for(j=0;j<w;j++)//水平方向进行快速傅立叶变换
  221. {
  222. QFC(&t[j*h],&f[j*h],hp);
  223. }
  224. for(j=0;j<h;j++)
  225. {
  226. for(i=0;i<w;i++)
  227. {
  228. temp=sqrt(f[i*h+j].re*f[i*h+j].re+f[i*h+j].im*f[i*h+j].im)/100;
  229. if(temp>255)
  230. temp=255;
  231. p=p_data+lLineBytes*(height-(j<h/2?j+h/2:j-h/2)-1)+
  232. (i<w/2?i+w/2:i-w/2);//将变换后的原点移到中心
  233. p=p_data+lLineBytes*(height-(j<h/2?j:j)-1)+
  234. (i<w/2?i:i);
  235. *(p)=(BYTE)(temp);
  236. }
  237. }
  238. delete t;
  239. delete f;
  240. }
  241. //////////////////////////////////////////////////////////////
  242. //该函数用来实现二维傅立叶变换
  243. //参数height、width分别表示图象的高度和宽度,ising表示正反变换
  244. //////////////////////////////////////////////////////////////
  245. void PinYuLuBoDib::fourier(double * data, int height, int width, int isign)
  246. {
  247. int idim;
  248. unsigned long i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2;
  249. unsigned long ibit,k1,k2,n,nprev,nrem,ntot,nn[3];
  250. double tempi,tempr;
  251. double theta,wi,wpi,wpr,wr,wtemp;
  252. ntot=height*width; 
  253. nn[1]=height;
  254. nn[2]=width;
  255. nprev=1;
  256. for (idim=2;idim>=1;idim--) 
  257. {
  258. n=nn[idim];
  259. nrem=ntot/(n*nprev);
  260. ip1=nprev << 1;
  261. ip2=ip1*n;
  262. ip3=ip2*nrem;
  263. i2rev=1;
  264. for (i2=1;i2<=ip2;i2+=ip1)
  265. {
  266. if (i2 < i2rev) 
  267. {
  268. for (i1=i2;i1<=i2+ip1-2;i1+=2) 
  269. {
  270. for (i3=i1;i3<=ip3;i3+=ip2)
  271. {
  272. i3rev=i2rev+i3-i2;
  273. SWAP(data[i3],data[i3rev]);
  274. SWAP(data[i3+1],data[i3rev+1]);
  275. }
  276. }
  277. }
  278. ibit=ip2 >> 1;
  279. while (ibit >= ip1 && i2rev > ibit)
  280. {
  281. i2rev -= ibit;
  282. ibit >>= 1;
  283. }
  284. i2rev += ibit;
  285. }
  286. ifp1=ip1;
  287. while (ifp1 < ip2) 
  288. {
  289. ifp2=ifp1 << 1;
  290. theta=isign*pi*2/(ifp2/ip1);
  291. wtemp=sin(0.5*theta);
  292. wpr = -2.0*wtemp*wtemp;
  293. wpi=sin(theta);
  294. wr=1.0;
  295. wi=0.0;
  296. for (i3=1;i3<=ifp1;i3+=ip1)
  297. {
  298. for (i1=i3;i1<=i3+ip1-2;i1+=2) 
  299. {
  300. for (i2=i1;i2<=ip3;i2+=ifp2) 
  301. {
  302. k1=i2;
  303. k2=k1+ifp1;
  304. tempr=wr*data[k2]-wi*data[k2+1];
  305. tempi=wr*data[k2+1]+wi*data[k2];
  306. data[k2]=data[k1]-tempr;
  307. data[k2+1]=data[k1+1]-tempi;
  308. data[k1] += tempr;
  309. data[k1+1] += tempi;
  310. }
  311. }
  312. wr=(wtemp=wr)*wpr-wi*wpi+wr;
  313. wi=wi*wpr+wtemp*wpi+wi;
  314. }
  315. ifp1=ifp2;
  316. }
  317. nprev *= n;
  318. }
  319. }
  320. /*************************************************************************
  321. * 函数:BWFilterL(int u,int v,int u1,int v1)
  322. *参数:u、v分别是截止频率的x、y分量值,由用户给定
  323. *功能:此函数用来实现图象的布特沃斯低通滤波
  324. /*************************************************************************/
  325. void PinYuLuBoDib::BWFilterL(int u,int v,int n)
  326. {
  327. LPBYTE  p_data, p;//指向原图象数据区指针
  328. int width,height;//原图象的宽度和高度       
  329. int i,j;
  330. double max=0.0,d0,d;//中间变量
  331. double *t,*H;
  332. if(this->byBitCount==8)//灰度图像
  333.    p_data=this->GetData();//指向原图象数据区
  334. else//24位真彩色
  335.    p_data=this->GetData2();//指向原图象数据区
  336. width=this->GetWidth();//得到图象宽度
  337. height=this->GetHeight();//得到图象高度
  338.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  339. t=new double [height*lLineBytes*2+1];//分配存储器空间
  340. H=new double [height*lLineBytes*2+1];
  341. d0=sqrt(u*u+v*v);//计算截止频率d0
  342. for(j=0;j<height;j++)
  343. {
  344. for(i=0;i<lLineBytes;i++)
  345. {
  346. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  347. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  348. t[(2*lLineBytes)*j+2*i+2]=0.0;
  349. d=sqrt(i*i+j*j);
  350. H[2*i+(2*lLineBytes)*j+1]=1/(1+pow((d/d0),(2*n)));
  351. H[2*i+(2*lLineBytes)*j+2]=0.0;
  352. }
  353. }
  354.     fourier(t,height,lLineBytes,1);
  355. for(j=1;j<height*lLineBytes*2;j+=2)
  356. {
  357. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  358. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  359. }
  360. fourier(t,height,lLineBytes,-1);
  361. for(j=0;j<height;j++)
  362. {
  363. for(i=0;i<lLineBytes;i++)
  364. {
  365. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  366. if(max<t[(2*lLineBytes)*j+2*i+1])
  367. max=t[(2*lLineBytes)*j+2*i+1];
  368. }
  369. }
  370. for(j=0;j<height;j++)
  371. {
  372. for(i=0;i<lLineBytes;i++)
  373. {
  374. p=p_data+lLineBytes*j+i;
  375. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  376. }
  377. }
  378. delete t;
  379. delete H;
  380. }
  381. ////////////////////////////////////////////////
  382. //此函数用来实现图象的布特沃斯高通滤波
  383. //参数u、v分别是截止频率的x、y分量值,由用户给定
  384. ////////////////////////////////////////////////
  385. void PinYuLuBoDib::BWFilterH(int u,int v,int n)
  386. {
  387. LPBYTE p_data,p;//指向原图象数据区指针
  388. int width,height;//原图象的宽度和高度       
  389. int i,j;
  390. double max=0.0,d0,d;//中间变量
  391. double *t,*H;
  392. if(this->byBitCount==8)//灰度图像
  393.    p_data=this->GetData();//指向原图象数据区
  394. else//24位真彩色
  395.    p_data=this->GetData2();//指向原图象数据区
  396. width=this->GetWidth();//得到图象宽度
  397. height=this->GetHeight();//得到图象高度
  398.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  399. t=new double [height*lLineBytes*2+1];//分配存储器空间
  400. H=new double [height*lLineBytes*2+1];
  401. d0=sqrt(u*u+v*v);//计算截止频率d0
  402. for(j=0;j<height;j++)
  403. {
  404. for(i=0;i<lLineBytes;i++)
  405. {
  406. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  407. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  408. t[(2*lLineBytes)*j+2*i+2]=0.0;
  409. d=sqrt(j*j+i*i);
  410. H[2*i+(2*lLineBytes)*j+1]=1/(1+pow((d0/d),(2*n)));
  411. H[2*i+(2*lLineBytes)*j+2]=0.0;
  412. }
  413. }
  414.     fourier(t,height,lLineBytes,1);
  415. for(j=1;j<height*lLineBytes*2;j+=2)
  416. {
  417. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  418. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  419. }
  420. fourier(t,height,lLineBytes,-1);
  421. for(j=0;j<height;j++)
  422. {
  423. for(i=0;i<lLineBytes;i++)
  424. {
  425. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  426. if(max<t[(2*lLineBytes)*j+2*i+1])
  427. max=t[(2*lLineBytes)*j+2*i+1];
  428. }
  429. }
  430. for(j=0;j<height;j++)
  431. {
  432. for(i=0;i<lLineBytes;i++)
  433. {
  434. p=p_data+lLineBytes*j+i;
  435. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  436. }
  437. }
  438. delete t;
  439. delete H;
  440. }
  441. /*************************************************************************
  442. * 函数:PerfectFilterL(int u,int v)
  443. *参数:u、v分别是截止频率的x、y分量值,由用户给定
  444. *功能:此函数用来实现图象的理想低通滤波
  445. /*************************************************************************/
  446.  void PinYuLuBoDib::PerfectFilterL(int u,int v)
  447. {
  448. LPBYTE  p_data, p;//指向原图象数据区指针
  449. int width,height;//原图象的宽度和高度       
  450. int i,j;
  451. double d0,max=0.0;//中间变量
  452. double *t,*H;
  453. if(this->byBitCount==8)//灰度图像
  454. p_data=this->GetData();//指向原图象数据区
  455. else//24位真彩色
  456. p_data=this->GetData2();//指向原图象数据区
  457. width=this->GetWidth();//得到图象宽度
  458. height=this->GetHeight();//得到图象高度
  459.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  460. t=new double [height*lLineBytes*2+1];//分配存储器空间
  461. H=new double [height*lLineBytes*2+1];
  462. d0=sqrt(u*u+v*v);//计算截止频率d0
  463. for(j=0;j<height;j++)
  464. {
  465. for(i=0;i<lLineBytes;i++)
  466. {
  467. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  468. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  469. t[(2*lLineBytes)*j+2*i+2]=0.0;
  470. if((sqrt(i*i+j*j))<=d0)
  471. H[2*i+(2*lLineBytes)*j+1]=1.0;
  472. else
  473. H[2*i+(2*lLineBytes)*j+1]=0.0;
  474. H[2*i+(2*lLineBytes)*j+2]=0.0;
  475. }
  476. }
  477.     fourier(t,height,lLineBytes,1);
  478. for(j=1;j<height*lLineBytes*2;j+=2)
  479. {
  480. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  481. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  482. }
  483. fourier(t,height,lLineBytes,-1);
  484. for(j=0;j<height;j++)
  485. {
  486. for(i=0;i<lLineBytes;i++)
  487. {
  488. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  489. if(max<t[(2*lLineBytes)*j+2*i+1])
  490. max=t[(2*lLineBytes)*j+2*i+1];
  491. }
  492. }
  493. for(j=0;j<height;j++)
  494. {
  495. for(i=0;i<lLineBytes;i++)
  496. {
  497. p=p_data+lLineBytes*j+i;
  498. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  499. }
  500. }
  501. delete t;
  502. delete H;
  503. }
  504. ////////////////////////////////////////////////
  505. //此函数用来实现图象的理想高通滤波
  506. //参数u、v分别是截止频率的x、y分量值,由用户给定
  507. ////////////////////////////////////////////////
  508. void PinYuLuBoDib::PerfectFilterH(int u,int v)
  509. {
  510. LPBYTE  p_data, p;//指向原图象数据区指针
  511. int width,height;//原图象的宽度和高度       
  512. int i,j;
  513. double d0,max=0.0;//中间变量
  514. double *t,*H;
  515. if(this->byBitCount==8)//灰度图像
  516. p_data=this->GetData();//指向原图象数据区
  517. else//24位真彩色
  518. p_data=this->GetData2();//指向原图象数据区
  519. width=this->GetWidth();//得到图象宽度
  520. height=this->GetHeight();//得到图象高度
  521.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  522. t=new double [height*lLineBytes*2+1];//分配存储器空间
  523. H=new double [height*lLineBytes*2+1];
  524. d0=sqrt(u*u+v*v);//计算截止频率d0
  525. for(j=0;j<height;j++)
  526. {
  527. for(i=0;i<lLineBytes;i++)
  528. {
  529. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  530. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  531. t[(2*lLineBytes)*j+2*i+2]=0.0;
  532. if((sqrt(i*i+j*j))<=d0)
  533. H[2*i+(2*lLineBytes)*j+1]=0.0;
  534. else
  535. H[2*i+(2*lLineBytes)*j+1]=1.0;
  536. H[2*i+(2*lLineBytes)*j+2]=0.0;
  537. }
  538. }
  539.     fourier(t,height,lLineBytes,1);
  540. for(j=1;j<height*lLineBytes*2;j+=2)
  541. {
  542. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  543. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  544. }
  545. fourier(t,height,lLineBytes,-1);
  546. for(j=0;j<height;j++)
  547. {
  548. for(i=0;i<lLineBytes;i++)
  549. {
  550. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  551. if(max<t[(2*lLineBytes)*j+2*i+1])
  552. max=t[(2*lLineBytes)*j+2*i+1];
  553. }
  554. }
  555. for(j=0;j<height;j++)
  556. {
  557. for(i=0;i<lLineBytes;i++)
  558. {
  559. p=p_data+lLineBytes*j+i;
  560. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  561. }
  562. }
  563. delete t;
  564. delete H;
  565. }
  566. /*************************************************************************
  567. * 函数:TLFilter(int u,int v,int u1,int v1)
  568. *参数:u、v分别是截止频率的x、y分量值,由用户给定
  569. *功能:此函数用来实现图象的梯形低通滤波
  570. /*************************************************************************/
  571. void PinYuLuBoDib::TLFilter(int u,int v,int u1,int v1)
  572. {
  573. LPBYTE  p_data, p;//指向原图象数据区指针
  574. int width,height;//原图象的宽度和高度       
  575. int i,j;
  576. double max=0.0,d0,d,d1;//中间变量
  577. double *t,*H;
  578. if(this->byBitCount==8)//灰度图像
  579.    p_data=this->GetData();//指向原图象数据区
  580. else//24位真彩色
  581.    p_data=this->GetData2();//指向原图象数据区
  582. width=this->GetWidth();//得到图象宽度
  583. height=this->GetHeight();//得到图象高度
  584.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  585. t=new double [height*lLineBytes*2+1];//分配存储器空间
  586. H=new double [height*lLineBytes*2+1];
  587. d0=sqrt(u*u+v*v);//计算截止频率d0
  588. d1=sqrt(u1*u1+v1*v1);
  589. for(j=0;j<height;j++)
  590. {
  591. for(i=0;i<lLineBytes;i++)
  592. {
  593. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  594. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  595. t[(2*lLineBytes)*j+2*i+2]=0.0;
  596. d=sqrt(i*i+j*j);
  597. if(d<d0)
  598. {
  599. H[2*i+(2*lLineBytes)*j+1]=1;
  600. H[2*i+(2*lLineBytes)*j+2]=0.0;
  601. }
  602. if(d>d1)
  603. {
  604. H[2*i+(2*lLineBytes)*j+1]=0.0;
  605. H[2*i+(2*lLineBytes)*j+2]=0.0;
  606. }
  607. else
  608. {
  609. H[2*i+(2*lLineBytes)*j+1]=(d-d1)/(d0-d1);
  610. H[2*i+(2*lLineBytes)*j+2]=0.0;
  611. }
  612. }
  613. }
  614.     fourier(t,height,lLineBytes,1);
  615. for(j=1;j<height*lLineBytes*2;j+=2)
  616. {
  617. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  618. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  619. }
  620. fourier(t,height,lLineBytes,-1);
  621. for(j=0;j<height;j++)
  622. {
  623. for(i=0;i<lLineBytes;i++)
  624. {
  625. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  626. if(max<t[(2*lLineBytes)*j+2*i+1])
  627. max=t[(2*lLineBytes)*j+2*i+1];
  628. }
  629. }
  630. for(j=0;j<height;j++)
  631. {
  632. for(i=0;i<lLineBytes;i++)
  633. {
  634. p=p_data+lLineBytes*j+i;
  635. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  636. }
  637. }
  638. delete t;
  639. delete H;
  640. }
  641. ////////////////////////////////////////////////
  642. //此函数用来实现图象的梯形高通滤波
  643. //参数u、v分别是截止频率的x、y分量值,由用户给定
  644. ////////////////////////////////////////////////
  645. void PinYuLuBoDib::THFilter(int u,int v,int u1,int v1)
  646. {
  647. LPBYTE  p_data, p;//指向原图象数据区指针
  648. int width,height;//原图象的宽度和高度       
  649. int i,j;
  650. double max=0.0,d0,d,d1;//中间变量
  651. double *t,*H;
  652. if(this->byBitCount==8)//灰度图像
  653. p_data=this->GetData();//指向原图象数据区
  654. else//24位真彩色
  655. p_data=this->GetData2();//指向原图象数据区
  656. width=this->GetWidth();//得到图象宽度
  657. height=this->GetHeight();//得到图象高度
  658.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  659. t=new double [height*lLineBytes*2+1];//分配存储器空间
  660. H=new double [height*lLineBytes*2+1];
  661. d0=sqrt(u*u+v*v);//计算截止频率d0
  662. d1=sqrt(u1*u1+v1*v1);
  663. for(j=0;j<height;j++)
  664. {
  665. for(i=0;i<lLineBytes;i++)
  666. {
  667. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  668. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  669. t[(2*lLineBytes)*j+2*i+2]=0.0;
  670. d=sqrt(i*i+j*j);
  671. if(d<d0)
  672. {
  673. H[2*i+(2*lLineBytes)*j+1]=0;
  674. H[2*i+(2*lLineBytes)*j+2]=0.0;
  675. }
  676. if(d>d1)
  677. {
  678. H[2*i+(2*lLineBytes)*j+1]=1;
  679. H[2*i+(2*lLineBytes)*j+2]=0.0;
  680. }
  681. else
  682. {
  683. H[2*i+(2*lLineBytes)*j+1]=(d-d0)/(d1-d0);
  684. H[2*i+(2*lLineBytes)*j+2]=0.0;
  685. }
  686. }
  687. }
  688.     fourier(t,height,lLineBytes,1);
  689. for(j=1;j<height*lLineBytes*2;j+=2)
  690. {
  691. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  692. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  693. }
  694. fourier(t,height,lLineBytes,-1);
  695. for(j=0;j<height;j++)
  696. {
  697. for(i=0;i<lLineBytes;i++)
  698. {
  699. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  700. if(max<t[(2*lLineBytes)*j+2*i+1])
  701. max=t[(2*lLineBytes)*j+2*i+1];
  702. }
  703. }
  704. for(j=0;j<height;j++)
  705. {
  706. for(i=0;i<lLineBytes;i++)
  707. {
  708. p=p_data+lLineBytes*j+i;
  709. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  710. }
  711. }
  712. delete t;
  713. delete H;
  714. }
  715. /*************************************************************************
  716. * 函数:ZLFilter(int u,int v,int u1,int v1)
  717. *参数:u、v分别是截止频率的x、y分量值,由用户给定
  718. *功能:此函数用来实现图象的指数低通滤波
  719. ///////////////////////////////////////////////*/
  720. void PinYuLuBoDib::ZLFilter(int u,int v,int n)
  721. {
  722. LPBYTE  p_data, p;//指向原图象数据区指针
  723. int width,height;//原图象的宽度和高度       
  724. int i,j;
  725. double max=0.0,d0,d;//中间变量
  726. double *t,*H;
  727. if(this->byBitCount==8)//灰度图像
  728. p_data=this->GetData();//指向原图象数据区
  729. else//24位真彩色
  730. p_data=this->GetData2();//指向原图象数据区
  731. width=this->GetWidth();//得到图象宽度
  732. height=this->GetHeight();//得到图象高度
  733.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  734. t=new double [height*lLineBytes*2+1];//分配存储器空间
  735. H=new double [height*lLineBytes*2+1];
  736. d0=sqrt(u*u+v*v);//计算截止频率d0
  737. for(j=0;j<height;j++)
  738. {
  739. for(i=0;i<lLineBytes;i++)
  740. {
  741. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  742. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  743. t[(2*lLineBytes)*j+2*i+2]=0.0;
  744. d=sqrt(i*i+j*j);
  745. H[2*i+(2*lLineBytes)*j+1]=exp(-pow((d/d0),n));
  746. H[2*i+(2*lLineBytes)*j+2]=0.0;
  747. }
  748. }
  749.     fourier(t,height,lLineBytes,1);
  750. for(j=1;j<height*lLineBytes*2;j+=2)
  751. {
  752. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  753. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  754. }
  755. fourier(t,height,lLineBytes,-1);
  756. for(j=0;j<height;j++)
  757. {
  758. for(i=0;i<lLineBytes;i++)
  759. {
  760. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  761. if(max<t[(2*lLineBytes)*j+2*i+1])
  762. max=t[(2*lLineBytes)*j+2*i+1];
  763. }
  764. }
  765. for(j=0;j<height;j++)
  766. {
  767. for(i=0;i<lLineBytes;i++)
  768. {
  769. p=p_data+lLineBytes*j+i;
  770. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  771. }
  772. }
  773. delete t;
  774. delete H;
  775. }
  776. ////////////////////////////////////////////////
  777. //此函数用来实现图象的指数高通滤波
  778. //参数u、v分别是截止频率的x、y分量值,由用户给定
  779. ////////////////////////////////////////////////
  780. void PinYuLuBoDib::ZHFilter(int u,int v,int n)
  781. {
  782. LPBYTE  p_data, p;//指向原图象数据区指针
  783. int width,height;//原图象的宽度和高度       
  784. int i,j;
  785. double max=0.0,d0,d;//中间变量
  786. double *t,*H;
  787. if(this->byBitCount==8)//灰度图像
  788. p_data=this->GetData();//指向原图象数据区
  789. else//24位真彩色
  790. p_data=this->GetData2();//指向原图象数据区
  791. width=this->GetWidth();//得到图象宽度
  792. height=this->GetHeight();//得到图象高度
  793.     long lLineBytes=WIDTHBYTES(width*8);//计算图象每行的字节数
  794. t=new double [height*lLineBytes*2+1];//分配存储器空间
  795. H=new double [height*lLineBytes*2+1];
  796. d0=sqrt(u*u+v*v);//计算截止频率d0
  797. for(j=0;j<height;j++)
  798. {
  799. for(i=0;i<lLineBytes;i++)
  800. {
  801. p=p_data+lLineBytes*j+i;//指向第i行第j列象素
  802. t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
  803. t[(2*lLineBytes)*j+2*i+2]=0.0;
  804. d=sqrt(i*i+j*j);
  805. H[2*i+(2*lLineBytes)*j+1]=exp(-pow((d0/d),n));
  806. H[2*i+(2*lLineBytes)*j+2]=0.0;
  807. }
  808. }
  809.     fourier(t,height,lLineBytes,1);
  810. for(j=1;j<height*lLineBytes*2;j+=2)
  811. {
  812. t[j]=t[j]*H[j]-t[j+1]*H[j+1];
  813. t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
  814. }
  815. fourier(t,height,lLineBytes,-1);
  816. for(j=0;j<height;j++)
  817. {
  818. for(i=0;i<lLineBytes;i++)
  819. {
  820. t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
  821. if(max<t[(2*lLineBytes)*j+2*i+1])
  822. max=t[(2*lLineBytes)*j+2*i+1];
  823. }
  824. }       
  825. for(j=0;j<height;j++)
  826. {
  827. for(i=0;i<lLineBytes;i++)
  828. {
  829. p=p_data+lLineBytes*j+i;
  830. *(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
  831. }
  832. }
  833. delete t;
  834. delete H;
  835. }