Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

my fingerprint identification project , plz help

Thread view: 
santoshtwaghmode - 09 Apr 2007 19:47 GMT
hi sir,
i am santosh from india.i doing computer engineering.we completed ,
our final project in java. and our project name is automatic
fingerprint identification

system and this tottaly based on image processing concept. we done
this but our internal guide does  not accept this. and suggest some
modification in our

project. i send you to all code, GUI and fingerprint database. you
run this code .
and test our project . the main class file is Finger_Print.java. use
this for testing.
and i write point which is want to my guide, plz advice on that .
#  i have in gui four windows. first is user fingerprint which given
from database1  and second given from internal system database2. other
2 are for seeing

what is exactly going on during number of process.but presently both
fingerprint are given user by using file browsing facility. but this
lenghty and time

consuming process when database are big. therefore we want  first
fingerprint will given by user using browse facility and second one
given by

automatically second window from database2 and proceed it same like as
before and show the result. but we have problem  only that how to give
database

connectivity  and automaticaly proceed all fingerprint one by one and
store the result which is matching with that fingerprint. therefore
plz advice me. and

implement your own idea in our project. plz modified our code as you
prefer. and send to me. i wait your advice. bcoz our project
submission will be on 20

th april. plz give me as early as possible.  plz all of you reply me
on my email address. THANKING YOU.

my email address:  santoshtwaghmode@gmail.com


YOURS FAITHFULLY

SANTOSH

i give code with file name , plz u have copy paste as separate file.
plz download some fingerprint on the internet and test my project.file
save as given name.

