我试图通过应用DFT(傅立叶)对图像进行模糊,计算幅度和相位部分,最后拍摄一个滤镜图像,它只是在黑色中间的白色模糊圆圈,具有相同的尺寸原始图片。
为此,在我从原始图像获得幅度图像之后,在幅度图像和滤波器图像之间进行乘法,“逐个位置”,因此我有一个新的幅度图像。
问题是,当我尝试用这个新的幅度(和旧阶段)反转DFT时,我得到了垃圾。如果我使用原始幅度进行IDFT,我会成功获得原始图像(镜像但是没问题)。
for(int i=0; i < ROWS; i++) {
for(int j=0; j < COLS; j++) {
magnitude->matriz[i][j] = (magnitude->matriz[i][j] * filter->matriz[i][j]);
}
}
也许还有一些额外的数学?或者必须首先操纵滤镜(圆圈)图像。我尝试将结果除以COLS或ROWS,结果是某种二值化图像,它与原始图像相似,但不是我想要的! (甚至没有关闭)。
感谢您的帮助。
如有必要,我可以发布更多代码或所有代码。
的 EDITED 的 添加了代码和示例图像。
//The Discrete Fourier Transform function
//It applies the transform in an array only (1D)
COMPLEX* DFT(COMPLEX* F, int N, bool inv) {
int u, x;
float cosarg = 0;
float sinarg = 0;
float W;
COMPLEX *ft;
COMPLEX tmp;
ft = (COMPLEX*) malloc(N*sizeof(COMPLEX));
for (u=0; u<N; u++) {
ft[u].r = 0;
ft[u].i = 0;
W = (u*2*PI)/N;
for (x=0; x<N; x++) {
tmp.r = cos(W*x);
if(inv==false) tmp.i = (-1.0)*sin(W*x);
else tmp.i= sin(W*x);
ft[u] = complex_plus(ft[u],(complex_times(F[x],tmp)));
}
if(inv==false)ft[u].r = ft[u].r/N;
if(inv==false)ft[u].i = ft[u].i/N;
}
return ft;
}
int main(){
//Declarations
BMP Original;
BMP Blur;
BMP Edge;
BMP Mag;
BMP High;
BMP Low;
BMP Filter;
BMP Magnitude;
Matriz* magnitude;
Matriz* phase;
MCOMPLEX* original;
MCOMPLEX* fourier;
MCOMPLEX* fourier_colunas;
COMPLEX* buffer;
COMPLEX* ftbuffer;
Matriz* blur;
Matriz* edge;
Matriz* filter;
int COLS;
int ROWS;
float max;
float scale_brightness;
//Original image
Original.openBmp(STRING);
Filter.openBmp(FILTER);
Blur.creatImg(Original.getIntWidth(), Original.getIntHeight(), 0, 0, 0);
Edge.creatImg(Original.getIntWidth(), Original.getIntHeight(), 0, 0, 0);
Magnitude.creatImg(Original.getIntWidth(), Original.getIntHeight(), 0, 0, 0);
//Convert open image to 2d array for manipulation
original = converteToMCOMPLEX(Original);
filter = converteToM(Filter);
//Based on original image dimensions
COLS= original->w;
ROWS= original->h;
//Dynamic allocations
buffer=(COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
ftbuffer=(COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
fourier_colunas = (MCOMPLEX*) malloc(sizeof(MCOMPLEX));
fourier_colunas->c= (COMPLEX**) malloc(COLS*sizeof(COMPLEX*));
fourier = (MCOMPLEX*) malloc(sizeof(MCOMPLEX));
fourier->c = (COMPLEX**) malloc(COLS*sizeof(COMPLEX*));
magnitude = (Matriz*) malloc(sizeof(Matriz));
magnitude->matriz = (float**) malloc(COLS*sizeof(float*));
phase = (Matriz*) malloc(sizeof(Matriz));
phase->matriz = (float**) malloc(COLS*sizeof(float*));
blur = (Matriz*) malloc(sizeof(Matriz));
blur->matriz = (float**) malloc(COLS*sizeof(float*));
for(int i=0; i<COLS; i++){
fourier_colunas->c[i] = (COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
fourier->c[i] = (COMPLEX*) malloc(ROWS*sizeof(COMPLEX));
magnitude->matriz[i] = (float*) malloc(ROWS*sizeof(float));
phase->matriz[i] = (float*) malloc(ROWS*sizeof(float));
blur->matriz[i] = (float*) malloc(ROWS*sizeof(float));
}
//1D-Transform column by column
for (int j=0; j<COLS; j++) {
//Copy a column from array original into the buffer vector/
for (int i=0; i<ROWS; i++) {
buffer[i].r = original->c[i][j].r;
buffer[i].i = original->c[i][j].r;
}
//Call DFT to apply 1D-transform in the column
ftbuffer = DFT(buffer,ROWS,false);
//Copy the result in an 2d array representing the complex fourier intermediary image
//calculated considering just the transform of the columns
for (int i=0; i<ROWS; i++) {
fourier_colunas->c[i][j].r = ftbuffer[i].r;
fourier_colunas->c[i][j].i = ftbuffer[i].i;
}
}
//Now 1-Transform row by row
for (int i=0; i<ROWS; i++) {
//Copy a row from array fourier_colunas (the intermediary result) into the buffer vector
for (int j=0; j<COLS; j++) {
buffer[j].r = fourier_colunas->c[i][j].r;
buffer[j].i = fourier_colunas->c[i][j].r;
}
//Call DFT to apply 1D-transform in the row
ftbuffer = DFT(buffer,COLS,false);
//Copy the result to the final fourier image 2D-transformed with two 1D-transforms
for (int j=0; j<COLS; j++) {
fourier->c[i][j].r = ftbuffer[j].r;
fourier->c[i][j].i = ftbuffer[j].i;
}
}
//This would serve the purpose to scale the magnitude image so it's better visible to human eye,
//not being used to not affect the final result (need pure magnitude image)
//max=0;
//
//for (int i=0; i<ROWS; i++) {
// for (int j=0; j<COLS; j++) {
// if (complex_mag(fourier->c[i][j]) > max) max = complex_mag(fourier->c[i][j]);
// }
//}
//scale_brightness = 255/(log(1 + max));
// for (int i=0; i < ROWS; i++) {
// for (int j=0; j < COLS; j++) {
// magnitude->matriz[i][j] = scale_brightness*(log(1 + complex_mag(fourier->c[i][j])));
// }
//}
//Calculates the magnitude 2d array/image from the fourier transform (real and imaginary components)
for (int i=0; i < ROWS; i++) {
for (int j=0; j < COLS; j++) {
magnitude->matriz[i][j] = complex_mag(fourier->c[i][j]);
}
}
//Calculates the phase 2d array/image from the fourier transform (real and imaginary components)
for (int i=0; i < ROWS; i++) {
for (int j=0; j < COLS; j++) {
phase->matriz[i][j] = complex_phase(fourier->c[i][j]);
}
}
//This filter should work.
for(int i=0; i < ROWS; i++) {
for(int j=0; j < COLS; j++) {
magnitude->matriz[i][j] = (magnitude->matriz[i][j] * filter->matriz[i][j]);
}
}
//With the new magnitude combine with the (unmodified) phase part
//to obtain a new fourier complex image to inverse transform
for(int i=0; i < ROWS; i++) {
for(int j=0; j < COLS; j++) {
fourier->c[i][j].r = complex_r(magnitude->matriz[i][j], phase->matriz[i][j]);
fourier->c[i][j].i = complex_i(magnitude->matriz[i][j], phase->matriz[i][j]);
}
}
//This code is the same fourier procedure as before, with the exception of the inv flag
//set to TRUE, so now the DFT function performs a inverse fourier transform in the complex image (2d fourier array)
//The result is IDFT(fourier)
for (int j=0; j<COLS; j++) {
for (int i=0; i<ROWS; i++) {
buffer[i].r = fourier->c[i][j].r;
buffer[i].i = fourier->c[i][j].i;
}
ftbuffer = DFT(buffer,ROWS,true);
for (int i=0; i<ROWS; i++) {
fourier_colunas->c[i][j].r = ftbuffer[i].r;
fourier_colunas->c[i][j].i = ftbuffer[i].i;
}
}
for (int i=0; i<ROWS; i++) {
for (int j=0; j<COLS; j++) {
buffer[j].r = fourier_colunas->c[i][j].r;
buffer[j].i = fourier_colunas->c[i][j].i;
}
ftbuffer = DFT(buffer,COLS,true);
//What remains is to the copy col by col in the final 2d array
//that will represent the new image. We just want the real part
for (int j=0; j<COLS; j++) {
blur->matriz[i][j] = ftbuffer[j].r;
// blur->c[i][j].i = ftbuffer[j].i;
}
}
//Procedures to convert the arrays to real images
//and save them
blur->h= Original.getIntHeight();
blur->w= Original.getIntWidth();
magnitude->h= Original.getIntHeight();
magnitude->w= Original.getIntWidth();
Magnitude = converteToBMP(magnitude, Magnitude);
Magnitude.saveBmp("c:\\f1\\magnitude.bmp");
Blur = converteToBMP(blur, Blur);
Blur.saveBmp("c:\\f1\\blur.bmp");
system("pause");
return 0;
}
图片
我没有足够的声誉来指导链接图片,因此我将发布未格式化的链接。
原始图片:http://imm.io/ZIUH
两个Cenarios
1 - 没有过滤器。只需应用傅立叶变换和逆傅里叶变换即可获得相同的图像。
//Fourier transformed and reversed: http://imm.io/ZIU8
//Resultant not modified magnitude image: http://imm.io/ZIVX
//Resultand log-scaled magnitude image: http://imm.io/ZIW5
2 - 通过将幅度图像与滤镜图像相乘来过滤原始图像
//Filter: http://imm.io/ZIVq
//Filter and Magnitude: http://imm.io/ZIVC
//Result (fourier reversed): http://imm.io/ZIV4