Griaule Biometrics

Home » The code itself

How to code

Connection with the database

All the direct operations with the database are made through the class DatabaseOP.
For connecting with sqlserver, the driver jtds was used.
See the details of the connection:

	private void connect() throws ClassNotFoundException, SQLException { 
		
		String URL = "jdbc:mysql://192.168.0.31/tutorialSite";  
		String DRIVER = "com.mysql.jdbc.Driver";  
		String USUARIO = "kaique.ferreira";  
		String SENHA = "griaule123";  
		Class.forName( DRIVER );  
		con = DriverManager.getConnection(URL,USUARIO,SENHA);
			
	}

Most things this class do, are basic operations with database, however there is one that is remarkable: the functions of the class LoadDataToMemory, that is the class responsible for bringing the information from the database to the memory, making the fingerprint identification faster.

See the details of the method from DatabaseOP , which uses the methods from LoadDataToMemory to bring information to the memory.

    private void loadToMemory() throws Exception{

    	 selectStmt = con.prepareStatement("select * from tabela");
	     ResultSet rs = selectStmt.executeQuery();
	   
	     /* In order to load the data from the database the method loadDataToMemory expects a result set as a 
	      * parameter.
	      * This result set should be obtained by a select that brings all the templates.
	      */
	     loadData = new LoadDataToMemory();
	     loadData.loadDataToMemory(rs);
   }
The LoadDataToMemory class

Many customers complain about their search speed, they claim we promise a matching speed of 35.000 fingerprints per second, but they forget that it was measured with no other operations between the matching itself. This is why is so important bringing the templates to memory before comparing them, database access costs much time to a computer. LoadDataToMemory class is the responsible for this important quest. It's core is its method loadDataToMemory, which is shown below. It basically loops the database (parameter received as a result set) and stores it on an array.

public void loadDataToMemory(ResultSet rs) throws Exception{
 
	 int counter  = 0;
	 array = new Register[3000];

	 while (rs.next()){
	 
	      	byte[] template1 = rs.getBytes("template1");
	      	byte[] template2 = rs.getBytes("template2");
	      	byte[] template3 = rs.getBytes("template3");
	      	String name = rs.getString("name");	        
	      	int ID = rs.getInt("id");

	        Register reg = new Register(ID,name,template1,template2,template3);
	        array[counter] = reg;
	        
	        counter++;
	 }

	 this.numberOfRegisters = counter;
}
Interacting with the fingerprints

The program has two main classes that do the operations with fingerprints, one class for each form that manages fingerprints. Notice they are very similiar , they could have been made using inheritance.

Let's see some interesting stuff about those classes.

User authentication

The user authentication part is made by the class FormAuth along with the class FingerprintOPFormAuth. When the program detects that a fingerprint was read, he automatically compares it with the fingerprint stored in the database related to the name the user selected. Notice that on the onImageAcquired event , the program immediately after extracting the template , tries to compare the fingerprints by calling the method authenticate.

    public void onImageAcquired(String IDSensor, FingerprintImage fingerprint) {
    	
   	try {
    	 template = fingerprintSDK.extract(fingerprint);
    	}
    	catch (GrFingerJavaException e) {}
    	
    	this.fingerprint = fingerprint;
    	frmAuth.showImage(fingerprint);
    	
    	try {
			authenticate();
		} catch (IllegalArgumentException e) {
			
		} catch (GrFingerJavaException e) {

		
			e.printStackTrace();
		}
    }
    
    public void authenticate() throws IllegalArgumentException, GrFingerJavaException{
    	
    	String name = null;
    	if (frmAuth.comboNames.getItemCount() > 0){ //check if the user selected a name
    	    name = frmAuth.comboNames.getSelectedItem().toString();
        
    	    //the matrix templates receives a array containing the 3 templates related to the user name 
    	    byte[][] templates = frmAuth.databaseOP.authenticate(name);  
        
    	    boolean matched = false;
        
    	    // if one single template matches, the user is authenticated  
    	    for (int i = 0; i < 3; i++){
    	    	 Template temp = new Template(templates[i]);
    	    	 matched = fingerprintSDK.verify(template,temp);
    	    	 if (matched)
    	    		 break;
    	    	}
    	
    	    frmAuth.handleAuth(name, matched);
    	}
    }

