terça-feira, novembro 17, 2020

Sensor Biométrico de Impressão Digital - Parte 4: Identificando Digitais

Continuando o nosso estudo do módulo FPM10A, vamos ver como identificar uma digital capturada pelo módulo. Recomendo dar uma lida no post anterior para entender a terminologia.

Fonte: https://www.jfsmonline.com/text.asp?2016/2/1/60/162807


Como vimos na parte anterior, as digitais são cadastradas em um memória (ou "biblioteca") do módulo. Existem duas operações que podemos fazer para identificar uma digital recém capturada em relação às cadastradas:

  • Comparar com uma digital específica. Esta operação tipicamente é usada quando a digital é usada como uma "senha" após a identificação da pessoa (por exemplo, pela digitação de um código ou leitura de um cartão).
  • Procurar a digital na biblioteca. Nesta operação a digital está sendo usada para identificar a pessoa.
O módulo FPM10A possui dois comandos separados para isso. O comando MATCH compara as duas digitais que estão em CharBuffer1 e CharBuffer2. O comando SEARCH procura uma digital que está em CharBuffer1 ou CharBuffer2 em um trecho da biblioteca (definido pela posição inicial e a quantidade de posições).

Para usar o MATCH vamos ter que usar o comando LOAD, que recupera uma digital da biblioteca e coloca em CharBuffer1 ou CharBuffer2.

O programa completo (Digital3) está no github. Vou apresentar aqui apenas os trechos que ilustram o processo.

Estas duas rotinas são da parte anteior, estão aqui para facilitar o entendimento.
// Faz a captura de imagem e geração da feature
void capturaFeature(byte numBuf) {
  while (true) {
    // Captura a imagem
    Serial.println("Coloque o dedo");
    do {
      delay(50);
    } while (!fpm.capturaDigital());
    Serial.println("OK");

    // Tenta gerar as features
    bool ok = fpm.geraFeature(numBuf);

    // Pede para retirar o dedo
    Serial.println("Retire o dedo");
    do {
      delay(2000);
    } while (fpm.capturaDigital() || (fpm.ultimaResposta() != FPM10A::RESP_NOFINGER));

    // Verifica se precisa tentar novamente
    if (ok) {
      return;
    }
    Serial.println("Imagem ruim, vamos tentar novamente");
  }
}

// Lê uma posição (0 a maxDigitais-1)
int lePosicao() {
  int posicao;
  int c;

  while (Serial.read() != -1) {
    delay(100);
  }
  
  while (true) {
    posicao = 0;
    Serial.print ("Posicao? ");
    while (true) {
      c = Serial.read();
      if (c == 0x0D) {
        break;  // enter
      }
      if ((c >= '0') && (c <= '9') && (posicao < 100)) {
        Serial.write(c);
        posicao = (posicao*10 + c - '0');
      }
    }
    Serial.println();
    if (posicao < maxDigitais) {
      return posicao;
    }
    Serial.println ("Posicao invalida");    
  }
}
A comparação da digital com uma armazenada fica assim:
Serial.println("Compara digital");
posicao = lePosicao();
capturaFeature(1);
if (!fpm.recuperaDigital(2, posicao)) {
  Serial.println ("Erro ao recuperar digital");
  break;
}
if (fpm.comparaDigital()) {
  Serial.println ("Digitais iguais");
} else {
  Serial.println ("Digitais diferentes");
}
A busca da digital na bilioteca é mais simples:
Serial.println("Procura digital");
capturaFeature(1);
posicao = fpm.procuraDigital(1, 0, maxDigitais);
if (posicao == -1) {
  Serial.println ("Digital nao encontrada");
} else {
  Serial.print ("Identificou digital ");
  Serial.println (posicao);
}
Eu não usei neste exemplo, mas os dois comandos de comparação retornam também um número que indica o grau de semelhança entre as digitais consideradas iguais. No próximo post da série vamos ver como "puxar" a imagem da digital capturada.

Nenhum comentário: