Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用java实现傅里叶变换求幅值_Java_Image_Image Processing_Fft - Fatal编程技术网

用java实现傅里叶变换求幅值

用java实现傅里叶变换求幅值,java,image,image-processing,fft,Java,Image,Image Processing,Fft,我有下面的代码,使用简单的傅里叶变换算法,但它不能像它应该的那样工作 public int ft(int x, int y, int br, int a, int height, int width, int[][] pixelTemp, double c){ int r; int g; int b; double avg; double newCitra = 0; int temp; for (int i=0; i<hei

我有下面的代码,使用简单的傅里叶变换算法,但它不能像它应该的那样工作

public int ft(int x, int y, int br, int a, int height, int width, int[][] pixelTemp, double c){
    int r;
    int g;
    int b;
    double avg;     
    double newCitra = 0;
    int temp;
    for (int i=0; i<height; i++){
        for (int j=0; j<width; j++){
            temp = pixelTemp[i][j];
            r = (temp>>16)&0xff;
            g = (temp>>8)&0xff;
            b = temp&0xff;
            avg = (r+g+b)/3;
            if (Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))>0){
                if(-2*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))>0){
                    newCitra = ((newCitra + (((double)avg/(double)(height*width)))*(sqrt(Math.pow((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))),2)+Math.pow((double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))),2)))));
                } else {
                    newCitra = ((newCitra + (((double)avg/(double)(height*width)))*(sqrt(Math.pow((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))),2)-Math.pow((double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))),2)))));
                }                    
            } else {
                if(-2*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))>0){
                    newCitra = (newCitra + ((double)avg/(double)(height*width))*((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))))+(double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))));
                } else {
                    newCitra = (newCitra + ((double)avg/(double)(height*width))*((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))))-(double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))));
                }
            }
            /*System.out.println(newCitra);*/
        }
    }
    newCitra = (int) (Math.log(1+newCitra)*c);
    int j = 30;
    int i = 10;
    /*System.out.println(Math.abs(sqrt(Math.pow((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))),2)-Math.pow((double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))),2))));*/
    int p = (255<<24) | ((int)newCitra<<16) | ((int)newCitra<<8) | (int)newCitra;

    return p;
}
公共整数英尺(整数x,整数y,整数br,整数a,整数高度,整数宽度,整数[][]像素温度,双c){ INTR; int g; int b; 双平均值; 双纽西特拉=0; 内部温度; 对于(int i=0;i16)&0xff; g=(温度>>8)&0xff; b=温度&0xff; 平均值=(r+g+b)/3; 如果(数学正弦(数学托拉半径(360*((双)(i*x)/(双)高)+(双)(j*y)/(双)宽)))>0{ 如果(-2*((双倍)(i*x)/(双倍)高度)+((双倍)(j*y)/(双倍)宽度))>0){ newCitra=((newCitra+((double)avg/(double)(height*width)))*(sqrt(Math.pow)((Math.cos)(Math.toRadians(360*((double)(i*x)/(double)height)+(double)(j*y)/(double)width()())),2)+Math.pow((double)Math.sin; }否则{ newCitra=((newCitra+((double)avg/(double)(height*width)))*(sqrt(Math.pow)((Math.cos)(Math.toRadians(360*((double)(i*x)/(double)height)+(double)(j*y)/(double)width()())),2)-Math.pow((double)Math.sin; } }否则{ 如果(-2*((双倍)(i*x)/(双倍)高度)+((双倍)(j*y)/(双倍)宽度))>0){ 纽西特拉=(纽西特拉+((双)平均/(双)(高度*宽度))*((数学)坐标系(数学托拉面(360*((双)(i*x)/(双)高度)+((双)(j*y)/(双)宽度()()(双)数学托拉面(360*((双)(i*x)/(双)高度)+(双)(双)(j*y)/(双)宽度()()()))))))); }否则{ 纽西特拉=(纽西特拉+(双)平均/(双)(高度*宽度))*((数学坐标系(数学托拉面)(360*((双)(i*x)/(双)高度)+(双)(j*y)/(双)宽度()()()(双)数学托拉面(360*((双)(i*x)/(双)高度)+(双)(双)(j*y)/(双)宽度()()())))))); } } /*System.out.println(newCitra)*/ } } newCitra=(int)(Math.log(1+newCitra)*c); int j=30; int i=10; /*System.out.println(Math.abs(sqrt(Math.pow)(Math.cos(Math.toRadians(360*)((double)(i*x)/(double)高度)+(double)(j*y)/(double)宽度(double))),2)Math.pow(double)Math.sin(Math.toRadians(360*)((double)(i*x)/(double)高度)+(double)(j*y)/(double)宽度)),2))*/
int p=(255显然您误解了公式。从另一个实现中,我已经

real +=  tempreal[row][t] * cos[col][t] - tempimag[row][t] * sin[col][t];
imag +=  tempreal[row][t] * sin [col][t] + tempimag[row][t] * cos[col][t];
一旦你有了实部和虚部,你就可以求平方根了

mag=Math.sqrt(real*real+imag*imag);
也在余弦/正弦中

cos[i][t]=Math.cos(2*Math.PI*t*i/n);
sin[i][t]=Math.sin(2*Math.PI*t*i/n);
我看到的不是正方形,而是双倍的

--

我已将您的功能更新如下:

a) 实部和虚部需要分别计算,没有复数计算 b) 一些重排

这似乎是可行的,如果你尝试在这里显示的图像对角线条纹,你会得到对角线上显示的页面

public double ft(int x, int y, int br, int a, int height, int width, int[][] pixelTemp, double c){
    int r;
    int g;
    int b;
    double avg;     
    double newCitrar = 0, newCitrai = 0;
    int temp;
    double f=(double)1/(double)(height*width);
    for (int i=0; i<width; i++){
        for (int j=0; j<height; j++){
            temp = pixelTemp[i][j];
//            r = (temp>>16)&0xff;
//            g = (temp>>8)&0xff;
//            b = temp&0xff;
            avg = temp; // (r+g+b)/3;
        newCitrar = newCitrar + avg*Math.cos(2*Math.PI*(((double)(i*x)/(double)width)+((double)(j*y)/(double)height)));
        newCitrai=newCitrai+avg*Math.sin(2*Math.PI*(((double)(i*x)/(double)width)+((double)(j*y)/(double)height)));
      }
    }
    newCitrar *=f;
    newCitrai *=f;
    double newCitra=Math.sqrt(newCitrar*newCitrar+newCitrai*newCitrai);
    return newCitra;
}
public double-ft(整数x,整数y,整数br,整数a,整数高度,整数宽度,整数[][]像素温度,双c){
INTR;
int g;
int b;
双平均值;
双新雪铁龙=0,新雪铁龙=0;
内部温度;
双f=(双)1/(双)(高*宽);
对于(int i=0;i16)&0xff;
//g=(温度>>8)&0xff;
//b=温度&0xff;
平均温度=温度;/(r+g+b)/3;
newCitrar=newCitrar+avg*Math.cos(2*Math.PI*((双倍)(i*x)/(双倍)宽度)+(双倍)(j*y)/(双倍)高度));
newCitrai=newCitrai+avg*Math.sin(2*Math.PI*((双倍)(i*x)/(双倍)宽度)+(双倍)(j*y)/(双倍)高度));
}
}
newCitrar*=f;
newCitrai*=f;
double newCitra=Math.sqrt(newCitrar*newCitrar+newCitrai*newCitrai);
返回纽西特拉;
}
在显示屏侧,我有以下内容:

  BufferedImage bim=null;
  try {
    bim=ImageIO.read(new File("str.gif"));
  }
  catch (Exception ex) { System.err.println("error"); }
  int wc=bim.getWidth(), hc=bim.getHeight();
  BufferedImage b2=new BufferedImage(wc, hc, BufferedImage.TYPE_INT_RGB);

  int[] pix=bim.getRGB(0, 0, wc, hc, null, 0, wc);
  int[][] pix2=new int[wc][hc];
  double ri;
  for(i=0; i<wc; 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=0.2126*rr+0.7152*rg+0.0722*rb;
    pix2[i][j]=(int)ri;
  }
  double max=0;
  for(i=0; i<wc; i++)
  for(j=0; j<hc; j++) {
  if(i%10==0 && j%10==0) System.out.println(i+" "+j);
    double ki=ft(i, j, 0, 0, hc, wc, pix2, 1);
    if(ki>max) max=ki;
    b2.setRGB(i, j, (int)ki);
  }
  saveImageIO(b2, (time/1000)+"f-1");

  double cc=255./Math.log(1+max);
  System.out.println(max+" "+cc);
  for(i=0; i<wc; i++)
  for(j=0; j<hc; j++) {
    b2.setRGB(i, j, (int) (Math.log(1+(b2.getRGB(i, j)&0x00ffffff))*cc));
  }   

  saveImageIO(b2, (time/1000)+"f-2");
buffereImage bim=null;
试一试{
bim=ImageIO.read(新文件(“str.gif”);
}
catch(异常ex){System.err.println(“error”);}
int wc=bim.getWidth(),hc=bim.getHeight();
BuffereImage b2=新的BuffereImage(wc、hc、BuffereImage.TYPE_INT_RGB);
int[]pix=bim.getRGB(0,0,wc,hc,null,0,wc);
int[][]pix2=新的int[wc][hc];
双ri;
对于(i=0;i16,rg=(pix[i+j*wc]&0x0000ff00)>>8,rb=pix[i+j*wc]&0x000000ff;
ri=0.2126*rr+0.7152*rg+0.0722*rb;
pix2[i][j]=(int)ri;
}
双最大值=0;

对于(i=0;我能指出
avg=(r+g+b)中的公式吗/3、 
avg
声明为
double
,但分配了
int
计算的结果,这将删除任何小数部分。以及??公式正确吗??你在说什么?3而不是3.3??你说的是假的!!@LewBloch@LewBloch你的评论是关于Asker自己的代码。你输入了这个吗错误的位置?@Lew Bloch我使用avg作为double,因为我想要一个更特殊的值,这样当我施法时结果会更准确,这样做是错误的吗?还是有更好的方法?@gpasch谢谢你的重覆,我真的很感激,我尝试在我的代码上实现你的代码,现在没有更多的NaN结果,但结果与wha不同我在另一个程序Gwyddion中检查了它,变量是什么?这里我把它作为x和y,代码是这样的:
sin=Math.sin(2*Math.PI*x*i/height);cos=Math.cos(2*Math.PI*y*j/width);