Griaule Biometrics

Home » The code itself

How to code

The application has two important forms, FormAuth and FormUserMgt. We will see separately how they work and how they interact with it other. Then we will take a more detailed look at the biometric parts.

FormAuth

Note that this forum will hold griaule's component. However we use 2 forms, only one component is necessary to handle the fingerprints, we just have to do some tricks on the code to allow that. Also, note that there is a dataset, a tableAdapter and a tableAdapterManager in the form. Those components are related to the dataset created on the previous section and can be find at the toolbox. They will be responsible for "talking" with the database.

Once the form is loaded, we instantiate FingerprintOPFormAuth, which is the "util" class for this form and then we call its function that will be responsible for starting griaule's component. Also, we fill our dataset and we fill the combo box with the user's names stored in the database.

    Private Sub FormAuth_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        fingerprintOP = New FingerprintOPFormAuth()
        fingerprintOP.InitializeGrFinger(GrFingerXCtrl)

        tabelaTableAdapter.Fill(ds.tabela)
        'fill our dataset
        loadComboNames()
    End Sub

    Private Sub loadComboNames()
        'loop the database to bring all the user's name
        For Each row As DBGriauleDataSet.tabelaRow In ds.tabela.Rows
            comboNames.Items.Add(row.Name)
        Next
    End Sub

When the onSensorPlug event happpens, we tell the application to start the capture.

    Private Sub grFingerXCtrlAuth_SensorPlug(ByVal sender As Object, ByVal e As AxGrFingerXLib._IGrFingerXCtrlEvents_SensorPlugEvent) Handles GrFingerXCtrl.SensorPlug
        GrFingerXCtrl.CapStartCapture(e.idSensor)
        'start the capture on this sensor
    End Sub

When the user puts the finger on the reader the onImageAcquired event is fired. When it happens, we want to get the image, put it on our picture box, extract the template and check if it matches the fingerprint of the user whose name is equal to the name selected on the combo box.
Another important thing in this match, is the "trick" that is made to use one component for two forms. Here we play with the flag "whichForm" , we check whether the received imaged belong to FormAuth or to FormUserMgt.

    Private Sub grFingerXCtrlAuth_ImageAcquired(ByVal sender As Object, ByVal e As AxGrFingerXLib._IGrFingerXCtrlEvents_ImageAcquiredEvent) Handles GrFingerXCtrl.ImageAcquired
        Dim handle As System.Drawing.Image = Nothing
        Dim hdc As IntPtr = GetDC(System.IntPtr.Zero)
        GrFingerXCtrl.CapRawImageToHandle(e.rawImage, e.width, e.height, hdc.ToInt32(), handle)

        If whichForm.Equals("FormAuth") Then
            'do the action related to the FormAuth
            pbFingerprint.Image = handle
            'put the just added image in our picture box
            pbFingerprint.Update()

            'set the parameters in the FingerprintOPFormUSerMgt class
            fingerprintOP.rawImage.img = e.rawImage
            fingerprintOP.rawImage.height = CInt(e.height)
            fingerprintOP.rawImage.width = CInt(e.width)
            fingerprintOP.rawImage.Res = e.res

            'finally , we extract the template and try to validate de user
            fingerprintOP.extractTemplate()
            Dim matched As Boolean = fingerprintOP.authenticate(comboNames.SelectedItem.ToString(), ds)

            'if the user is validated , a new form containing some details about this user is opened
            If matched Then
                Dim frm As New FormUser()
                frm.Show()
            End If
        Else
            FormUserMgt.onImageAcquired(handle, e.rawImage, CInt(e.height), CInt(e.width), e.res)
        End If
        'do the action related to the FormUserMgt
    End Sub

The flag whichForm starts with the value "FormAuth. There are two other moments when its value is modified.
One is when the FormUserMgt is opened, when obviously the flag assumes the value "FormUserMgt"

    Private Sub btnUserMgt_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnUserMgt.Click
        whichForm = "FormUserMgt"
        FormUserMgt = New FormUserMgt(GrFingerXCtrl, ds)
        AddHandler FormUserMgt.FormClosed, AddressOf formUserMgt_FormClosed
        FormUserMgt.Show()
    End Sub

The other moment is when the FormUserMgt is closed, when obviously the flag assumes the value "FormAuth"
One is when the FormUserMgt is opened, where obviously the flag assumes the value FormUserMgt

    Private Sub formUserMgt_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs)
        whichForm = "FormAuth"
        comboNames.Items.Clear()
        loadComboNames()
    End Sub

FormUserMgt

This form is responsible for inserting/searching/removing users.

Its constructor receives the griaule's component , and FormAuth's dataset. By that, it is able to perform fingerprint and database operations

        Public Sub New(ByVal grfingerxFormAuth As AxGrFingerXLib.AxGrFingerXCtrl, ByVal dataSet As DBGriauleDataSet)
            InitializeComponent()
            fingerprintOP = New FingerprintOPFormUserMgt(grfingerxFormAuth, dataSet, Me)
        End Sub

It has a function called onImageAcquired, note that this is not the griaule's component function, it is just an imitation that is called from the true function in the FormAuth. This form has an util class as well, it is called FingerprintOPFormUserMgt. When the fake onImageAcquired is fired , this util class parameters are set and the image is handled.

Understand the biometric codes

