我尝试使用以下代码实现FFT:Rosetta Code FFT
这是我得到的结果的屏幕截图: FFT gone wrong
这是我在代码上使用上述FFT的代码:
function fastFourier(img){
let height=img.rows;
let width=img.cols;
let tmp=createArray(height,width);
let temp=createArray(height,width);
let rows=createArray(height,width);
let prettypls=img.clone();
//new complex array
for(i=0;i<height;i++){
for(j=0;j<width;j++){
rows[i][j]=new Complex(0, 0);
}
}
//put pixel values in complex array
if(height%2==0&&width%2==0){
for ( y = 0; y < height; y++) {
for ( x = 0; x < width; x++) {
let pixel = img.ucharPtr(y,x);
rows[y][x].re=pixel[0];
}
}
//perform fft
for(y=0;y<height;y++){
tmp[y]=cfft(rows[y]);
}
//take the magnitudes
for(i=0;i<height;i++){
for(j=0;j<width;j++){
temp[i][j]=Math.round(tmp[i][j].re);
}
}
//do a log transform
temp=logTransform(temp,height,width);
//put the real values into Mat
for(i=0;i<height;i++){
for(j=0;j<width;j++){
let pixel = prettypls.ucharPtr(i,j);
pixel[0]=Math.round(temp[i][j]);
}
}
cv.imshow('fourierTransform', prettypls);
rows=[];temp=[];tmp=[];prettypls.delete();
}
else alert('Image size must be a power of 2.');
}
我根据this对FFT的描述进行了对数变换。这是我的日志转换代码:
function logTransform(img,h,w){
//https://homepages.inf.ed.ac.uk/rbf/HIPR2/pixlog.htm
let max=findMax2d(img,h,w);
let c=255/(Math.log(1+max));
for(i=0;i<h;i++){
for(j=0;j<w;j++){
img[i][j]=c*Math.log(1+Math.abs(img[i][j]));
}
}
return img;
}
我不知道我做错了什么。当它只是普通数组时,FFT结果很好,但是将其与图像一起使用可返回上述结果。
答案 0 :(得分:2)
您正在确切地获得所需的信息:对于图像中的每一行,分析该行中的强度频率 。您的代码将每一行视为一个单独的样本数组,并对其进行FFT。
您可能想要的是二维FFT,如此处所述:http://www.robots.ox.ac.uk/~az/lectures/ia/lect2.pdf
现在,您正在计算一系列的一维FFT,这是不一样的。
答案 1 :(得分:1)
Florian在他的回答中要说的是,您需要对所获得结果的列进行FFT计算。
2D DFT是可分离的。这意味着可以通过沿结果的每一行取一维DFT,然后再沿结果的每一列取一维DFT来进行计算。或等效地,首先沿列,然后沿行。