User management

The user authentication part is made by the class FormMain along with the class FingerprintOPFormMain.

Basically, the insert button and the search button define the action the program is going to take when recognizing an image. One more time is used the onImageAcquired event. Let's see this function by parts.

Insert:

If the class property function is set as 0, it means the program is on insertion mode. In this mode, it is read to read 3 users fingerprint. To know how much were read the templateCounter is used. On the two first fingerprints it just extracts the template and keeps it on the classes variables
On the last, besides extracting and keeping ,it gives the order to FormMain to insert in the database the templates that he kept , and the user's id and name

    	if (this.function == 0){
    		
    		try {
    			switch (this.templateCounter){ //extracts the template into the correct variable 
    				case 0:
    					template1 = fingerprintSDK.extract(fingerprint);
    					break;
    				case 1:
    					template2 = fingerprintSDK.extract(fingerprint);
    					break;
    				case 2: 
    					template3 = fingerprintSDK.extract(fingerprint);
    					this.templateCounter = 0; //restarts the counting
    					this.function = -1; //the program is no long is insertion mode
    					try {
							frmMain.commitInsert(); //tells FormMain to insert in the database the templates above extracted
						} catch (Exception e) {}
				       break;
    			}
		} catch (GrFingerJavaException e1) {
			e1.printStackTrace();}
	
		 this.templateCounter++;
    	}

Search:

If the class property function is set as 1, it means the program is on searching mode.
This is an interesting example of how to make comparisons between 3 fingerprints brought by the database and kept in the memory.
A LoadDataToMemory object is created, this object receives the object used on the program , therefore, it has all the database informations in the memory.
As on fingerprint identification is necessary to compare one by one, a loop, that in the worst case checks every database register , is made.
Notice that the method prepareForIdentification must be called just one time , outside the loop.

    	else if (this.function == 1){
    		try {
				Template temp = fingerprintSDK.extract(fingerprint); //temp receives the current fingerprint that was read
				LoadDataToMemory lm = frmMain.frmAuth.databaseOP.getData(); //An object with the templates in the memory
				fingerprintSDK.prepareForIdentification(temp); 
				boolean matched = false;
				int i;
				
				// if one single template matches, the user is authenticated 
				for (i = 0; i < lm.numberOfRegisters(); i++){
		   	    	 matched = false;
		   	    	 
		   	    	 matched = fingerprintSDK.identify(new Template(lm.getTemplate1(i)));
		   	    	 
		   	    	 if (!matched)
		   	    		 matched = fingerprintSDK.identify(new Template(lm.getTemplate2(i)));
		   	    	 
		   	    	 if (!matched)
		   	    		 matched = fingerprintSDK.identify(new Template(lm.getTemplate3(i)));
		   	    	 
		   	    	 if (matched)
		   	    		 break;
		   	   
		   	    	 
		   	    }
		   	    	
		   	    if (matched){
		   	    	this.registerIndex = lm.getID(i); //the index tha was found is keeped
		   	    	String msg = "Template found, id:" + Integer.toString(registerIndex);
		   	    	JOptionPane.showMessageDialog(null,msg, "Found", JOptionPane.INFORMATION_MESSAGE);
		   	    	frmMain.btnRemove.setEnabled(true);
		   	    }
		   	    else
		   	 	    JOptionPane.showMessageDialog(null,"Template not found", "Not found", JOptionPane.INFORMATION_MESSAGE);
		   		 
			} catch (GrFingerJavaException e) {
				e.printStackTrace();}
    	}