terça-feira, janeiro 05, 2021

Sensor Biométrico de Impressão Digital - Parte 5: Pegando a Imagem da Digital e Salvando e Restaurando Templates

Para completar o estudo ficaram faltando alguns comandos que envolvem a troca de uma quantidade maior de dados com o sensor, o que deu algum trabalho e trouxe algumas surpresas.


O monitor da IDE do Arduino não é apropriado para exercitar estes comandos. Para isto eu criei uma aplicação em Python, usando as bibliotecas Tkinter (para construir a interface gráfica), PIL (para manipular a imagem da digital) e Serial (para comunicar com o microcontrolador). O resultado não é muito "pitônico", robusto ou genérico, mas é o suficiente para os meus testes. Ele pode ser visto no repositório do projeto no github.

O programa permite fazer três operações:

  • Captura: Faz o processo de cadastrar uma digital (que é salva numa posição fixa do sensor), enviando a imagem e o template. No PC, a imagem é apresentada na tela e salva no arquivo [nome].bmp, onde [nome] é o que foi digitado no campo correspondente (ou 'teste' se o campo estiver vazio). O template é salvo em [nome].fpm.
  • Confere: Faz a leitura de uma digital e compara com a salva na posição de teste
  • Carrega: Envia o template em [nome].fpm para o sensor e salva na posição de teste

Os testes iniciais ainda foram feitos usando o monitor. Para isso eu transferi os dados binários no formato hexadecimal, algo bastante ineficiente do ponto de vista de velocidade.

O esquema de comunicação entre o programa Python e o microcontrolador (que continuou sendo o Seeeduino XIAO) é simples:

  • O programa Python envia uma letra para disparar uma operação (as operações suportadas são Cadastrar digital, Verificar digital e carregar Template.
  • As respostas do microcontrolador começam com uma letra e são seguidas de uma quantidade pré-determinada de caracteres.
  • No caso específico da carga de template, o microcontrolador envia uma letra para indicar que está pronto. O programa Python envia o próximo trecho dos dados (até 128 bytes, em hexadecimal), seguido de 'z' se tem mais dados ou 'Z' se é o trecho final.

A transferência de dados com o sensor me confundiu no começo. São utilizados dois tipos de pacotes: o pacote de dados e o pacote final de dados. Ao receber um comando que envolva a transferência de dados o sensor manda primeiro um pacote de resposta, indicando se o comando foi aceito. Em seguida são transferidos vários pacotes de dado e um pacote final de dados. A quantidade de bytes enviados em cada pacote é configurável, assumi o default de 128.

Uma coisa chata nesta sequência é que não é informado no começo qual o tamanho total dos dados. Ao tentar entender melhor a dinâmica desta comunicação achei uma biblioteca interessante, que você pode ver aqui. Uma das coisas importantes que ele menciona é que existem muitas variações entre sensores parecidos.

O primeiro comando a examinar é o que envia a imagem capturada pelo sensor (UpImage). A imagem tem uma resolução de 256x288 pontos. A imagem enviada é em tons de cinza, com 4 bits por ponto. Na comunicação cada byte corresponde a dois pontos (os 4 bits mais significativos corresponde ao ponto à esquerda). Como o tamanho da imagem é maior a Ram disponível no XIAO, implementei um esquema onde cada pacote recebido do sensor é imediatamente repassado ao programa Python (em hexadecimal). Isto é viável porque a comunicação USB do XIAO é muito mais rápida que a comunicação serial com o sensor (caso contrário poderia ocorrer a perda de caracteres enviados pelo sensor).

No lado do Python aproveitei parte do código de um exemplo da biblioteca do  Brian Ejike para salvar os dados recebidos em formato BMP (nada muito especial aqui, mas teria que relembrar o formato dos arquivos BMP e gastar tempo acertando os detalhes).

O segundo comando é o que envia o template gerado pelo sensor (UpChar). Uma surpresa aqui foi o tamanho do template: 1536 bytes, bem maior do que o que eu esperava.

O último comando é o inverso do anterior (DownChar). Aqui é o micrcontrolador quem envia os pacotes de dados para o sensor.

O código todo pode ser visto no meu github. Lembrando, o meu código está feito para um Arduino com duas seriais.

Com este post termino o meu estudo do sensor (fica faltando fazer um projeto completo, mas isso vai para a GLIP).

Nenhum comentário: