gpt4 book ai didi

java - 如何使用离散傅里叶变换在频域中的图像上实现低通滤波器?

转载 作者:行者123 更新时间:2023-12-01 10:00:10 25 4
gpt4 key购买 nike

我正在尝试在图像上实现二维傅里叶变换。我有了它,所以我的 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");
}
}

}

图像经过并返回相同。我将图像移动到中心并获取光谱图像来测试它是否有效。

enter image description here

This is the magnitude of the complex number and shifted to the center

这是复数的大小并移至中心

enter image description here

低通滤波器

enter image description here

过滤器通过 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];
}
}
}

enter image description here

这就是我得到的结果。抱歉发了这么长的帖子。如果有人有任何见解,我将不胜感激。我已经为此苦苦挣扎了几个星期。

最佳答案

这是我用来测试它的代码:

      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 就是你的图像;它显示得很好 - 你必须重新洗牌象限。

因此,我建议您再次查看您的过滤器读取的下载内容。

关于java - 如何使用离散傅里叶变换在频域中的图像上实现低通滤波器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36878830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com