简体   繁体   中英

Gabor Image Processing in Java without MathLab

I'm looking for some help in applying 2D Gabor Wavelets Formula to an image in java. This is the formula that I'm using. Gabor Formula

I need my output to look like this I've read the image in and its currently stored in a 2D array. My code is as follows:` public void RunGabor() throws IOException

{
    double[][]pixels=getImage();
    int H= pixels.length;
    int W =pixels[0].length;

    size=H*W;
    gaussian=size/2;
    System.out.println(gaussian);
    GaborGrid = new int[H][W];
    GaborNorm = new int[H][W];


    double X=0,Y=0, gx=-gaussian,gy=-gaussian, count=0, total=0;
    int ax=0, dy=0;
    for(int x=0; x<pixels.length; x++)
    {
        for(int k=0;k< pixels[0].length; k++)
        {   
            X=gx*Math.cos(theta)+gy*Math.sin(theta);
            Y=-gx*Math.sin(theta)+gy*Math.cos(theta);

            pixels[dy][ax]=((Math.exp(-(Math.pow(X, 2)+(Math.pow(Y, 2)*
                    Math.pow(upsi,2)))/(2*Math.pow(sigma, 2))))*
                    (Math.cos((kappa*X+varphi))));
            System.out.println("Pixels" +pixels[dy][ax]);
            total+=pixels[dy][ax];
            count++;
            System.out.println("Count" +count);
            gx+=1;
           ax++;

        }

    System.out.println("second loop");
        ax=0;
        dy++;
        gy+=1;
        gx=-gaussian;
    }
    mean=total/count;
    System.out.println("Mean" +mean);
    NormaliseImage(pixels);

}`

From there it calls a method normaliseImage

public void NormaliseImage(double[][] pixels)
{
     double minII = pixels[0][0];
     double maxII = pixels[0][0];
        for(int y=0; y<pixels.length; y++){
            for(int x= 0; x<pixels[0].length; x++){
                if(pixels[y][x] <= minII){
                    minII =pixels[y][x];
                }
                if(pixels[y][x]>= maxII){
                    maxII=pixels[y][x];
                }

      }

My create image class looks like this

  public CreateImage(int[][] data, String IMGname)
{
    name = IMGname;
    width =  data[0].length;
    height = data.length;
    System.out.println("NEW IMAGE 1");
    pixels = new int[height*width];
    int count=0;
    for(int i=0; i<data.length; i++)
    {
        for(int j=0; j<data[0].length; j++)
        {
            pixels[count] = (int)Math.abs(data[i][j]);
            pixels[count] = convert2pixel(pixels[count]);
            count++;
        }
    }
    Create(width, height, pixels, name);
}
public int convert2pixel(int pixel)
{
    return ((0xff<<24)|(pixel<<16)|(pixel<<8)|pixel);
}
public int convert2grey(double pixel)
{
    int red=((int)pixel>>16) & 0xff;
    int green = ((int)pixel>>8) & 0xff;
    int blue = (int)pixel & 0xff;
    return (int)(0.3*red+0.6*green+0.1*blue);
}
public void Create(int Width, int Height, int pixels[], String n)//throws Exception
{
    //System.out.println("Inside Create Image");
    MemoryImageSource MemImg = new MemoryImageSource(Width,Height,pixels,0,Width);
    Image img2= Toolkit.getDefaultToolkit().createImage(MemImg);

    BufferedImage bfi = new BufferedImage(Height,Width, BufferedImage.TYPE_INT_BGR);
    Graphics2D g2D = bfi.createGraphics();

    g2D.drawImage(img2, 0, 0, Width, Height, null);
    try
    {
        ImageIO.write(bfi, "png", new File(n+".png"));
    }
    catch(Exception e){}
}

}

My output is just a grey screen, any help would be appreciated.

Update: Gabor Driver Class `

public class Gabor_Driver{




public static void main(String[]args)throws IOException
{


      double lamda=75;
      double theta=45;
      double varphi=90;
      double upsi=10;
      double bandW=10;
      //int size=500;
    Gabor gabor = new Gabor(lamda, theta, varphi, upsi, bandW );
}
    }

` Gabor class :

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;



public class Gabor
{
CreateImage ci;
private double lamda=0;
private double theta=0;
private double varphi=0;
private double upsi=0;
private double bandW=0;
private double B=0;
private double sigma=0;
private double kappa=0;
private int[][] GaborGrid;
private int[][] GaborNorm;

int size=0;
double toRadians=180/Math.PI, min=500, max=-500, mean=0;;
int gaussian=0;
double rotation;
double GLFmean=0;
//Standard Gabor no quantization
public Gabor(double l, double t, double v, double u, double b) throws IOException
{

    lamda=l;
    theta=t/toRadians;
    varphi=v/toRadians;
    upsi=u;
    bandW=b;
    kappa=(2*Math.PI)/lamda;
    Calculate_Sigma();

    RunGabor();

}
public void RunGabor() throws IOException

{
    double[][]pixels=getImage();
    int H= pixels.length;
    int W =pixels[0].length;

    size=H*W;
    gaussian=size/2;
    System.out.println(gaussian);
    GaborGrid = new int[H][W];
    GaborNorm = new int[H][W];


    double X=0,Y=0, gx=-gaussian,gy=-gaussian, count=0, total=0;
    int ax=0, dy=0;
    for(int x=0; x<pixels.length; x++)
    {
        for(int k=0;k< pixels[0].length; k++)
        {   
            X=gx*Math.cos(theta)+gy*Math.sin(theta);
            Y=-gx*Math.sin(theta)+gy*Math.cos(theta);

            pixels[dy][ax]=((Math.exp(-(Math.pow(X, 2)+(Math.pow(Y, 2)*
                    Math.pow(upsi,2)))/(2*Math.pow(sigma, 2))))*
                    (Math.cos((kappa*X+varphi))));
            System.out.println("Pixels" +pixels[dy][ax]);
            total+=pixels[dy][ax];
            count++;
            System.out.println("Count" +count);
            gx+=1;
           ax++;

        }
        System.out.println("second loop");
        ax=0;
        dy++;
        gy+=1;
        gx=-gaussian;
    }
    mean=total/count;
    System.out.println("Mean" +mean);
    NormaliseImage(pixels);

}

public double[][] getImage() throws IOException{
    int[][]pixels =null;
    double[][] doubles = null;
    JFileChooser fc = new JFileChooser();
    int returnValue = fc.showOpenDialog(null);
    if (returnValue == JFileChooser.APPROVE_OPTION) {
      File selectedFile = fc.getSelectedFile();





        BufferedImage image = ImageIO.read(selectedFile);


          System.out.println(selectedFile.getName());
          int W =image.getWidth();
          int H= image.getHeight();
          int width = image.getWidth();
          int height = image.getHeight();
          pixels = new int[height][width];
            for (int row = 0; row < height; row++) {
                 image.getRGB(0, row, width, 1, pixels[row], 0, width);
            }


             doubles = new double[pixels.length][pixels[0].length];
            for(int i=0; i<pixels.length; i++) {
                for(int j=0; j<pixels[0].length; j++)
                doubles[i][j] = pixels[+i][+j];
            }
    }



    return doubles;


}
public void NormaliseImage(double[][] pixels)
{
     double minII = pixels[0][0];
     double maxII = pixels[0][0];
        for(int y=0; y<pixels.length; y++){
            for(int x= 0; x<pixels[0].length; x++){
                if(pixels[y][x] <= minII){
                    minII =pixels[y][x];
                }
                if(pixels[y][x]>= maxII){
                    maxII=pixels[y][x];
                }

      }
  }



      int count=0;
      double total=0;

        for(int y=0; y<pixels.length; y++){
            for(int x= 0; x<pixels[0].length; x++){
                total += pixels[y][x];
                count++;
            }
        }
        double average =(double)total/count;

        for(int y=0; y<pixels.length; y++){
            for(int x= 0; x<pixels[0].length; x++){
                double normalise= ((((pixels[y][x]-min))/((max-min)))*255);
                if(normalise<=average){
                    normalise =0;
                }
                GaborNorm[y][x] = (int) normalise;
                }
            }


    ci = new CreateImage(GaborNorm, "Gabor");
}


private void Calculate_Sigma()
{
    B=(1/Math.PI)*(0.588705011)*((Math.pow(2, bandW)+1)/(Math.pow(2, bandW)-1));
    sigma=B*lamda;
}

}

Create image class:

import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;

public class CreateImage
{
int[] pixels;
int width=0, height=0;
String  name;

public CreateImage(int[][] data, String IMGname)
{
    name = IMGname;
    width =  data[0].length;
    height = data.length;
    System.out.println("NEW IMAGE 1");
    pixels = new int[height*width];
    int count=0;
    for(int i=0; i<data.length; i++)
    {
        for(int j=0; j<data[0].length; j++)
        {
            pixels[count] = (int)Math.abs(data[i][j]);
            pixels[count] = convert2pixel(pixels[count]);
            count++;
        }
    }
    Create(width, height, pixels, name);
}
public int convert2pixel(int pixel)
{
    return ((0xff<<24)|(pixel<<16)|(pixel<<8)|pixel);
}
public int convert2grey(double pixel)
{
    int red=((int)pixel>>16) & 0xff;
    int green = ((int)pixel>>8) & 0xff;
    int blue = (int)pixel & 0xff;
    return (int)(0.3*red+0.6*green+0.1*blue);
}
public void Create(int Width, int Height, int pixels[], String n)//throws Exception
{
    //System.out.println("Inside Create Image");
    MemoryImageSource MemImg = new MemoryImageSource(Width,Height,pixels,0,Width);
    Image img2= Toolkit.getDefaultToolkit().createImage(MemImg);

    BufferedImage bfi = new BufferedImage(Height,Width, BufferedImage.TYPE_INT_BGR);
    Graphics2D g2D = bfi.createGraphics();

    g2D.drawImage(img2, 0, 0, Width, Height, null);
    try
    {
        ImageIO.write(bfi, "png", new File(n+".png"));
    }
    catch(Exception e){}
}

}

Your calculations are mostly correct. You are calculating the function itself in RunGabor - I think gx, gy should be replaced with x, k. This

 for(int x=0; x<pixels.length; x++)
{
    for(int k=0;k< pixels[0].length; k++)
    {   
        X=gx*Math.cos(theta)+gy*Math.sin(theta);
        Y=-gx*Math.sin(theta)+gy*Math.cos(theta);

        pixels[dy][ax]=((Math.exp(-(Math.pow(X, 2)+(Math.pow(Y, 2)*
                Math.pow(upsi,2)))/(2*Math.pow(sigma, 2))))*
                (Math.cos((kappa*X+varphi))));

should be replaced with

 public Kernel getKernel() {
  double sigma = calculateSigma(waveLength, bandwidth);
  float[] data = new float[width*height];
  for(int k = 0, x = -width/2; x <= width/2; x++) {
     for(int y = -height/2; y <= height/2; y++) {
        for(double orientation : orientations) {
           double x1 = x*Math.cos(orientation) + y*Math.sin(orientation);
           double y1 = -x*Math.sin(orientation) + y*Math.cos(orientation);
           data[k] += (float)(gaborFunction(x1, y1, sigma, aspectRatio, waveLength, phaseOffset));
        }
        k++;
     }
  }

But you have to apply the function on the pixels that you are reading, the image. If you look at this other implementation https://github.com/clumsy/gabor-filter/blob/master/src/main/java/GaborFilter.java

you will find many parallels. See if you can fix it.

At least as a first step you should try to print the values of the gabor function either 3x3 or 5x5. If they look reasonable you can go ahead to apply it to the image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM