数字图像处理成长之路4: C语言与离散傅立叶变换(DFT)

来源:互联网 发布:淘宝客导购推广位 编辑:程序博客网 时间:2024/06/05 01:09

这几天一直学习傅立叶变换,看了很多国内外资料,网上讲原理的很多,到了程序实现这块大多是Matlab,opencv等,这些软件的api对于我们理解DFT在计算机中的实现并没有多大帮助。于是想用C/C++实现DFT,经过不断的阅读与编程实验,最终程序有了还算满意的结果。

“关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶变换的描述,但是大都是些故弄玄虚的文章,太过抽象,尽是一些让人看了就望而生畏的公式的罗列,让人很难能够从感性上得到理解”—dznlong

这是在网上看到的一句话,也是我一直以来的心声,要想弄明白一些事情,终究是要自己动手。

至于原理性的内容,网上太多,我这里不多说了,仅列几个连接供参考。
https://en.wikipedia.org/wiki/Fourier_series
http://www.cnblogs.com/v-July-v/archive/2011/02/20/1983676.html
http://www.dspguide.com/pdfbook.htm

 for (int u = 0; u < width; u ++)     for (int v =0; v < height; v ++){         for (int x = 0; x < width; x++){             for (int y = 0; y < height; y++){                real += srcMat.at<Vec3b>(y, x)[0] * cos(- ((double)2 * PI * u * x / width + (double)2 * PI * v * y / height )) * 1;                imaginary += srcMat.at<Vec3b>(y, x)[0] * sin(-((double)2 * PI * u * x / width + (double)2 * PI * v * y /height)) * 1;            }        }

u和v是变换后的变量,从程序可以看出,每一个F(u,v)的计算都需要遍历整副图像,确实是相当费时间,我只用了100 × 100 的图像,计算速度慢的惊人。

 real =  100 * real / (width * height); imaginary =100 *  imaginary / (width * height);

为什么要乘以100呢?因为此时的real和imaginary值很小,如果显示出来基本是黑色,所以为了显示清楚,我们随便乘以个值放大一下,这应该就是Opencv例子里说的归一化。

“`
tmpMat.at(u, v) = sqrt(real * real + imaginary * imaginary);

“`这里写图片描述
上面那个小方块窗口是原图像变换后的图像,用的是opencv的方法。
这里写图片描述
这个图是用C语言实现的DFT,为了看得清晰点,我把它放大了,相比与opencv的图这个没有做坐标的变换。

这个程序不是完美的,只是一种尝试,通过这个过程,对DFT有进一步了解,养成这种自己动手的习惯后,对学习其他的算法有一定帮助,接下来我该转移到其他问题学习,当知识丰富后还会在回过头来重新审视今天这些内容,并加以完善。

原创粉丝点击