1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| public static void main(String[] args) {
// load image from disk
BufferedImage input;
try {
input = ImageIO.read( new File("tiger.jpg") );
} catch (Exception e) {
throw new RuntimeException("Error loading Image file : "+e.getMessage());
}
int W=input.getWidth();
int H=input.getHeight();
// image data (in complex plane)
double[][] doubleimage = new double[H][2*W];
for(int y=0;y<H;y++) {
for(int x=0;x<W;x++) {
doubleimage[y][2*x] = input.getRaster().getSample(x, y, 1); // green channel
doubleimage[y][2*x+1] = 0;
}
}
// mask data (in complex plane)
double[][] doublemask = new double[H][2*W];
double Sigma2=15; int R = (int)(1+3*Math.sqrt(Sigma2));
for(int dy=-R;dy<=R;dy++) {
for(int dx=-R;dx<=R;dx++) {
int x=(dx+W)%W, y=(dy+H)%H; // centered at (0,0)
doublemask[y][2*x] = Math.exp(-(dx*dx+dy*dy)/(2*Sigma2))/(2*Math.PI*Sigma2); // gaussian
doublemask[y][2*x+1] = 0;
}
}
// FFT
DoubleFFT_2D fft = new DoubleFFT_2D(H, W);
fft.complexForward(doubleimage);
fft.complexForward(doublemask);
// complex product : image * mask
double[][] result = new double[H][2*W];
for(int y=0;y<H;y++) {
for(int x=0;x<W;x++) {
double img_r=doubleimage[y][2*x];
double img_i=doubleimage[y][2*x+1];
double mask_r=doublemask[y][2*x];
double mask_i=doublemask[y][2*x+1];
result[y][2*x] = img_r*mask_r - img_i*mask_i;
result[y][2*x+1] = img_r*mask_i + img_i*mask_r;
}
}
// inverse FFT
fft.complexInverse(result, true);
// display
BufferedImage output = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);
for(int y=0;y<H;y++) {
for(int x=0;x<W;x++) {
double pixel_r = result[y][2*x];
double pixel_i = result[y][2*x+1]; // should be 0
int v = (int)pixel_r;
if (v<0) v=0; else if (v>255) v=255;
output.getRaster().setSample(x, y, 0, v);
output.getRaster().setSample(x, y, 1, v);
output.getRaster().setSample(x, y, 2, v);
}
}
Display.bufferedImage(output);
} |