```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

1> Finger_Print.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import java.io.*;
import java.util.*;

class Finger_Print{
    JFileChooser chooser;
    JMenuBar menu;
    BufferedImage bi1,bi2,orienti,segi1,segi2,threshi1,threshi2;
    BufferedImage thini1,thini2;
    static JPanel mainPanel;
    JPanel source_panel,output_panel,button_panel;
    JLabel template_image,template_text,input_image,input_text,
            tmplt_output_image,tmplt_output_text,output_image,output_text;
    JButton start_button,clear_button,exit_button;
    File image1,image2;
    Vector real_x1,real_y1,real_theta1,real_x2,real_y2,real_theta2;
    Vector end_x1,end_y1,end_x2,end_y2;
    double mean1,mean2,score;

    ImageManip imap1,imap2;
    Bin_Thin bt1,bt2;
    Minutiae_Extract me1,me2;
    Matching match;

    public Finger_Print() {
        mainPanel = new JPanel();
       mainPanel.setLayout(new
BoxLayout(mainPanel,BoxLayout.Y_AXIS));//main panel is splitted along
Y-axis

       source_panel = new JPanel();
        source_panel.setLayout(new
BoxLayout(source_panel,BoxLayout.X_AXIS));//Above splitted part
divided along x-axis

        output_panel = new JPanel();
        output_panel.setLayout(new
BoxLayout(output_panel,BoxLayout.X_AXIS));//Above splitted part
divided along x-axis

        button_panel = new JPanel();
        button_panel.setLayout(new FlowLayout());//Flow layouts are
typically used to arrange buttons in a panel
       addWidgets();

       mainPanel.add(source_panel);
       mainPanel.add(output_panel);
       mainPanel.add(button_panel);

       source_panel.setMaximumSize(new Dimension(500,350));//500-X-axis,
350-Y-axis
       output_panel.setMaximumSize(new Dimension(500,350));
       button_panel.setMaximumSize(new Dimension(500,50));

    }

    private static void createAndShowGUI() {
        Graphics g;
       JFrame.setDefaultLookAndFeelDecorated(false);

       Finger_Print phases = new Finger_Print();

       JFrame mainFrame = new JFrame("Finger Print");
         mainFrame.setResizable(true);
         mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);  //sets
mainframe in maximised state.
         mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//
closes panel when click on min,max,close
         mainFrame.setContentPane(phases.mainPanel);
        mainFrame.setVisible(true);
   }

    public static void main(String[] args) {
       javax.swing.SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               createAndShowGUI();
           }
       });
   }
   private void setDefault()
   {
       template_image.setText("Source Image1");
       template_image.setIcon(new ImageIcon("Default.jpg"));

       input_image.setText("Source Image2");
       input_image.setIcon(new ImageIcon("Default.jpg"));

       tmplt_output_image.setText("Output Image1");
       tmplt_output_image.setIcon(new ImageIcon("Default.jpg"));

       output_image.setText("Output Image2");
       output_image.setIcon(new ImageIcon("Default.jpg"));

       bi1 = null;
       bi2 = null;
       segi1 = null;
       segi2 = null;
       orienti = null;
       threshi1 = null;
       threshi2 = null;
       thini1 = null;
       thini2 = null;
       mean1 = 0;
       mean2 = 0;
       score = 0;

       start_button.setText("Start");
   }
    public void addWidgets()
    {
        chooser = new JFileChooser();//File choosers provide a GUI for
navigating the file system
        chooser.addChoosableFileFilter(new filter1());//This mthd allow to
choose those imgs that r allowed by Filter1

        template_image = new JLabel();//JLabel:A display area for a short
text string or an image, or both.
             //
template_image.setBorder(BorderFactory.createLineBorder(Color.black));//
Border Factory.. returns obj type BORDER
        template_image.setBorder(BorderFactory.createLoweredBevelBorder());//
createLoweredBevelBorder()..shaded border
        template_image.setMaximumSize(new Dimension(250,250));
        template_image.setVerticalAlignment(SwingConstants.TOP);//Before
taking i/p image
        template_image.setHorizontalAlignment(SwingConstants.CENTER);//
Before taking i/p image
        template_image.setVerticalTextPosition(SwingConstants.BOTTOM);//
After taking i/p image
        template_image.setHorizontalTextPosition(SwingConstants.CENTER);//
After taking i/p image
        //template_image.setIcon(new ImageIcon("images/20.jpg"));

        input_image = new JLabel();
        input_image.setBorder(BorderFactory.createLoweredBevelBorder());
        input_image.setMaximumSize(new Dimension(250,250));
        input_image.setVerticalAlignment(SwingConstants.TOP);
        input_image.setHorizontalAlignment(SwingConstants.CENTER);
        input_image.setVerticalTextPosition(SwingConstants.BOTTOM);
        input_image.setHorizontalTextPosition(SwingConstants.CENTER);

        source_panel.add(template_image);
        source_panel.add(input_image);

        tmplt_output_image = new JLabel();
   
tmplt_output_image.setBorder(BorderFactory.createLoweredBevelBorder());
        tmplt_output_image.setMaximumSize(new Dimension(250,250));
        tmplt_output_image.setVerticalAlignment(SwingConstants.TOP);
        tmplt_output_image.setHorizontalAlignment(SwingConstants.CENTER);
        tmplt_output_image.setVerticalTextPosition(SwingConstants.BOTTOM);
        tmplt_output_image.setHorizontalTextPosition(SwingConstants.CENTER);

        output_image = new JLabel();
        output_image.setBorder(BorderFactory.createLoweredBevelBorder());
        output_image.setMaximumSize(new Dimension(250,250));
        output_panel.add(tmplt_output_image);
        output_panel.add(output_image);
        output_image.setVerticalAlignment(SwingConstants.TOP);
        output_image.setHorizontalAlignment(SwingConstants.CENTER);
        output_image.setVerticalTextPosition(SwingConstants.BOTTOM);
        output_image.setHorizontalTextPosition(SwingConstants.CENTER);

        start_button = new JButton("Start");
        start_button.addActionListener(new ActionListener() //Adds specified
action listener to receive action events
        { public void actionPerformed(ActionEvent event) {    //
actionPerformed Invoked when an action occurs

                if(start_button.getText().equals("Start")) //getText -Returns the
button's text.
                {
                    if((image1 = ChooseFile()) != null)
                    {
                        if((image2 = ChooseFile()) != null)
                        {
                            try{
                                bi1 = ImageIO.read(image1); //If code throws exception
                                bi2 = ImageIO.read(image2); //try block performs catch action
                            }catch(IOException e) { }  //Signals that an I/O exception has
occurred
                            template_image.setIcon(
                                new ImageIcon(bi1.getScaledInstance(    //Gets scaled version
of image.
                                    250,225,Image.SCALE_SMOOTH)));//Choose an image-scaling

algorithm that gives
                                                                         //higher priority
to image smoothness than scaling speed.
                            input_image.setIcon(
                                new ImageIcon(bi2.getScaledInstance(
                                    250,225,Image.SCALE_SMOOTH)));
                            start_button.setText("Orientation");

                            imap1 = new ImageManip(bi1);
                            imap2 = new ImageManip(bi2);
                        }
                    }
                }
                else if(start_button.getText().equals("Orientation"))
                {
                    //System.out.println("Field Orientation");
                    mean1 = imap1.fieldestimation();
                    mean2 = imap2.fieldestimation();
                    orienti = new BufferedImage(bi1.getWidth(),bi1.getHeight(),5);//
Constructs a BufferedImage of one of the

predefined image types.
                    orienti = imap1.draworientation();//The orientation used for
drawing. It is the sum of the orientation and

attrOrientation variables.

                    tmplt_output_image.setIcon(
                        new ImageIcon(orienti.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Orientation Image1");

                    orienti = null;
                    orienti = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    orienti = imap2.draworientation();
                    output_image.setIcon(
                        new ImageIcon(orienti.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Orientation Image2");

                    start_button.setText("Segmentation");
                }
                else if(start_button.getText().equals("Segmentation"))
                {
                    //System.out.println(mean1+":"+mean2);
                    segi1 = new BufferedImage(bi1.getWidth(),bi1.getHeight(),5);
                    segi2 = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    imap1.segmentation(mean1,segi1);

                    tmplt_output_image.setIcon(
                        new ImageIcon(segi1.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Segmented Image1");

                    segi2 = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    imap2.segmentation(mean2,segi2);
                    output_image.setIcon(
                        new ImageIcon(segi2.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Segmented Image2");

                    start_button.setText("Binarization");
                }
                else if(start_button.getText().equals("Binarization"))
                {
                    bt1 = new Bin_Thin();
                    bt2 = new Bin_Thin();

                    threshi1 = new BufferedImage(bi1.getWidth(),bi1.getHeight(),5);
                    bt1.thres(16,bi1.getWidth(),bi1.getHeight(),segi1,threshi1);
                    tmplt_output_image.setIcon(
                        new ImageIcon(threshi1.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Binarized Image1");

                    threshi2 = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    bt2.thres(16,bi2.getWidth(),bi2.getHeight(),segi2,threshi2);
                    output_image.setIcon(
                        new ImageIcon(threshi2.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Binarized Image2");

                    start_button.setText("Thinning");
                }
                else if(start_button.getText().equals("Thinning"))
                {
                    thini1 = new BufferedImage(bi1.getWidth(),bi1.getHeight(),5);
                    thini1 =
bt1.thin(threshi1,threshi1.getWidth(),threshi1.getHeight(),5);
                    tmplt_output_image.setIcon(
                        new ImageIcon(thini1.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Thinned Image1");

                    thini2 = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    thini2 =
bt2.thin(threshi2,threshi2.getWidth(),threshi2.getHeight(),5);
                    output_image.setIcon(
                        new ImageIcon(thini2.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Thinned Image2");

                    start_button.setText("Smooth");
                }
                else if(start_button.getText().equals("Smooth"))
                {
                    bt1.m_connect(thini1);
                    tmplt_output_image.setIcon(
                        new ImageIcon(thini1.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Smoothen Image1");

                    bt2.m_connect(thini2);
                    output_image.setIcon(
                        new ImageIcon(thini2.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Smoothen Image2");

                    start_button.setText("Extract");
                }
                else if(start_button.getText().equals("Extract"))
                {
                    me1 = new Minutiae_Extract();
                    me2 = new Minutiae_Extract();
                    end_x1 = new Vector(20,1);//Vector(int initialCapacity, int
capacityIncrement)
                    end_y1 = new Vector(20,1);// empty vector with specified initial
capacity & capacity
                    BufferedImage mextimg = new
BufferedImage(bi1.getWidth(),bi1.getHeight(),5);
                    mextimg = me1.extract(thini1,end_x1,end_y1);
                    tmplt_output_image.setIcon(
                        new ImageIcon(mextimg.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Extracted Minutiae (Image1)");

                    mextimg =null;
                    end_x2 = new Vector(20,1);//Vector(int initialCapacity, int
capacityIncrement)
                    end_y2 = new Vector(20,1);// empty vector with specified initial
capacity & capacity increment.
                    mextimg = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    mextimg = me2.extract(thini2,end_x2,end_y2);
                    output_image.setIcon(
                        new ImageIcon(mextimg.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Extracted Minutiae (Image2)");

                    start_button.setText("Filter");
                }
                else if(start_button.getText().equals("Filter"))
                {
                    BufferedImage filti = new
BufferedImage(bi1.getWidth(),bi1.getHeight(),5);
                    real_x1 = new Vector(20,1);
                    real_y1 = new Vector(20,1);
                    real_theta1 = new Vector(20,1);
                    filti =
me1.postprocess(thini1,imap1.theta,end_x1,end_y1,real_x1,real_y1,real_theta1);
                    tmplt_output_image.setIcon(
                        new ImageIcon(filti.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    tmplt_output_image.setText("Filtered Minutiae (Image1)");

                    filti = null;
                    real_x2 = new Vector(20,1);
                    real_y2 = new Vector(20,1);
                    real_theta2 = new Vector(20,1);
                    filti = new BufferedImage(bi2.getWidth(),bi2.getHeight(),5);
                    filti =
me1.postprocess(thini2,imap2.theta,end_x2,end_y2,real_x2,real_y2,real_theta2);
                    output_image.setIcon(
                        new ImageIcon(filti.getScaledInstance(
                            250,225,Image.SCALE_SMOOTH)));
                    output_image.setText("Filtered Minutiae (Image2)");

                    start_button.setText("Match");
                }
                else if(start_button.getText().equals("Match"))
                {
                    match = new Matching();
                    score =
match.CompareMinutiaeSets(real_x1,real_y1,real_theta1,real_x2,real_y2,real_theta2);
                    JOptionPane.showMessageDialog((JFrame) null,
                    score > 90 ? Math.ceil(score)+"% : Template
Matched":Math.ceil(score)+"% : No

Match","Output",JOptionPane.INFORMATION_MESSAGE);
                    start_button.setText("Start");
                }
            }
            });

        exit_button = new JButton("Exit");
        exit_button.addActionListener(new ActionListener()
        { public void actionPerformed(ActionEvent event) {
                System.exit(1);
            }
            });

        clear_button = new JButton("Clear");
        clear_button.addActionListener(new ActionListener()
        { public void actionPerformed(ActionEvent event) {
                setDefault();
            }
            });

        button_panel.add(exit_button);
        button_panel.add(clear_button);
        button_panel.add(start_button);

        setDefault();
    }
    private File ChooseFile()
    {
        int result = chooser.showOpenDialog(null);//Pops up an "Open File"
file chooser dialog.
        File file = chooser.getSelectedFile();//Returns the selected file
        if(result == JFileChooser.APPROVE_OPTION){   //APPROVE_OPTION return
int 0 value if yes/ok choosen
            //System.out.println(file.getPath());
            return file;
        }
        else if(result == JFileChooser.CANCEL_OPTION){ //CANCEL_OPTION
return int 1 value if cancel is choosen
            return null;
        }
        return null;
    }
    public static void writetoFile(BufferedImage bi,String filename)
    {
        try
        {
        Iterator writers = ImageIO.getImageWritersByFormatName("jpg");
        ImageWriter writer = (ImageWriter)writers.next();
        File f = new File("images/output/"+filename);
        ImageOutputStream ios = ImageIO.createImageOutputStream(f);
        writer.setOutput(ios);
        writer.write(bi);
        }
        catch(IOException e){}
    }
}
class filter1 extends javax.swing.filechooser.FileFilter//A
FileFilter, once implemented, can be set on a JFileChooser to
                                                        //keep
unwanted files from appearing in the directory listing.
{
    public boolean accept(File fileobj)//checks extension is jpg or not.
    {
        String extension = "";

        if(fileobj.getPath().lastIndexOf('.') > 0)
            extension = fileobj.getPath().substring(
                fileobj.getPath().lastIndexOf('.')
                +1).toLowerCase();

        if(extension != "")
            return extension.equals("jpg");
        else
            return fileobj.isDirectory();//returns 0 if obj invalid & viseversa
    }

    public String getDescription()//displays returned string in file
navigation
    {
        return "JPG files (*.jpg)";
    }
}

```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

2> Bin_Thin.java

import java.awt.image.*;

class Bin_Thin
{
    public void thres(int size,int iw,int ih,BufferedImage
source,BufferedImage dest)
    {
        int i,j,k,l,mean_thres,count = 0;
        for(i = 0;i < iw;i+=size)
        {
            for(j = 0;j<ih;j+=size)
            {
                mean_thres = 0;
                for(k = i;k <= i+size-1 && k<iw; k++)
                {
                    for(l = j; l<=j+size-1 && l<ih;l++)
                    {
                        mean_thres = mean_thres + (0xFF & source.getRGB(k,l));
                    }
                }
                mean_thres = mean_thres/(size*size);
                for(k = i;k <= i+size-1 && k<iw; k++)
                {
                    for(l = j; l<=j+size-1 && l<ih;l++)
                    {
                        if ((0xFF & source.getRGB(k,l)) >= mean_thres)
                        {
                            dest.setRGB(k,l,0xFF000000);
                        }
                        else
                        {
                            dest.setRGB(k,l,0xFFFFFFFF);
                        }
                    }
                }
            }
        }
    }
    public BufferedImage thin(BufferedImage pixel,int iw,int ih,int
type) //thinning
    {
        int count = 100,A,B,P[],i,j;
        P = new int[8];
        BufferedImage temp,k;
        temp = new BufferedImage(iw,ih,type);
        k = new BufferedImage(iw,ih,type);
        for(i = 0;i<iw;i++)
        {
            for(j=0;j<ih;j++)
            {
                temp.setRGB(i,j,pixel.getRGB(i,j));
                k.setRGB(i,j,temp.getRGB(i,j));
                               //setRGB():Sets a pixel in this
BufferedImage to the specified RGB value
            }
        }

        while(count != 0)
        {
            count = 0;
            for(i = 1;i<iw-1;i++)
            {
                for(j = 1;j<ih-1;j++)
                {
                    if((temp.getRGB(i,j) & 0x01) == 1)//check whether pixel belong to
BG or Fingerprint.
                    {
                        //System.out.println("HI");
                                               P[0] =
temp.getRGB(i,j-1)&0x01;
                                               P[1] = temp.getRGB(i
+1,j-1)&0x01;
                                               P[2] = temp.getRGB(i
+1,j)&0x01;
                                               P[3] = temp.getRGB(i
+1,j+1)&0x01;
                                               P[4] = temp.getRGB(i,j
+1)&0x01;
                                          P[5] = temp.getRGB(i-1,j+1)&0x01;
                                               P[6] =
temp.getRGB(i-1,j)&0x01;
                        P[7] = temp.getRGB(i-1,j-1)&0x01;

                        B = P[0]+P[1]+P[2]+P[3]+P[4]+P[5]+P[6]+P[7];
                        A=0;
                       if ( P[0]==0   && P[1]==1   )A++;//checks connectivity
pass 1 step2
                       if ( P[1]==0   && P[2]==1   )A++;
                       if ( P[2]==0   && P[3]==1   )A++;
                       if ( P[3]==0   && P[4]==1   )A++;
                       if ( P[4]==0   && P[5]==1   )A++;
                       if ( P[5]==0   && P[6]==1   )A++;
                       if ( P[6]==0   && P[7]==1   )A++;
                       if ( P[7]==0   && P[0]==1   )A++;
                       if( (B>=2) && (B<=6) && (A==1) && (P[0]*P[2]*P[4]==0)
&& (P[0]*P[2]*P[6]==0)  )
                       {
                           k.setRGB(i,j,0xFF000000);
                           count++;
                         }
                    }
                }
            }
            for(i = 0;i<iw;i++) //pass 2 begins
            for(j=0;j<ih;j++)
            {
                temp.setRGB(i,j,k.getRGB(i,j));
            }
            for(i = 1;i<iw-1;i++)
            {
                for(j = 1;j<ih-1;j++)
                {
                    if((temp.getRGB(i,j) & 0x01) == 1)
                    {
                        P[7] = temp.getRGB(i-1,j-1)&0x01; P[0] = temp.getRGB(i,j-1)&
0x01; P[1] = temp.getRGB(i+1,j-1) &

0x01;
                        P[6] = temp.getRGB(i-1,j) & 0x01;

    P[2] = temp.getRGB(i+1,j)&0x01;
                        P[5] = temp.getRGB(i-1,j+1)&0x01; P[4] = temp.getRGB(i,j
+1)&0x01; P[3] =

temp.getRGB(i+1,j+1)&0x01;
                        B = P[0]+P[1]+P[2]+P[3]+P[4]+P[5]+P[6]+P[7];
                        A=0;
                       if ( P[0]==0   && P[1]==1   )A++;
                       if ( P[1]==0   && P[2]==1   )A++;
                       if ( P[2]==0   && P[3]==1   )A++;
                       if ( P[3]==0   && P[4]==1   )A++;
                       if ( P[4]==0   && P[5]==1   )A++;
                       if ( P[5]==0   && P[6]==1   )A++;
                       if ( P[6]==0   && P[7]==1   )A++;
                       if ( P[7]==0   && P[0]==1   )A++;
                       if( (B>=2) && (B<=6) && (A==1) && (P[2]*P[4]*P[6]==0)
&& (P[0]*P[4]*P[6]==0)  )
                       {
                           k.setRGB(i,j,0xFF000000);
                           count++;
                         }
                    }
                }
            }
            for(i = 0;i<iw;i++)
            for(j=0;j<ih;j++)
            {
                temp.setRGB(i,j,k.getRGB(i,j));
            }
        }
        for(i = 0;i<iw;i++)
        {
            for(j=0;j<ih;j++)
            {
                if((temp.getRGB(i,j)&0x01) == 0)
                    temp.setRGB(i,j,0xFFFFFFFF);//white
                else
                    temp.setRGB(i,j,0xFF000000);//black
            }
        }
        return temp;
    }
    public void m_connect(BufferedImage thini)   //smoothes image.
    {
        BufferedImage temp;
        temp = new
BufferedImage(thini.getWidth(),thini.getHeight(),thini.getType());
        for(int i=1;i<thini.getWidth()-1;i++)
        {
            for(int j = 0;j<thini.getHeight()-1;j++)
            {
                if(thini.getRGB(i,j) == 0xFF000000 && thini.getRGB(i+1,j+1) ==
0xFF000000)
                {
                    thini.setRGB(i+1,j,0xFFFFFFFF);  // 1 2   if pixel 3&2 are black
make 1,2 white.
                    thini.setRGB(i,j+1,0xFFFFFFFF);  // 3 4
                }
                if(thini.getRGB(i,j) == 0xFF000000 && thini.getRGB(i-1,j+1) ==
0xFF000000)
                {
                    thini.setRGB(i,j+1,0xFFFFFFFF);  // 1 2   if pixel 1&4 are black
make 3,2 white.
                    thini.setRGB(i-1,j,0xFFFFFFFF);  // 3 4
                }
            }
        }
    }
}

`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

3>  Histogram.java

import java.awt.image.*;

class Histogram
{
    int ptable[],ncount,nmean,nvariance;
    public Histogram()
    {
        ptable = new int[256];
        for (int i = 0; i < 256; i++)
           ptable[i] = 0;
       ncount    = 0;
       nmean     = -1;
       nvariance = -1;
    }
    public void HistogramCompute(BufferedImage bi)
    {
        int w,h,x,y;
        w = bi.getWidth();
        h = bi.getHeight();
        for(y=0;y<h;y++)
        {
            for(x=0;x<w;x++)
            {
                ptable[bi.getRGB(x,y)&0xFF]++;
            }
        }
        ncount = w*h;
    }
    public int HistogramGetMean()
    {
        if(nmean == -1)
        {
            nmean = 0;
            for(int i=0;i<256;i++)
                nmean+=i*ptable[i];

            nmean /= ncount;
        }
        return nmean;
    }
    public int HistogramGetVariance()
    {
        nmean = HistogramGetMean();
        if(nvariance == -1)
        {
            nvariance = 0;
            for(int i=0;i<256;i++)
                nvariance += ptable[i]*(i-nmean)*(i-nmean);

            nvariance /= ncount;
        }
        return nvariance;
    }
}

`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

4> ImageEnhance.java

import java.awt.image.*;

class ImageEnhance
{
    public BufferedImage bi;
    int iw,ih;
    public double EnhanceGabor(int x,int y,double o,double f,double r2)
    {
        double dy2 = 1.0/r2;
       double dx2 = 1.0/r2;
       double x2, y2;
       o += Math.PI/2;
       y2 = -x*Math.sin(o) + y*Math.cos(o);
       x2 =  x*Math.cos(o) + y*Math.sin(o);
       return Math.exp(-0.5*(x2*x2*dx2 +
y2*y2*dy2))*Math.cos(2*Math.PI*x2*f);

    }
    public void ImageEnhanceGabor(BufferedImage normalized,double[]
freq,double[] theta)
    {
        double r2 = 0.5*0.5;
        int Wg2 = 8,i,j,v,u;
        double o,f,sum;
        iw = normalized.getWidth();
        ih = normalized.getHeight();
        bi = new BufferedImage(iw,ih,5);
        for (j = Wg2; j < ih-Wg2; j++)
       for (i = Wg2; i < iw-Wg2; i++)
       {
            sum = 0.0;
            o = theta[i+j*iw];
            f = freq[i+j*iw];
            //System.out.println(f);
            for (v = -Wg2; v <= Wg2; v++)
            for (u = -Wg2; u <= Wg2; u++)
            {
                sum += EnhanceGabor(u,v,o,f,r2)
                        * (normalized.getRGB((i-u),(j-v)) & 0xFF);
            }
            /* printf("%6.1f ", sum);*/
            //System.out.println(sum);
            if (sum>255.0) sum = 255.0;
            if (sum<0.0)   sum = 0.0;
              bi.setRGB(i,j,0xFF000000 | (new Double(sum)).intValue()
<< 16 |
                               (new Double(sum)).intValue() << 8 |
                               (new Double(sum)).intValue());
       }
   }

}
`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

5>ImageManip.java

import java.awt.image.*;

class ImageManip
{
    BufferedImage bi;
    public BufferedImage normalize;
    public int iw,ih,size;
    public double theta[],cl[],freq[],theta2[],mask[];
    public ImageManip(BufferedImage bi)
    {
        this.bi = bi;
        size = 16;
        iw = bi.getWidth();
        ih = bi.getHeight();
    }
    public void FingerprintGetDirection()
    {
        double Gx[],Gy[],Vx[],Vy[],Ve[];
        int i,j;
        Gx = new double[ih*iw];
        Gy = new double[ih*iw];
        Vx = new double[iw*ih];
        Vy = new double[iw*ih];
        Ve = new double[iw*ih];
        theta = new double[iw*ih];
        //cl = new double[iw*ih];
        int xmin,xmax,ymin,ymax;
        double max=0;
        for(i = 0 ;i < iw; i++)
        {
            xmin = i-1 < 0 ? 0 : i-1;
            xmax = i+1 == iw ? iw-1: i+1;
            for(j = 0;j < ih;j++)
            {
                ymin = j-1 < 0 ? 0 : j-1;
                ymax = j+1 == ih ? ih-1 : j+1;
                Gx[i+(j*iw)] = ((bi.getRGB(xmin,ymax) & 0xFF) +
                                2*(bi.getRGB(i,ymax) & 0xFF) + (bi.getRGB(xmax,ymax) & 0xFF)
                                - (bi.getRGB(xmin,ymin) & 0xFF) -
                                2*(bi.getRGB(i,ymin) & 0xFF) - (bi.getRGB(xmax,ymin) & 0xFF));
                Gy[i+(j*iw)] = ((bi.getRGB(xmax,ymin) & 0xFF) +
                                2*(bi.getRGB(xmax,j) & 0xFF) + (bi.getRGB(xmax,ymax) & 0xFF)
                                - (bi.getRGB(xmin,ymin) & 0xFF) -
                                2*(bi.getRGB(xmin,j) & 0xFF) - (bi.getRGB(xmin,ymax) & 0xFF));
                Gx[i+(j*iw)] =(double) ((double)1/8)*(bi.getRGB(i,j) & 0xFF)*Gx[i+
(j*iw)];
                Gy[i+(j*iw)] = (double)((double)1/8)*(bi.getRGB(i,j) & 0xFF)*Gy[i+
(j*iw)];
            }
        }
        int u,v;
        int k = 0;

        for(i = 0; i < ih; i++)
        {
            for(j = 0; j < iw; j++)
            {
                Vx[i*iw+j] = 0;
                Vy[i*iw+j] = 0;
                Ve[i*iw+j] = 0;

                for( u = i-size/2;u<=i+size/2 && u < ih;u++)
                {
                    if(u < 0)
                        u = 0;
                    else if(u >= ih)
                        u = ih-1;
                    for(v = j-size/2;v<=j+size/2 && v < iw;v++)
                    {
                        if(v < 0)
                            v = 0;
                        else if(v >= iw)
                            v = iw-1;

                        Vx[i*iw+j] += 2*Gx[v+(u*iw)]*Gy[v+(u*iw)];
                        Vy[i*iw+j] += (Gx[v+(u*iw)]*Gx[v+(u*iw)])
                                        - (Gy[v+(u*iw)]*Gy[v+(u*iw)]);
                        /*Ve[i*iw+j] += Gx[v+(u*iw)]*Gx[v+(u*iw)]
                                        + Gy[v+(u*iw)]*Gy[v+(u*iw)];*/
                    }
                }

                theta[i*iw+j] = (double)Math.atan2(Vx[i*iw+j],Vy[i*iw+j]);
                /*cl[k] = Math.sqrt(((double)Vx[k]*Vx[k] + (double)Vy[k]*Vy[k])
                                /((double)(size*size)/(double)Ve[k]));*/
                //System.out.println(theta[i*iw+j]);
            }
        }
        FingerPrintDirectionLowPass(5);
    }
    public void FingerPrintDirectionLowPass(int
nFilterSize)              //This method applies a low pass filter
    {
        int fsize = nFilterSize*2+1,val,x,y,i,j;
        double filter[] = new double[fsize*fsize];
        double phix[] = new double[iw*ih];
        double phiy[] = new double[iw*ih];
        double phi2x[] = new double[iw*ih];
        double phi2y[] = new double[iw*ih];
        double nx,ny;

        theta2 = new double[iw*ih];
        for(y = 0;y<ih;y++)
        {
            for(x = 0;x<iw;x++)
            {
                val = x+y*iw;
                phix[val] = Math.cos(theta[val]);
                phiy[val] = Math.sin(theta[val]);
            }
        }
        nx = 0.0;
        for(j = 0;j<fsize;j++)
        {
            for(i=0;i<fsize;i++)
            {
                filter[j*fsize+i] = 1.0;
                nx += filter[j*fsize+i];
            }
        }
        if (nx>1.0)
       {
           for (j = 0; j < fsize; j++)
           for (i = 0; i < fsize; i++)
               /* normalize the result */
               filter[j*fsize+i] /= nx;
       }
       /* low-pass on the result arrays getting phi2 */
       for (y = 0; y < ih-fsize; y++)
       for (x = 0; x < iw-fsize; x++)
       {
           nx = 0.0;
           ny = 0.0;
           for (j = 0; j < fsize; j++)
           for (i = 0; i < fsize; i++)
           {
               val = (x+i)+(j+y)*iw;
               nx += filter[j*fsize+i]*phix[val];
               ny += filter[j*fsize+i]*phiy[val];
           }
           val = x+y*iw;
           phi2x[val] = nx;
           phi2y[val] = ny;
       }
       phix = null;
       phiy = null;
       /* 5 - local ridge orientation -> theta */
       for (y = 0; y < ih-fsize; y++)
       for (x = 0; x < iw-fsize; x++)
       {
           val = x+y*iw;
           theta2[val] = (double)Math.atan2(phi2y[val],
phi2x[val])*0.5;// Converts rectangular coordinates (x, y) to polar
           //System.out.println(Math.toDegrees(theta2[val]));
       }
    }
    public void FingerprintGetFrequency()
    {
        double cosdir,sindir,Xsig[],out[],pmax,pmin;
        freq = new double[iw*ih];
        out = new double[iw*ih];
        Xsig = new double[32];
        final double EPSILON = 0.0001;
        int u,v,k,val;
        int peak_pos[];
       int peak_cnt;
       double peak_freq;
        peak_pos = new int[32];

        System.out.println("--Finding X-signature...");

        for(int y = 0;y<ih-16;y++)
        for(int x = 0;x<iw - 16;x++)
        {
            val = x+y*iw;
            cosdir = Math.cos(theta2[val]);
            sindir = -Math.sin(theta2[val]);

            for(k=0;k<32;k++)
            {
                Xsig[k] = 0.0;
                for(int d=0;d<16;d++)
                {
                    u = x+(int)(((d - 8)*cosdir)+((k - 16)*sindir));
                    v = y+(int)(((d - 8)*sindir)+((16 - k)*cosdir));
                    u = u<0?0:u;
                    v = v<0?0:v;
                    u = u>=iw?iw-1:u;
                    v = v>=ih?ih-1:v;
                    Xsig[k] += (bi.getRGB(u,v) & 0xFF);

                }
                Xsig[k] /= 16;
            }
            pmax = pmin = Xsig[0];
            peak_cnt = 0;
            for(k = 0;k < 32;k++)
            {
                if(Xsig[k] < pmin) pmin = Xsig[k];
                if(Xsig[k] > pmax) pmax = Xsig[k];
            }

            if ((pmax - pmin)>64.0)
           {
               for (k = 1; k < 32-1; k++)
               if ((Xsig[k-1] < Xsig[k]) && (Xsig[k] >= Xsig[k+1]))
               {
                   peak_pos[peak_cnt++] = k;
               }
           }
            peak_freq = 0.0;
            if (peak_cnt>=2)
           {
               for (k = 0; k < peak_cnt-1; k++)
                   peak_freq += peak_pos[k+1]-peak_pos[k];
               peak_freq /= peak_cnt-1;
           }
           if (peak_freq > 30.0)
               out[val] = 0.0;
           else if (peak_freq < 2.0)
               out[val] = 0.0;
           else
               out[val] = 1.0/peak_freq;

       }
       System.out.println("--Interpolation...");
        for (int y = 16; y < ih-16; y++)
       for (int x = 16; x < iw-16; x++)
       {
           if (out[x+y*iw]<EPSILON)
           {
               if (out[x+(y-1)*iw]>EPSILON)
               {
                   out[x+(y*iw)] = out[x+(y-1)*iw];
               }
               else
               {
                   if (out[x-1+(y*iw)]>EPSILON)
                       out[x+(y*iw)] = out[x-1+(y*iw)];
               }
           }
       }

        double lpfactor = (1.0/((3*2+1)*(3*2+1)));
        System.out.println("--Inter ridge distance...");
        for (int y = 16; y < ih-16; y++)
       for (int x = 16; x < iw-16; x++)
       {
           k = x + y*iw;
           peak_freq = 0.0;
           for ( v = -3; v <= 3; v++)
           for ( u = -3; u <= 3; u++)
               peak_freq += out[(x+u)+(y+v)*iw];
           freq[k] = peak_freq*lpfactor;
       }

    }
    /*public void FingerprintGetMask()
    {
        double freqmin = 1.0/25;
        double freqmax = 1.0/3;
        int out = new int[iw*ih];
        int x,y,pos,posout;

        for (y = 0; y < ih; y++)
       for (x = 0; x < iw; x++)
       {
           pos    = x + y * iw;
           posout = x + y * iw;
           out[posout] = 0;
           if (freq[pos] >= freqmin && freq[pos] <= freqmax)
           {
               out[posout] = 255;
           }
       }
          for (y = 0; y < 4; y++)
           ImageDilate(mask);
       for (y = 0; y < 12; y++)
           ImageErode(mask);
    }*/
    public void ImageNormalize()
    {
        final int mean = 100, variance = 100;
        Histogram histogram = new Histogram();
        int x,y;
        double fmean,fsigma,fmean0,fsigma0,fgray,fcoeff = 0.0;

        histogram.HistogramCompute(bi);
        fmean = (double)histogram.HistogramGetMean();
        fsigma = Math.sqrt((double)histogram.HistogramGetVariance());

        fmean0 = mean;
        fsigma0 = Math.sqrt(variance);

        if(fsigma > 0.0)
            fcoeff = fsigma0/fsigma;

        normalize = new BufferedImage(iw,ih,5);
        for (y = 0; y < ih; y++)
           for (x = 0; x < iw; x++)
           {
               fgray = bi.getRGB(x,y) & 0xFF;
               fgray = fmean0 + fcoeff*(fgray - mean);
               if (fgray < 0.0)    fgray = 0.0;
               if (fgray > 255.0)  fgray = 255.0;
               normalize.setRGB(x,y,0xFF000000 | (new
Double(fgray)).intValue() << 16 |
                               (new Double(fgray)).intValue() << 8 |
                               (new Double(fgray)).intValue());
           }

    }

    /*Old Hierarchical Algorithm*/

    public double fieldestimation()
    {
        int i,j;
        double Gx[],Gy[],Vx[],Vy[],Ve[];
        Gx = new double[ih*iw];
        Gy = new double[ih*iw];
        Vx = new double[(iw/size+1)*(ih/size+1)];
        Vy = new double[(iw/size+1)*(ih/size+1)];
        Ve = new double[(iw/size+1)*(ih/size+1)];
        theta = new double[(iw/size+1)*(ih/size+1)];
        cl = new double[(iw/size+1)*(ih/size+1)];
        int xmin,xmax,ymin,ymax;
        double max=0;
        for(i = 0 ;i < iw; i++)
        {
            xmin = i-1 < 0 ? 0 : i-1;
            xmax = i+1 == iw ? iw-1: i+1;
            for(j = 0;j < ih;j++)
            {
                ymin = j-1 < 0 ? 0 : j-1;
                ymax = j+1 == ih ? ih-1 : j+1;
                Gx[i+(j*iw)] = ((bi.getRGB(xmin,ymax) & 0xFF) +
                                2*(bi.getRGB(i,ymax) & 0xFF) + (bi.getRGB(xmax,ymax) & 0xFF)
                                - (bi.getRGB(xmin,ymin) & 0xFF) -
                                2*(bi.getRGB(i,ymin) & 0xFF) - (bi.getRGB(xmax,ymin) & 0xFF));
                Gy[i+(j*iw)] = ((bi.getRGB(xmax,ymin) & 0xFF) +
                                2*(bi.getRGB(xmax,j) & 0xFF) + (bi.getRGB(xmax,ymax) & 0xFF)
                                - (bi.getRGB(xmin,ymin) & 0xFF) -
                                2*(bi.getRGB(xmin,j) & 0xFF) - (bi.getRGB(xmin,ymax) & 0xFF));
                Gx[i+(j*iw)] =(double) ((double)1/8)*(bi.getRGB(i,j) & 0xFF)*Gx[i+
(j*iw)];
                Gy[i+(j*iw)] = (double)((double)1/8)*(bi.getRGB(i,j) & 0xFF)*Gy[i+
(j*iw)];
            }
        }
        int u,v;
        int k = 0;

        for(i = 0; i < ih; i+=size)
        {
            for(j = 0; j < iw; j+=size)
            {
                Vx[k] = 0;
                Vy[k] = 0;
                Ve[k] = 0;

                for( u = i;u<=i+size && u < ih;u++)
                {
                    for(v = j;v<=j+size && v < iw;v++)
                    {
                        Vx[k] += 2*Gx[v+(u*iw)]*Gy[v+(u*iw)];
                        Vy[k] += (Gx[v+(u*iw)]*Gx[v+(u*iw)])
                                        - (Gy[v+(u*iw)]*Gy[v+(u*iw)]);
                        Ve[k] += Gx[v+(u*iw)]*Gx[v+(u*iw)]
                                        + Gy[v+(u*iw)]*Gy[v+(u*iw)];
                    }
                }

                theta[k] = (double)0.5*Math.atan2(Vx[k],Vy[k]);
                cl[k] = Math.sqrt(((double)Vx[k]*Vx[k] + (double)Vy[k]*Vy[k])
                                /((double)(size*size)/(double)Ve[k]));
                              //cl[k] is certainty level and if
<Threshold it is treated as background.

                if(k == 0)
                {
                    max = cl[0];
                }

                if(max < cl[k])
                    max = cl[k];
                k++;

            }
        }
        return max;    //max is mean of finger print used bfore orientation
in F_P class
    }
    public void segmentation(double max,BufferedImage dest)
    {
        int k = 0,i,j,u,v;
        for(i = 0; i < ih; i+=size)
        {
            for(j = 0; j < iw; j+=size)
            {
                if(cl[k] < max*0.0005)  //max*0.0005 is threshold.
                {
                    for( u = i;u<i+size & u < ih;u++)      //Replaces bg pixel with
black
                    {
                        for(v = j;v<j+size & v < iw;v++)
                        {
                            dest.setRGB(v,u,0xFF000000);//black
                        }
                    }
                }
                else
                {
                    for( u = i;u<i+size & u < ih;u++)
                    {
                        for(v = j;v<j+size & v < iw;v++)
                        {
                            dest.setRGB(v,u,bi.getRGB(v,u));
                        }
                    }
                }

                k++;
            }
        }
    }
    public BufferedImage draworientation()
    {
        BufferedImage dest;
        int linex[],liney[],tarx[],tary[];
        linex = new int[16];
        liney = new int[16];
        tarx = new int[16];
        tary = new int[16];
        int k = 0,i,j;
        double xy[],ans[];
        xy = new double[3];
        ans = new double[3];
        double r[][];
        r = new double[3][3];
        int point;
        int field[],l;
          field = new int[(size+1)*(size+1)];
          dest = new BufferedImage(iw,ih,5);
          int p;
          int u,v;
        for(i = 0;i<ih;i+=size)
        {
            for(j = 0;j<iw;j+=size)
            {
                point = -(size/2-1); //point is midpoint of W*W window .detail
&diagram refer thining pdf
                for(int b = 0;b<size;b++)
                {
                    linex[b] = point++;  //point is on x axis
                    liney[b] = 0;
                }
                for(int c=0;c<size;c++)
                  {
                    r[0][0] = Math.cos(theta[k]);
                    r[0][1] = -Math.sin(theta[k]);
                    r[0][2] = r[1][2] = r[2][0] = r[2][1] = 0;
                    r[1][0] = Math.sin(theta[k]);
                    r[1][1] = Math.cos(theta[k]);
                    r[2][2] = 1;

                   xy[0] = linex[c];
                   xy[1] = liney[c];
                    xy[2] = 1;
                    for(int a=0;a<3;a++)
                          ans[a] = 0;
                    matmul1(xy,r,ans);
                   tarx[c] = (int)ans[0];
                    tary[c] = (int)ans[1];

                  }
                  p = 0;
                  for(int m = -7;m<=8;m++)
                  {
                      for(int n = -7;n<=8;n++)
                      {
                          for(l = 0;l<size;l++)
                          {
                              if(m == tary[l] && n == tarx[l])
                              {
                                  field[p] = 0xFFFFFFFF;//white
                                  break;
                              }
                          }
                          if(l == size)
                              field[p] = 0xFF000000;//black
                          p++;
                      }
                  }
                  p = 0;
                  for(u = i; u < i+size && u < ih;u++)
                  {
                      for(v = j;v < j+size && v < iw;v++)
                      {
                          if(field[p] == 0xFFFFFFFF)
                              dest.setRGB(v,u,field[p]);
                          else
                              dest.setRGB(v,u,bi.getRGB(v,u));
                          p++;
                      }
                  }
                  k++;
              }
          }
          return dest;
    }
    public void matmul1(double xy[],double t[][],double ans[])
    {
         int i,j;

         for(i=0;i<3;i++)
            for(j=0;j<3;j++)
            {
                  ans[i] = ans[i] + xy[j]*t[j][i];
            }
    }
}

`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````

6>  Matching.java

import java.util.*;

class Matching{
    final int EPS_REF=30,EDIT_DIST_THRESHOLD=10;
    final double ALPHA=1.0,BETA=2.0,GAMMA=0.1,
            OHM=(200.0*(ALPHA+GAMMA+BETA)),ETA=0.5;
    final double
DEL_LO_M_N=-8.0,DEL_HI_M_N=8.0,SI_LO_M_N=-7.5,SI_HI_M_N=7.5;
    final double DEL_REF=(DEL_HI_M_N - DEL_LO_M_N);
    final double SI_REF=(SI_HI_M_N - SI_LO_M_N);

    public double CompareMinutiaeSets(Vector end_x,Vector end_y,Vector
end_theta,
            Vector end_x1,Vector end_y1,Vector end_theta1)
    {
        int i=0,tx,ty;
        double itheta,ttheta,ir,tr,ie,te,ftmp3=0.0;
        int ltmp1=0,ltmp2=0,ltmp3=0;
        double fatmp1[],fatmp2[],edit_dist[][];

        double diff_r,diff_e,diff_theta,ftmp;
        double window_mn,a;
        double edit_dist_m1_n;
        double edit_dist_m_n1;
        double edit_dist_m1_n1;
        double edit_dist_m_n=0.0;
        int window_flag,nb_pair,nb_minutiae;
        double Mpq;
        int nb_input_minutiae = end_x1.size();
        int nb_tmplt_minutiae = end_x.size();
        //System.out.println(nb_input_minutiae);
        Polar p_polar_input[];
        p_polar_input = new Polar[nb_input_minutiae];
        //System.out.println(p_polar_input+" : "+p_polar_input.length);
        for(int n=0;n<nb_input_minutiae;n++)
        {
            p_polar_input[n] = new Polar();
            //System.out.println(p_polar_input[n]);
            p_polar_input[n].toPolar(new Integer((end_x1.get(n)).toString()),
                                    new Integer((end_y1.get(n)).toString()),
                                    new Double((end_theta1.get(n)).toString()));

        }

        Polar p_polar_tmplt[];
        p_polar_tmplt = new Polar[nb_tmplt_minutiae];
        for(int n = 0;n<nb_tmplt_minutiae;n++)
        {
            p_polar_tmplt[n] = new Polar();
            p_polar_tmplt[n].toPolar(new Integer((end_x.get(n)).toString()),
                                    new Integer((end_y.get(n)).toString()),
                                    new Double((end_theta.get(n)).toString()));
        }

        InsertionSort(p_polar_input,nb_input_minutiae);
        InsertionSort(p_polar_tmplt,nb_tmplt_minutiae);

        //Finding Edit Distance
        if(nb_tmplt_minutiae > nb_input_minutiae)
            edit_dist = new double[nb_tmplt_minutiae][nb_tmplt_minutiae];
        else
            edit_dist = new double[nb_input_minutiae][nb_input_minutiae];

        for(int m = 0;m<nb_tmplt_minutiae;m++)
            edit_dist[m][0] = 0.0;

        for(int n = 0;n<nb_input_minutiae;n++)
            edit_dist[0][n] = 0.0;

        for(int m =1;m<nb_tmplt_minutiae;m++)
        {
            tr = p_polar_tmplt[m].r;
            te = p_polar_tmplt[m].e;
            ttheta = p_polar_tmplt[m].angle;
            for(int n=1;n<nb_input_minutiae;n++)
            {
                ir = p_polar_input[n].r;
                ie = p_polar_input[n].e;
                itheta = p_polar_input[n].angle;
                //calculate window function w(m,n)
                diff_r = tr - ir;
                ftmp = te - ie;
                ftmp += 360.0;
                if(ftmp > 360.0)
                    a = ftmp - 360.0;
                else
                    a = 360.0 - ftmp;

                if(a < 180.0)
                    diff_e = a;
                else
                    diff_e = a-180.0;

                ftmp = ttheta - itheta;
                ftmp += 360.0;
                if(ftmp > 360.0)
                    a = ftmp - 360.0;
                else
                    a = 360.0 - ftmp;

                if(a < 180.0)
                    diff_theta = a;
                else
                    diff_theta = a-180.0;

                window_flag = 0;
                if((diff_r < DEL_REF) || (diff_e < SI_REF) || (diff_theta <
EPS_REF))
                    window_flag = 1;

                if(window_flag == 1)
                {
                    window_mn = (ALPHA * diff_r);
                    window_mn += (BETA * diff_e);
                    window_mn += (GAMMA * diff_theta);
                }
                else
                    window_mn = OHM;

                edit_dist_m1_n = edit_dist[m-1][n+0] + OHM;
                edit_dist_m_n1 = edit_dist[m+0][n-1] + OHM;
                edit_dist_m1_n1 = edit_dist[m-1][n-1] + window_mn;
                edit_dist_m_n = 0.0;
                if(edit_dist_m1_n < edit_dist_m_n1)
                    edit_dist_m_n = edit_dist_m1_n;
                else
                    edit_dist_m_n = edit_dist_m_n1;

                if(edit_dist_m1_n1 < edit_dist_m_n)
                    edit_dist_m_n = edit_dist_m1_n1;

                edit_dist[m][n] = edit_dist_m_n;
            }
        }
        nb_pair = 0;
        //System.out.println(nb_tmplt_minutiae+" : "+nb_input_minutiae);
        for(int m = 0;m<(nb_tmplt_minutiae < nb_input_minutiae ?
nb_tmplt_minutiae:nb_input_minutiae);m++)
        {
                if(edit_dist[m][m] < (double)EDIT_DIST_THRESHOLD)
                    nb_pair++;
        }

        nb_minutiae = nb_tmplt_minutiae;

        if(nb_input_minutiae < nb_tmplt_minutiae)
            nb_minutiae = nb_input_minutiae;

        //System.out.println(nb_minutiae+":"+nb_pair);

        Mpq = ((double)100.0 * (double)nb_pair)/(double)nb_minutiae;
        return Mpq;
    }
    public void InsertionSort(Polar[] p,int count)
    {
        double item_to_insert1; // On the kth pass, insert item k into its
correct
       double item_to_insert2; // On the kth pass, insert item k into
its correct
       double item_to_insert3; // On the kth pass, insert item k into
its correct
       int still_looking, j, k;    // position among the first k entries
in vector.

       //System.out.println("");
       //for(int i=0;i<count;i++)
       //    System.out.println(p[i].angle+":"+p[i].r+":"+p[i].e);
       for (k = 1; k < count; ++k) {

           // Walk backwards through list,
           // looking for slot to insert v[k]

           item_to_insert1 = p[k].angle;
          item_to_insert2 = p[k].r;
           item_to_insert3 = p[k].e;

           j = k - 1;
           still_looking = 1;

           while ((j >= 0) && (still_looking==1))  {

               if (item_to_insert1 < p[j].angle) {

                  p[j + 1].angle = p[j].angle;
                  p[j + 1].r = p[j].r;
                   p[j + 1].e = p[j].e;

                   p[j].angle = item_to_insert1;       // where
item_to_insert belongs
                   p[j].r = item_to_insert2;           // where
item_to_insert belongs
                   p[j].e = item_to_insert3;           // where
item_to_insert belongs

                  --j;

              } else  {

                   still_looking = 0;                  // Upon leaving
loop, j + 1 is the index
                  p[j + 1].angle = item_to_insert1;   // where
item_to_insert belongs
                   p[j + 1].r = item_to_insert2;       // where
item_to_insert belongs
                   p[j + 1].e = item_to_insert3;       // where
item_to_insert belongs