Como o reconhecimento de face ajuda a encontrar telefones de teste

Olá, cidadãos de Habrovsk! A EastBanc Technologies possui um grande número de projetos relacionados ao desenvolvimento móvel. Nesse contexto, é necessário um zoológico inteiro de dispositivos para testes em todas as etapas. E, caracteristicamente, todos os dispositivos são constantemente necessários para uma variedade de pessoas, e encontrá-lo em um departamento de desenvolvimento móvel de várias dezenas de pessoas é uma história completa. Sem mencionar que existem testadores, designers, PMs, no final!

E, para não perder o telefone, mas para saber claramente onde está e com quem, usamos um banco de dados online que reconhece os funcionários pelo rosto. Agora vamos contar como chegamos a isso e o implementamos.

imagem

Contexto histórico


Tínhamos uma placa com “cartões” de dispositivos com informações básicas e um local para um ímã indicando um funcionário. Todo mundo observou sobre levar o dispositivo.

imagem

Este sistema tem suas desvantagens - não críticas, mas geralmente desconfortáveis:

  • Os ímãs não são tão fáceis de mover de um lugar para outro.
  • Para olhar para esse quadro, você definitivamente precisará ir para outro escritório.
  • E ainda assim, alguém pode precisar de vários dispositivos ao mesmo tempo ... O que significa que você precisa de vários ímãs por funcionário.
  • Ah, sim, às vezes até os funcionários param e chegam novos, nos quais ímãs também precisam ser feitos.

Aplicativo para celular


Em uma empresa envolvida na automação de processos de negócios, o uso da solução "analógica" descrita acima não é muito saudável. Naturalmente, decidimos automatizar a tarefa de encontrar o dispositivo certo. O primeiro passo foi escrever um aplicativo móvel que possa determinar e relatar sua localização em salas via pontos de acesso Wi-Fi. No caminho, por conveniência, eles deram ao dispositivo a capacidade de informar o servidor sobre a versão do sistema operacional e também mostram uma característica tão importante quanto a carga da bateria.

Parece que o problema está resolvido. Você olha a lista no banco de dados em que a última vez que o dispositivo viu o Wi-Fi, você vai lá e ...

Em operação, descobriu-se que nem tudo é tão simples. Instalamos o aplicativo em dispositivos de teste e trabalhamos com ele por vários meses. Descobriu-se que esta opção é conveniente, mas também não é o ideal.

Os dispositivos estão descarregados, basta desligar, os pontos de acesso Wi-Fi são reorganizados de um lugar para outro, e a geolocalização por si só indica que o dispositivo está no escritório. Obrigado capitão!

Você pode, é claro, tentar otimizar o sistema existente, mas por que não reinventá-lo com base nas tecnologias do século XXI? Mal disse o que fez.

Como queríamos que fosse


Criamos um conceito para um sistema que reconheceria os funcionários por seus rostos, testaria os dispositivos por tags especiais, solicitaria confirmação de uma alteração no status do dispositivo e, em seguida, faria alterações no banco de dados on-line, que qualquer funcionário pode assistir sem se levantar da cadeira.

Reconhecimento de rosto


O reconhecimento facial, como um todo, resolveu o problema em 2018. Portanto, não reinventamos o volante e tentamos treinar nossos próprios modelos, mas aproveitamos uma solução pronta. O módulo FaceRecognition parecia ser a opção mais conveniente, pois não requer treinamento adicional e funciona muito rapidamente, mesmo sem aceleração na GPU.

Usando a função face_locations , os rostos foram detectados nas fotos dos funcionários e, usando os códigos de rosto , os recursos faciais de um funcionário específico foram extraídos deles.

Os dados recebidos foram coletados no banco de dados. Para determinar um funcionário específico usando a função face_distance , foi considerada a “diferença” entre a codificação do funcionário detectado e as codificações do banco de dados.

Em geral, nesta fase, é possível ir além e criar um classificador, por exemplo, baseado no KNN , para que o sistema seja menos sensível à dinâmica dos rostos dos funcionários. No entanto, na prática, isso requer significativamente mais tempo. E a média banal da codificação do rosto de uma pessoa entre a que está agora no banco de dados e a que o sistema descobriu para alterar o status do dispositivo acabou sendo suficiente para evitar a acumulação de erros na prática.

Código de reconhecimento de rosto
face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) face_names = [] for face_encoding in face_encodings: matches = face_recognition.face_distance( known_face_encodings, face_encoding) name = "Unknown" if np.min(matches) <= 0.45: best_match_index = np.argmin(matches) name = known_face_info[str(best_match_index)]['name'] else: best_match_index = None 


Reconhecimento de dispositivo


Inicialmente, surgiu a idéia de usar códigos QR para o reconhecimento do dispositivo, no qual inserir ao mesmo tempo informações sobre o dispositivo. No entanto, para o reconhecimento estável do código QR, ele precisou ser trazido muito perto da câmera, o que é inconveniente.

Como resultado, surgiu a idéia de usar marcadores de realidade aumentada. Eles carregam menos informações, mas são muito mais reconhecidos de maneira estável. Durante os experimentos, um marcador de 30 milímetros foi reconhecido pela câmera com pequenos desvios da vertical (3-5 graus) a uma distância de até dois metros e meio.

Esta opção já parecia muito melhor. O ARuco foi escolhido entre todo o conjunto de marcadores de realidade aumentada, como todas as ferramentas necessárias para trabalhar com eles estão presentes na distribuição opencv-contrib-python .

Código de reconhecimento de token ARuco
 self.video_capture = cv2.VideoCapture(0) ret, frame = self.video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) markers = cv2.aruco.detectMarkers(gray, self.dictionary) 


Como resultado, cada dispositivo recebeu um índice numérico, ao qual um marcador foi associado a esse índice.

É uma coisa de chapéu?


Parece que aprendemos a reconhecer dispositivos e rostos, o trabalho está feito. Fanfarra, aplausos! O que mais pode ser necessário?

De fato, o trabalho está apenas começando. Agora, todos os componentes do sistema devem ser trabalhados de maneira estável e rápida "em batalha".

É necessário otimizar o custo dos recursos do servidor em modo inativo, pensar nos casos do usuário e entender como ele deve parecer graficamente.

Interface


Talvez o ponto mais importante no desenvolvimento de tais sistemas seja a interface. Alguém pode argumentar, mas o usuário é o elemento central nessa situação.

O mais rápido possível, você pode implementar a parte frontal usando o Tkinter .

Algumas notas sobre Tkinter
  • Preste atenção às indentações / tamanhos dos elementos (relativos ou absolutos).
  • Lembre-se de que unidades relativas e absolutas podem ser usadas juntas (seus valores são simplesmente somados).
  • Parâmetro
     .attributes("-fullscreen", True) 
    Permite criar um aplicativo de janela única, expandindo para tela cheia, para não confundir os usuários com elementos da interface do sistema.

A interface consiste em cartões com informações sobre o dispositivo e o usuário que está usando este dispositivo. A maior parte da tela é ocupada pelo catálogo de cartões - a principal ferramenta de contabilidade. Na parte superior, há um filtro com o qual você pode filtrar o diretório por plataforma ou versão do sistema operacional.

imagem

Aqui estão os principais componentes da interface:


  • Dispositivo
    Os cartões do dispositivo são exibidos na tela com a versão do sistema operacional, o nome e o ID do dispositivo, bem como o usuário no qual este dispositivo está atualmente registrado.
  • Photofixing
    À direita está a unidade de controle, onde a imagem da webcam é exibida, além de botões para registrar e editar informações pessoais.

    Exibimos a imagem para dar feedback ao usuário - você definitivamente atinge a tela com o rótulo do dispositivo.
  • Seleção de versão do SO
    Fizemos uma lista com a escolha da versão de interesse do SO, porque frequentemente para testar, você não precisa de um dispositivo específico, mas de uma determinada versão do Android ou iOS. O filtro de versão é horizontal para economizar espaço e tornar a lista de versões acessível sem rolagem, em uma tela.

Otimização


Uma passagem de qualquer componente do sistema não leva muito tempo. No entanto, se você iniciar o reconhecimento de marcadores e faces ao mesmo tempo, uma tentativa de reconhecer todos os 30 quadros por segundo fornecidos pela câmera levará a uma exaustão completa dos recursos do computador sem uma GPU.

É claro que 99% das vezes o sistema fará esse trabalho ocioso.

Para evitar isso, foram tomadas as seguintes decisões de otimização:

  1. Somente cada oitavo quadro é alimentado no processamento.

    Código
     if self.lastseen + self.rec_threshold > time.time() or self.frame_number != 8: ret, frame = self.video_capture.read() self.frame_number += 1 if self.frame_number > 8: self.frame_number = 8 return frame, None, None, None 

    O atraso da resposta do sistema aumenta para cerca de 8/30 segundos, enquanto o tempo de reação humano é de aproximadamente um segundo. Consequentemente, esse atraso ainda não será perceptível para o usuário. E já reduzimos oito vezes a carga no sistema.
  2. Primeiro, o marcador do dispositivo é pesquisado no quadro e, somente quando é detectado, o reconhecimento de rosto é iniciado. Como a busca por marcadores no quadro é aproximadamente 300 vezes mais barata que a busca por rostos, decidimos que, no modo de espera, verificaremos apenas a presença de um marcador.
  3. Para reduzir os “freios” ao procurar faces quando não há faces na imagem, o parâmetro number_of_time_to_upsample foi desativado na função face_locations.

    face_locations = face_recognition.face_locations (rgb_small_frame, número_de_ vezes_para_upsample = 0)

    Devido a isso, o tempo de processamento do quadro, no qual não há faces, foi igual ao tempo de processamento do quadro, onde as faces são facilmente detectadas.

Qual é o resultado?


No momento, o sistema foi implantado com sucesso no MacMini Final de 2009, que chegou ao alcance de dois núcleos Core 2 Duo. Como parte do teste, funcionou com êxito, mesmo em um núcleo virtual com 1024 megabytes de RAM e 4 gigabytes de memória somente leitura no contêiner do Docker. MacMini conectou uma tela sensível ao toque para tornar a aparência minimalista.

Agora, mesmo os usuários que não usaram o quadro antigo com entusiasmo e sorriram ao registrar dispositivos em si mesmos, e houve muito menos casos de pesquisas malsucedidas!

O que vem a seguir?


Sem dúvida, existem muitos outros pontos no sistema atual que podemos e gostariamos de melhorar:

  • Verifique se os controles do SO não aparecem quando as caixas de diálogo são exibidas (agora essa é uma caixa de mensagens do pacote Tkinter).
  • Cálculos separados e solicitações de servidor em diferentes threads com processamento de interface (agora eles são executados no thread principal, mainloop Tkinter, que congela a interface ao enviar solicitações ao banco de dados online).
  • Traga a interface para o mesmo design com outros recursos corporativos.
  • Faça uma interface web completa para visualização remota de dados.
  • Use o reconhecimento de voz para confirmar / cancelar ações e preencher campos de texto.
  • Implemente o registro de vários dispositivos simultaneamente.

PS E é assim que funciona.
Vídeo gravado na versão beta da GUI

Source: https://habr.com/ru/post/pt426437/


All Articles