我试图在图像上实现二维傅立叶变换。我有它所以我的DFT和反DFT工作在图像上。但是当我应用滤波器时,通过乘以复数,并反过来得到图像噪声。
这是我的2D DFT
public void dft(double[][] inreal, double[][] inimag) {
int n = inreal.length;
double[][] tempreal = new double[n][n];
double[][] tempimag = new double[n][n];
realArray = new double[n][n];
imagArray = new double[n][n];
for(int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
double sumreal = 0;
double sumimag = 0;
for (int t = 0; t < n; t++) {
double angle = 2 * Math.PI * t * col / n;
sumreal += inreal[row][t] * Math.cos(angle) + inimag[row][t] * Math.sin(angle);
sumimag += -inreal[row][t] * Math.sin(angle) + inimag[row][t] * Math.cos(angle);
}
//System.out.println("r" + row + " " + "c" + col + " " + sumreal + " " + sumimag);
tempreal[row][col] = sumreal;
tempimag[row][col] = sumimag;
}
}
//now do it over the columns
for (int col = 0; col < n; col++) {
for (int row = 0; row < n; row++) { // For each output element
double sumreal = 0;
double sumimag = 0;
for (int t = 0; t < n; t++) { // For each input element
double angle = 2 * Math.PI * t * row / n;
sumreal += tempreal[t][col] * Math.cos(angle) + tempimag[t][col] * Math.sin(angle);
sumimag += -tempreal[t][col] * Math.sin(angle) + tempimag[t][col] * Math.cos(angle);
}
realArray[row][col] = sumreal;
imagArray[row][col] = sumimag;
//System.out.println(realArray[row][col] + " " + imagArray[row][col] + "i");
}
}
}
这是我的逆DFT
public void inverseDFT(double[][] inRealArray, double[][] inImagArray) {
int n = realArray.length;
outRealArray = new double[n][n];
outImagArray = new double[n][n];
outputarray = new int[n][n];
double[][] tempreal = new double[n][n];
double[][] tempimag = new double[n][n];
for (int col = 0; col < n; col++) {
for (int row = 0; row < n; row++) { // For each output element
double sumreal = 0;
double sumimag = 0;
for (int t = 0; t < n; t++) { // For each input element
double angle = 2 * Math.PI * t * row / n;
sumreal += inRealArray[t][col] * Math.cos(angle) - inImagArray[t][col] * Math.sin(angle);
sumimag += inRealArray[t][col] * Math.sin(angle) + inImagArray[t][col] * Math.cos(angle);
}
//System.out.println("r" + row + " " + "c" + col + " " + sumreal + " " + sumimag);
tempreal[row][col] = sumreal;
tempimag[row][col] = sumimag;
}
}
//now do it over the columns
for(int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) { // For each output element
double sumreal = 0;
double sumimag = 0;
for (int t = 0; t < n; t++) { // For each input element
double angle = 2 * Math.PI * t * col / n;
sumreal += tempreal[row][t] * Math.cos(angle) - tempimag[row][t] * Math.sin(angle);
sumimag += tempreal[row][t] * Math.sin(angle) + tempimag[row][t] * Math.cos(angle);
}
outRealArray[row][col] = sumreal / (n * n);
outImagArray[row][col] = sumimag / (n * n);
outputarray[row][col] = (int)Math.abs(outRealArray[row][col]);
//System.out.println(outRealArray[row][col] + " " + outImagArray[row][col] + "i");
}
}
}
图像通过并返回相同。 我将图像移动到中心并获得光谱图像以测试它是否有效。
这是复数的大小并转移到中心
低通滤波器
过滤器通过DFT。
这是我的代码乘以两者。
public void applyLowPassFilter(String filename, double[][] realArray, double[][] imagArray) throws IOException {
ReadPGMFile readPGM = new ReadPGMFile(filename);
double[][] filterArrayR = readPGM.loadArray();
double[][] filterArrayI = new double[filterArrayR.length][filterArrayR.length];
FourierTransform ft = new FourierTransform();
ft.dft(filterArrayR, filterArrayI);
filterReal = ft.getRealArray();
filterImag = ft.getImagArray();
int n = realArray.length;
resultRealArray = new double[n][n];
resultImagArray = new double[n][n];
for(int i = 0; i < n; i++){
int colValue = 0;
int rowValue = 0;
for(int j = 0; j < n; j++) {
if(j < n / 2 ){
colValue = (n / 2) - j;
} else {
colValue = (n - 1) - (j - ((n - 1) / 2));
}
if (i < n / 2) {
rowValue = (n / 2) - i;
} else {
rowValue = (n - 1) - (i - ((n - 1) / 2));
}
resultRealArray[i][j] = realArray[rowValue][colValue] * filterReal[i][j] - imagArray[rowValue][colValue] * filterImag[i][j];
resultImagArray[i][j] = realArray[rowValue][colValue] * filterImag[i][j] + imagArray[rowValue][colValue] * filterReal[i][j];
}
}
}
这是我得到的结果。对不起,很长的帖子。如果有人有任何见解我会很感激他们。几个星期以来,我一直在努力解决这个问题。
答案 0 :(得分:1)
以下是我用来测试它的代码:
int[] pix=bim.getRGB(0, 0, wc, hc, null, 0, wc);
double[][] ri=new double[hc][hc], ii=new double[hc][hc], ro=new double[hc][hc], io=new double[hc][hc];
for(i=0; i<hc; i++)
for(j=0; j<hc; j++) {
int rr=(pix[i+j*wc]&0x00ff0000)>>16, rg=(pix[i+j*wc]&0x0000ff00)>>8, rb=pix[i+j*wc]&0x000000ff;
ri[i][j]=0.2126*rr+0.7152*rg+0.0722*rb;
}
double[][] ff=new double[hc][hc];
ff[hc/2][hc/2]=ff[hc/2][hc/2+1]=ff[hc/2][hc/2-1]=ff[hc/2+1][hc/2]=ff[hc/2-1][hc/2]=1;
// ff[hc/2][hc/2]=ff[hc/2][hc/2+1]=ff[hc/2][hc/2-1]=ff[hc/2+1][hc/2]=ff[hc/2-1][hc/2]=ff[hc/2-1][hc/2-1]=ff[hc/2-1][hc/2+1]=ff[hc/2+1][hc/2-1]=ff[hc/2+1][hc/2+1]=0.125;
filterDFT(ff, ri, ro, io);
int[] pix2=new int[hc*hc];
for(i=0; i<hc; i++)
for(j=0; j<hc; j++) pix2[i+j*hc]=0xff000000|(int)Math.abs(ro[i][j]);
BufferedImage b2=new BufferedImage(hc, hc, BufferedImage.TYPE_INT_RGB);
b2.setRGB(0, 0, hc, hc, pix2, 0, hc);
现在b2是你的形象;它显示得很好 - 你必须重新调整象限。
因此,我建议您再次查看过滤器阅读的下载内容。