This application introduces us to some important biometric engineering concepts. One of them is storing 3 or more templates of the same finger. It strongly helps in reducing false rejections due to bad quality reading. The other is the idea of bringing the templates to the memory instead of directly managing the database. In the java tutorials we had to make a class for this specif purpose, but fortunately, visual studio components do that to us automatically.

The Extraction

For comparison, we can't use an image object. It's necessary to extract a representation of this image, it is called template. Griaule's component offers the method extract for that, see how the function extractTemplate,defined in our application uses the method extract from grfinger. It passes the parameters as reference, receiving the template in the variable template.tpt.

        Public Sub extractTemplate()
            template.size = CInt(GRConstants.GR_MAX_SIZE_TEMPLATE)
            grfingerx.Extract(rawImage.img, rawImage.width, rawImage.height, rawImage.Res, template.tpt, template.size, _
             CInt(GRConstants.GR_DEFAULT_CONTEXT))
        End Sub
The verification

In fingerprint recognition, we call verification when an specif fingerprint in a database is matched against a read fingerprint. That's what happens when the user puts its finger on the reader in the FormAuth. The application tries to match this user, with the user selected in the combo box. See the code comments for details.

        Public Function authenticate(ByVal name As String, ByVal ds As DBGriauleDataSet) As Boolean
            'instantiating the new templates
            Dim t1 As New TTemplate()
            Dim t2 As New TTemplate()
            Dim t3 As New TTemplate()

            Dim score As Integer = 0
            Dim result As Integer

            'we loop the database to find the name we want
            For Each row As DBGriauleDataSet.tabelaRow In ds.tabela.Rows
                If row.Name.Equals(name) Then
                    'when the name is found, we retrieve the template
                    Dim temp As Byte() = row.Template1
                    System.Array.Copy(temp, 0, t1.tpt, 0, temp.Length)
                    t1.size = temp.Length

                    temp = row.Template2
                    System.Array.Copy(temp, 0, t2.tpt, 0, temp.Length)
                    t2.size = temp.Length

                    temp = row.Template3
                    System.Array.Copy(temp, 0, t3.tpt, 0, temp.Length)
                    t3.size = temp.Length

                    Exit For
                End If
            Next

            'now we try to match with at least one of the user's fingerprint
            result = CInt(grfingerx.Verify(t1.tpt, template.tpt, score, CInt(GRConstants.GR_DEFAULT_CONTEXT)))

            If DirectCast(result, GRConstants) = GRConstants.GR_MATCH Then
                Return True
            End If

            result = CInt(grfingerx.Verify(t2.tpt, template.tpt, score, CInt(GRConstants.GR_DEFAULT_CONTEXT)))

            If DirectCast(result, GRConstants) = GRConstants.GR_MATCH Then
                Return True
            End If

            result = CInt(grfingerx.Verify(t3.tpt, template.tpt, score, CInt(GRConstants.GR_DEFAULT_CONTEXT)))

            If DirectCast(result, GRConstants) = GRConstants.GR_MATCH Then
                Return True
            End If

            Return False
        End Function
The Identification

In fingerprint recognition, we call identification when an specif fingerprint is, in the worst of cases, searched in a whole database. That's what happens when the user puts its finger on the reader in the FormUserMgt after clicking search. The application tries to match this user with some user registered in the database. See the code comments for details.

    Private Sub search()
        [function] = -1
        Dim temp As Byte()
        Dim score As Integer = 0
        templateSearch = extractTemplate(templateSearch)
        'the variable templateSearch receives the image
        Dim result As GRConstants = DirectCast(grfingerx.IdentifyPrepare(templateSearch.tpt, CInt(GRConstants.GR_DEFAULT_CONTEXT)), GRConstants)
        If result < 0 Then
            Return
        End If

        currentRow = Nothing

        'linear search in the database, trying to match at least one fingerprint
        For Each rowAux As DBGriauleDataSet.tabelaRow In ds.tabela.Rows
            'first fingerprint test
            temp = rowAux.Template1
            System.Array.Copy(temp, 0, template1.tpt, 0, temp.Length)
            template1.size = temp.Length

            result = DirectCast(grfingerx.Identify(template1.tpt, score, CInt(GRConstants.GR_DEFAULT_CONTEXT)), GRConstants)
            If result = GRConstants.GR_MATCH Then
                currentRow = rowAux
                Exit For
            End If

            'second fingerprint test
            temp = rowAux.Template2
            System.Array.Copy(temp, 0, template2.tpt, 0, temp.Length)
            template2.size = temp.Length

            result = DirectCast(grfingerx.Identify(template2.tpt, score, CInt(GRConstants.GR_DEFAULT_CONTEXT)), GRConstants)
            If result = GRConstants.GR_MATCH Then
                currentRow = rowAux
                Exit For
            End If

            'third fingerprint test
            temp = rowAux.Template3
            System.Array.Copy(temp, 0, template3.tpt, 0, temp.Length)
            template3.size = temp.Length

            result = DirectCast(grfingerx.Identify(template3.tpt, score, CInt(GRConstants.GR_DEFAULT_CONTEXT)), GRConstants)
            If result = GRConstants.GR_MATCH Then
                currentRow = rowAux
                Exit For
            End If
        Next

        frm.handleSearch()
        'the form handles the result, considering if the fingerprint was found or not
    End Sub