package ip.gabor;
import math.Mat;
import ip.gui.ConvolutionUtils;
import java.awt.*;
import java.awt.image.MemoryImageSource;
class GaborCanvas extends FilterCanvas {
private Image image;
private int[] spatialGaborIntArray = null;
private int[] frequencyGaborIntArray = null;
private int lat = 64;
private int sz = lat;
public GaborCanvas() {
}
public float[] getKernelf() {
float k[] = new float[spatialGaborIntArray.length];
for (int i = 0; i < k.length; i++)
k[i] = spatialGaborIntArray[i] / 255.0f;
return k;
}
public float[][] getKernel() {
short s[][] = graphics.ImageUtils.getGreenFromImage(image, this);
float f[][] = Mat.normalize(s);
Mat.scale(f, 2.0);
return f;
}
public void drawImage(String string) {
if (string.equals("space"))
image = getImage(spatialGaborIntArray);
if (string.equals("fourier"))
image = getImage(frequencyGaborIntArray);
this.repaint();
}
public Image getImage() {
return image;
}
public void setImage(Image img) {
image = img;
}
public Image getImage(int ia[]) {
return this.createImage(new MemoryImageSource(sz, sz,
ia,
0, sz));
}
public void paint(Graphics graphics) {
if (image != null)
graphics.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
public void ComputeImageArrays
(int kernelSize, double lambda, double theta, double phi, double gamma, double sigma) {
theta = theta * Math.PI / 180.0;
spatialGaborIntArray = new int[kernelSize * kernelSize];
frequencyGaborIntArray = new int[kernelSize * kernelSize];
sz = kernelSize;
double sigmaSquared = sigma * sigma;
double sigmaSquaredOnSizeSquared = -19.739208802178716 * sigmaSquared /
(double) (kernelSize * kernelSize);
double sizeOnLambda = (double) kernelSize / lambda;
double sineTheta = Math.sin(theta);
double cosTheta = Math.cos(theta);
double twoPi = 2 * Math.PI;
double gammaSquared = gamma * gamma;
for (int xMinusU = -kernelSize / 2; xMinusU < kernelSize / 2; xMinusU++) {
for (int yMinusV = -kernelSize / 2; yMinusV < kernelSize / 2; yMinusV++) {
double U = (double) xMinusU * cosTheta - (double) yMinusV * sineTheta;
double V = (double) xMinusU * sineTheta + (double) yMinusV * cosTheta;
double vSquared = V * V;
double uSquared = U * U;
computeGabor(uSquared, gammaSquared, vSquared, sigmaSquared,
twoPi, U, lambda, phi,
yMinusV, kernelSize, xMinusU);
}
}
}
private void computeGabor(double uSquared,
double gammaSquared,
double vSquared,
double sigmaSquared,
double twoPi,
double U,
double lambda,
double phi,
int yMinusV,
int size,
int xMinusU) {
double g
= Math.exp(-(uSquared + gammaSquared * vSquared)
/ (2.0 * sigmaSquared)) *
Math.cos(twoPi * U / lambda + phi);
int gScaled = (int) Math.round((1.0 + g) / 2.0 * 255.0);
spatialGaborIntArray[getArrayIndex(yMinusV, size, xMinusU)]
= packPixel(gScaled);
}
private void computeFourier(double sigmaSquaredOnSizeSquared,
double U, double sizeOnLambda,
double Vsquared, double gammaSquared,
int yMinusV, int size, int xMinusU) {
double g;
int gScaled;
g = (Math.exp(sigmaSquaredOnSizeSquared * ((U - sizeOnLambda)
* (U - sizeOnLambda)
+ Vsquared / gammaSquared))
+ Math.exp(sigmaSquaredOnSizeSquared * ((U + sizeOnLambda)
* (U + sizeOnLambda)
+ Vsquared / gammaSquared)));
gScaled = (int) Math.round(g * 255.0);
if (g > 1.0)
gScaled = 255;
frequencyGaborIntArray[getArrayIndex(yMinusV, size, xMinusU)]
= packPixel(gScaled);
}
private static int packPixel(int gScaled) {
return gScaled + (gScaled << 8) + (gScaled << 16) + -16777216;
}
private static int getArrayIndex(int yMinusEta, int size, int xMinusPsi) {
return (yMinusEta + size / 2) * size + xMinusPsi + size / 2;
}
}