我对图像处理很陌生,发现 FFT 卷积可以大大加快大内核大小的卷积。
我的问题是,如何在使用 KissFFT 时将内核应用于频率空间中的图像?
我已经做了以下事情:
//I have an image with RGB pixels and given width/height
const int dim[2] = {height, width}; // dimensions of fft
const int dimcount = 2; // number of dimensions. here 2
kiss_fftnd_cfg stf = kiss_fftnd_alloc(dim, dimcount, 0, 0, 0); // forward 2d
kiss_fftnd_cfg sti = kiss_fftnd_alloc(dim, dimcount, 1, 0, 0); // inverse 2d
kiss_fft_cpx *a = new kiss_fft_cpx[width * height];
kiss_fft_cpx *r = new kiss_fft_cpx[width * height];
kiss_fft_cpx *g = new kiss_fft_cpx[width * height];
kiss_fft_cpx *b = new kiss_fft_cpx[width * height];
kiss_fft_cpx *mask = new kiss_fft_cpx[width * height];
kiss_fft_cpx *outa = new kiss_fft_cpx[width * height];
kiss_fft_cpx *outr = new kiss_fft_cpx[width * height];
kiss_fft_cpx *outg = new kiss_fft_cpx[width * height];
kiss_fft_cpx *outb = new kiss_fft_cpx[width * height];
kiss_fft_cpx *outmask = new kiss_fft_cpx[width * height];
for(unsigned int i=0; i<height; i++) {
for(unsigned int l=0; l<width; l++) {
float red = intToFloat((int)Input(i,l)->Red);
float green = intToFloat((int)Input(i,l)->Green);
float blue = intToFloat((int)Input(i,l)->Blue);
int index = i * height + l;
a[index].r = 1.0;
r[index].r = red;
g[index].r = green;
b[index].r = blue;
}
}
kiss_fftnd(stf, a, outa);
kiss_fftnd(stf, r, outr);
kiss_fftnd(stf, g, outg);
kiss_fftnd(stf, b, outb);
kiss_fftnd(stf, mask, outmask);
kiss_fftnd(sti, outa, a);
kiss_fftnd(sti, outr, r);
kiss_fftnd(sti, outg, g);
当我在图像上再次设置 rgb 值时,我确实得到了原始图像。所以转换工作。如果我想应用内核,例如 9x9 框模糊(1/9、1/9、... 1/9),我现在应该怎么做。
我已经阅读了一些关于快速卷积的内容,但它们都是不同的,具体取决于 FFT 的实现。在应用过滤器之前,是否有一种“列表”我必须关心的事情?
我认为的方式:
图像大小必须是 2 的幂;我必须创建一个与图像大小相同的内核。将 9 个中间值设置为 1/9,其余设置为 0,然后将此内核转换为频域,将源图像与它相乘,然后将源图像转换回来。但这并没有真正起作用:DD