图像的正交变换----傅立叶变换

处理图像的空间:图像域(空间域)和变换域(频率域)
傅立叶变换:
  
  
  1. /*************************************************************************
  2. *
  3. * 函数名称:
  4. * FFT()
  5. *
  6. * 参数:
  7. * complex<double> * TD - 指向时域数组的指针
  8. * complex<double> * FD - 指向频域数组的指针
  9. * r -2的幂数,即迭代次数
  10. *
  11. * 返回值:
  12. * 无。
  13. *
  14. * 说明:
  15. * 该函数用来实现快速付立叶变换。
  16. *
  17. ************************************************************************/
  18. void FFT(std::complex<double>*TD,std::complex<double>*FD,int r);
  19. /*************************************************************************
  20. *
  21. * 函数名称:
  22. * IFFT()
  23. *
  24. * 参数:
  25. * complex<double> * FD - 指向频域值的指针
  26. * complex<double> * TD - 指向时域值的指针
  27. * r -2的幂数
  28. *
  29. * 返回值:
  30. * 无。
  31. *
  32. * 说明:
  33. * 该函数用来实现快速付立叶逆变换。
  34. *
  35. ************************************************************************/
  36. void IFFT(std::complex<double>* FD, std::complex<double>* TD,int r);
  37. /*************************************************************************
  38. *
  39. * 函数名称:
  40. * Fourier()
  41. *
  42. * 参数:
  43. * complex* TD - 输入的时域序列
  44. * LONG lWidth - 图象宽度
  45. * LONG lHeight - 图象高度
  46. * complex* FD - 输出的频域序列
  47. *
  48. * 返回值:
  49. * BOOL - 成功返回TRUE,否则返回FALSE。
  50. *
  51. * 说明:
  52. * 该函数进行二维快速付立叶变换。
  53. *
  54. ************************************************************************/
  55. BOOL Fourier(std::complex<double>* TD, LONG width, LONG height, std::complex<double>* FD);
  56. /*************************************************************************
  57. *
  58. * 函数名称:
  59. * IFourier()
  60. *
  61. * 参数:
  62. * LPBYTE TD - 返回的空域数据
  63. * LONG lWidth - 空域图象的宽度
  64. * LONG lHeight - 空域图象的高度
  65. * complex* FD - 输入的频域数据
  66. *
  67. * 返回值:
  68. * BOOL - 成功返回TRUE,否则返回FALSE。
  69. *
  70. * 说明:
  71. * 该函数进行二维快速付立叶逆变换。
  72. *
  73. ************************************************************************/
  74. BOOL IFourier(LPBYTE TD, LONG width, LONG height, std::complex<double>* FD);
  75. /*************************************************************************
  76. *
  77. * 函数名称:
  78. * BmpFourier()
  79. *
  80. * 参数:
  81. * BYTE *bmp --------待处理的图像
  82. LONG width,LONG height-------图像的宽度和高度
  83. *
  84. * 返回值:
  85. * BOOL - 成功返回TRUE,否则返回FALSE。
  86. *
  87. * 说明:
  88. * 该函数用来对图像进行付立叶变换。
  89. *
  90. ************************************************************************/
  91. BOOL BmpFourier(BYTE* bmp,LONG width,LONG height);
   
   
  1. voidMyProcess::FFT(std::complex<double>*TD,std::complex<double>*FD,int r)
  2. {
  3. // 循环变量
  4. LONG i;
  5. LONG j;
  6. LONG k;
  7. // 中间变量
  8. int p;
  9. // 角度
  10. double angle;
  11. complex<double>*W,*X1,*X2,*X;
  12. // 计算付立叶变换点数
  13. LONG N =1<< r;
  14. // 分配运算所需存储器
  15. W =new complex<double>[N /2];
  16. X1 =new complex<double>[N];
  17. X2 =new complex<double>[N];
  18. // 计算加权系数
  19. for(i =0; i < N /2; i++)
  20. {
  21. angle =-i * PI *2/ N;
  22. W[i]= complex<double>(cos(angle), sin(angle));
  23. }
  24. // 将时域点写入X1
  25. memcpy(X1, TD,sizeof(complex<double>)* N);
  26. // 采用蝶形算法进行快速付立叶变换
  27. for(k =0; k < r; k++)
  28. {
  29. for(j =0; j <1<< k; j++)
  30. {
  31. for(i =0; i <1<<(r - k -1); i++)
  32. {
  33. p = j *(1<<(r - k));
  34. X2[i + p]= X1[i + p]+ X1[i + p +(int)(1<<(r - k -1))];
  35. X2[i + p +(int)(1<<(r - k -1))]=(X1[i + p]- X1[i + p +(int)(1<<(r - k -1))])* W[i *(1<<k)];
  36. }
  37. }
  38. X = X1;
  39. X1 = X2;
  40. X2 = X;
  41. }
  42. // 重新排序
  43. for(j =0; j < N; j++)
  44. {
  45. p =0;
  46. for(i =0; i < r; i++)
  47. {
  48. if(j&(1<<i))
  49. {
  50. p+=1<<(r - i -1);
  51. }
  52. }
  53. FD[j]= X1[p];
  54. }
  55. // 释放内存
  56. delete W;
  57. delete X1;
  58. delete X2;
  59. }
  60. voidMyProcess::IFFT(complex<double>* FD, complex<double>* TD,int r)
  61. {
  62. // 循环变量
  63. int i;
  64. complex<double>*X;
  65. // 计算付立叶变换点数
  66. LONG N =1<<r;
  67. // 分配运算所需存储器
  68. X =new complex<double>[N];
  69. // 将频域点写入X
  70. memcpy(X, FD,sizeof(complex<double>)* N);
  71. // 求共轭
  72. for(i =0; i < N; i++)
  73. {
  74. X[i]= complex<double>(X[i].real(),-X[i].imag());
  75. }
  76. // 调用快速付立叶变换
  77. FFT(X, TD, r);
  78. // 求时域点的共轭
  79. for(i =0; i < N; i++)
  80. {
  81. TD[i]= complex<double>(TD[i].real()/ N,-TD[i].imag()/ N);
  82. }
  83. // 释放内存
  84. delete X;
  85. }
  86. BOOL MyProcess::Fourier(std::complex<double>* TD, LONG width, LONG height, std::complex<double>* FD)
  87. {
  88. // 循环变量
  89. LONG i;
  90. LONG j;
  91. LONG k;
  92. // 进行付立叶变换的宽度和高度(2的整数次方)
  93. LONG w =1;
  94. LONG h =1;
  95. int wp =0;
  96. int hp =0;
  97. // 计算进行付立叶变换的宽度和高度(2的整数次方)
  98. while(w < width/3)
  99. {
  100. w *=2;
  101. wp++;
  102. }
  103. while(h < height)
  104. {
  105. h *=2;
  106. hp++;
  107. }
  108. // 分配内存
  109. complex<double>*TempT,*TempF;
  110. TempT=new complex<double>[h];
  111. TempF=new complex<double>[h];
  112. // 对y方向进行快速付立叶变换
  113. for(i =0; i < w *3; i++)
  114. {
  115. // 抽取数据
  116. for(j =0; j < h; j++)
  117. TempT[j]= TD[j * w *3+ i];
  118. // 一维快速傅立叶变换
  119. FFT(TempT,TempF, hp);
  120. // 保存变换结果
  121. for(j =0; j < h; j++)
  122. TD[j * w *3+ i]=TempF[j];
  123. }
  124. // 释放内存
  125. deleteTempT;
  126. deleteTempF;
  127. // 分配内存
  128. TempT=new complex<double>[w];
  129. TempF=new complex<double>[w];
  130. // 对x方向进行快速付立叶变换
  131. for(i =0; i < h; i++)
  132. {
  133. for(k =0; k <3; k++)
  134. {
  135. // 抽取数据
  136. for(j =0; j < w; j++)
  137. TempT[j]= TD[i * w *3+ j *3+ k];
  138. // 一维快速傅立叶变换
  139. FFT(TempT,TempF, wp);
  140. // 保存变换结果
  141. for(j =0; j < w; j++)
  142. FD[i * w *3+ j *3+ k]=TempF[j];
  143. }
  144. }
  145. // 释放内存
  146. deleteTempT;
  147. deleteTempF;
  148. return TRUE;
  149. }
  150. BOOL MyProcess::IFourier(BYTE *TD, LONG width, LONG height, std::complex<double>* FD)
  151. {
  152. // 循环变量
  153. LONG i;
  154. LONG j;
  155. LONG k;
  156. // 进行付立叶变换的宽度和高度(2的整数次方)
  157. LONG w =1;
  158. LONG h =1;
  159. int wp =0;
  160. int hp =0;
  161. // 计算进行付立叶变换的宽度和高度(2的整数次方)
  162. while(w < width/3)
  163. {
  164. w *=2;
  165. wp++;
  166. }
  167. while(h < height)
  168. {
  169. h *=2;
  170. hp++;
  171. }
  172. // 计算图像每行的字节数
  173. // 分配内存
  174. complex<double>*TempT,*TempF;
  175. TempT=new complex<double>[w];
  176. TempF=new complex<double>[w];
  177. // 对x方向进行快速付立叶变换
  178. for(i =0; i < h; i++)
  179. {
  180. for(k =0; k <3; k++)
  181. {
  182. // 抽取数据
  183. for(j =0; j < w; j++)
  184. TempF[j]= FD[i * w *3+ j *3+ k];
  185. // 一维快速傅立叶变换
  186. IFFT(TempF,TempT, wp);
  187. // 保存变换结果
  188. for(j =0; j < w; j++)
  189. FD[i * w *3+ j *3+ k]=TempT[j];
  190. }
  191. }
  192. // 释放内存
  193. deleteTempT;
  194. deleteTempF;
  195. TempT=new complex<double>[h];
  196. TempF=new complex<double>[h];
  197. // 对y方向进行快速付立叶变换
  198. for(i =0; i < w *3; i++)
  199. {
  200. // 抽取数据
  201. for(j =0; j < h; j++)
  202. TempF[j]= FD[j * w *3+ i];
  203. // 一维快速傅立叶变换
  204. IFFT(TempF,TempT, hp);
  205. // 保存变换结果
  206. for(j =0; j < h; j++)
  207. FD[j * w *3+ i]=TempT[j];
  208. }
  209. // 释放内存
  210. deleteTempT;
  211. deleteTempF;
  212. for(i =0; i < h; i++)
  213. {
  214. for(j =0; j < w *3; j++)
  215. {
  216. if(i < height && j < width)
  217. *(TD + i * width + j)= FD[i * w *3+ j].real();
  218. }
  219. }
  220. return TRUE;
  221. }
  222. BOOL MyProcess::BmpFourier(BYTE* bmp,LONG width,LONG height)
  223. {
  224. LONG i,j;//循环变量
  225. // 中间变量
  226. double dTemp;
  227. LONG TI,TJ;
  228. // 进行付立叶变换的宽度和高度(2的整数次方)
  229. LONG w =1;
  230. LONG h =1;
  231. int wp =0;
  232. int hp =0;
  233. // 计算进行付立叶变换的宽度和高度(2的整数次方)
  234. while(w < width/3)
  235. {
  236. w *=2;
  237. wp++;
  238. }
  239. while(h < height)
  240. {
  241. h *=2;
  242. hp++;
  243. }// 分配内存
  244. complex<double>*FD,*TD,*TempD;
  245. FD =new complex<double>[w * h *3];
  246. TD =new complex<double>[w * h *3];
  247. TempD=new complex<double>[w * h *3];
  248. // 行
  249. for(i =0; i < h; i++)
  250. {
  251. // 列
  252. for(j =0; j <3* w; j++)
  253. {
  254. if(i < height && j < width)
  255. {
  256. // 获取时域数值
  257. unsignedcharValue= bmp[i*width+j];
  258. // 时域赋值
  259. TD[w * i *3+ j]= complex<double>(Value,0.0f);
  260. }
  261. else
  262. {
  263. // 否则补零
  264. TD[w * i *3+ j]= complex<double>(0.0f,0.0f);
  265. }
  266. }
  267. }
  268. // 进行频谱分析
  269. if(Fourier(TD, width, height, FD)== FALSE)
  270. return FALSE;
  271. // 释放内存
  272. delete[]TD;
  273. // 将原点放置于图像中心位置
  274. for(i =0; i < h; i++)
  275. {
  276. for(j =0; j <3* w; j++)
  277. {
  278. if(i < h /2)
  279. TI = i + h /2;
  280. else
  281. TI = i - h /2;
  282. if(j < w *3/2)
  283. TJ = j +3* w /2;
  284. else
  285. TJ = j -3* w /2;
  286. // 保存转换后的频谱图像
  287. TempD[i * w *3+ j]= FD[TI * w *3+ TJ];
  288. }
  289. }
  290. // 行
  291. for(i =(int)(h - height)/2; i <(int)(h + height)/2; i++)
  292. {
  293. // 列
  294. for(j =(int)(w *3- width)/2; j <(int)(w *3+ width)/2; j +=3)
  295. {
  296. // 计算频谱
  297. dTemp = sqrt(TempD[w *3* i + j].real()*TempD[w *3* i + j].real()+
  298. TempD[w *3* i + j].imag()*TempD[w *3* i + j].imag())/100;
  299. // 判断是否超过255
  300. if(dTemp >255)
  301. {
  302. // 对于超过的,直接设置为255
  303. dTemp =255;
  304. }
  305. // 限制为原图大小范围
  306. TI = i -(h - height)/2;
  307. TJ = j /3-(w - width/3)/2;
  308. // 对应象素指针
  309. LONG p = width * TI + TJ *3;
  310. // 更新源图像
  311. bmp[p]=(BYTE)(dTemp);
  312. bmp[p+1]=(BYTE)(dTemp);
  313. bmp[p+2]=(BYTE)(dTemp);
  314. }
  315. }
  316. // 删除临时变量
  317. delete[]FD;
  318. delete[]TempD;
  319. return TRUE;
  320. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值