/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package com.bc.ceres.jai; import javax.media.jai.PlanarImage; import javax.media.jai.RenderedOp; import javax.media.jai.operator.DFTDescriptor; import javax.media.jai.operator.ExtremaDescriptor; import javax.media.jai.operator.FileLoadDescriptor; import javax.media.jai.operator.FormatDescriptor; import javax.media.jai.operator.IDFTDescriptor; import javax.media.jai.operator.MagnitudeDescriptor; import javax.media.jai.operator.PhaseDescriptor; import javax.media.jai.operator.RescaleDescriptor; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.RenderedImage; import static java.lang.Math.*; public class DFTTestMain { private static int location; public static void main(String[] args) { RenderedImage src; if (args.length == 0) { src = createTestImage(512, 512); } else { src = FileLoadDescriptor.create(args[0], null, false, null); } PlanarImage dft = DFTDescriptor.create(src, DFTDescriptor.SCALING_NONE, DFTDescriptor.REAL_TO_COMPLEX, null); PlanarImage idft = IDFTDescriptor.create(dft, DFTDescriptor.SCALING_DIMENSIONS, DFTDescriptor.COMPLEX_TO_REAL, null); RenderedOp dftMagnitude = MagnitudeDescriptor.create(dft, null); RenderedOp dftPhase = PhaseDescriptor.create(dft, null); showImage(src, "Source"); showImage(rescale(dftMagnitude, 0, 1000), "FFT Magnitude"); showImage(rescale(dftPhase, -3, 3), "FFT Phase"); showImage(rescale(idft, 0.0, 255.0), "Inverse FFT"); } public static RenderedOp rescale(RenderedImage idft) { double[][] extrema = (double[][]) ExtremaDescriptor.create(idft, null, 1, 1, true, 1000, null).getProperty("extrema"); double x1 = extrema[0][0]; double x2 = extrema[1][0]; System.out.println("extrema min = " + x1); System.out.println("extrema max = " + x2); return rescale(idft, x1, x2); } public static RenderedOp rescale(RenderedImage idft, double x1, double x2) { return FormatDescriptor.create(rescale(idft, x1, x2, 0.0, 255.0), DataBuffer.TYPE_BYTE, null); } public static RenderedOp rescale(RenderedImage src, double x1, double x2, double y1, double y2) { double a = (y2 - y1) / (x2 - x1); double b = y1 - a * x1; return RescaleDescriptor.create(FormatDescriptor.create(src, DataBuffer.TYPE_DOUBLE, null), new double[]{a}, new double[]{b}, null); } public static void showImage(RenderedImage image, String name) { int width = image.getWidth(); int height = image.getHeight(); int numBands = image.getSampleModel().getNumBands(); int dataType = image.getSampleModel().getDataType(); System.out.println("============= Image " + name); System.out.println("width = " + width); System.out.println("height = " + height); System.out.println("numBands = " + numBands); System.out.println("dataType = " + dataType); BufferedImage bufferedImage; if (image instanceof PlanarImage) { PlanarImage planarImage = (PlanarImage) image; long t0 = System.nanoTime(); bufferedImage = planarImage.getAsBufferedImage(); long t1 = System.nanoTime(); System.out.println("BufferedImage created in " + (t1-t0)/(1000.0*1000.0) + " ms"); } else if (image instanceof BufferedImage) { bufferedImage = (BufferedImage) image; } else { throw new IllegalArgumentException("image"); } JScrollPane scrollPane = new JScrollPane(new JLabel(new ImageIcon(bufferedImage))); scrollPane.setBorder(null); JFrame frame = new JFrame(name); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(scrollPane); frame.pack(); frame.setLocation(location += 24, location += 24); frame.setVisible(true); } public static BufferedImage createTestImage(int width, int height) { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); double r = 2 * PI; int n0 = 5; int n = 3; double fu = 1; double fv = 1; double s = 1.0 / n; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { double u = r * x / (width - 1.0); double v = r * y / (height - 1.0); double w = 0; for (int k = n0; k < n0 + n; k++) { w += 0.5*s * (sin(fu * k * u) + sin(fv * k * v)); } w = 0.5 * (1.0 + w); data[y * width + x] = (byte) floor(255.0 * w); } } return image; } }