Escrito por

Software Architect at Visum
Artigo Yuri Marx · 2 hr atrás 4m read

Reconhecimento facial com InterSystems Vector Search e DeepFace

O reconhecimento facial tornou-se o método mais popular para validar a identidade das pessoas, permitindo assim o acesso a sistemas, a confirmação de dados pessoais e documentais e a aprovação de ações e documentos.
Os desafios estão relacionados ao desempenho quando o banco de dados é muito grande, à precisão e, principalmente, à privacidade dos dados faciais biométricos. Para esses desafios, nada é melhor do que usar o InterSystems Vector Search, pois ele permite:

  1. Realizar buscas vetoriais em milhões de registros com respostas muito mais rápidas do que os métodos tradicionais.
  2. Os modelos vetoriais e matemáticos usados ​​pelo Vector Search têm alta precisão sem sacrificar o desempenho.
  3. Não é necessário armazenar as imagens dos rostos, mas apenas os embeddings das imagens, tornando a engenharia reversa impossível. Isso permite total conformidade com o GDPR, LGPD e outras regulamentações de privacidade de dados pessoais.

Este artigo detalha o processo passo a passo de coleta, processamento, armazenamento e realização de buscas faciais vetoriais. O Deepface, uma biblioteca Python muito popular para processar rostos humanos e transformá-los em representações vetoriais (embeddings), é usado em conjunto com o InterSystems IRIS Vector Search para realizar comparações vetoriais nas representações armazenadas, permitindo o reconhecimento facial em tempo quase real.

Instalação e utilização da solução

Siga estes passos para instalar o reconhecimento facial (uma solução de código aberto baseada em Deepface e IRIS):

  1. Clone/git pull o repositório para qualquer diretório local.
$ git clone https://github.com/yurimarx/facial-matching.git
$ cd facial-matching
$ docker-compose build
$ docker-compose up -d

Observação: a etapa de construção do docker-compose é demorada porque os modelos do DeepFace são baixados nesta fase.

2. Abra o aplicativo em http://localhost:8501.

3. Cadastre algumas pessoas (selecione Câmera e Tirar Foto para capturar sua imagem com a câmera do seu computador ou faça o upload de arquivos. Clique em Finalizar Cadastro para salvar a pessoa no banco de dados IRIS e em Redefinir formulário para limpar o formulário e usá-lo novamente):

4. Encontre pessoas usando uma foto ou sua câmera para encontrar pessoas já cadastradas (use a aba Buscar/Verificar):


5. Veja todas as pessoas cadastradas na aba Lista de Cadastrados:


 

Detalhes sobre a implementação

  1. Tabela de vetores para armazenar embeddings:
Class dc.facialmatching.FacialData Extends (%Persistent, %JSON.Adaptor)
{

Property FaceVector As %Vector(%JSONINCLUDE = "none", DATATYPE = "float", LEN = 4096);

Property Name As %String(MAXLEN = 100);

Property Age As %Integer;

Property Gender As %String;

Property Ethnicity As %String;

Property SSN As %String;

2. A propriedade `FaceVector As %Vector(%JSONINCLUDE = "none", DATATYPE = "float", LEN = 4096)` permite definir o tipo de dados e o comprimento do vetor de incorporação. Cada modelo pode ter tipos de dados e comprimentos diferentes.

3. Para transformar e salvar a imagem como um vetor incorporado:

def register():
    try:
        ssn = request.form.get('ssn')
        name = request.form.get('name')
        
        if 'image' not in request.files:
            return jsonify({"error": "Nenhum arquivo de imagem enviado"}), 400
        
        file = request.files['image']
        
        filestr = file.read()
        nparr = np.frombuffer(filestr, np.uint8)
        img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

        objs = DeepFace.represent(img, model_name="VGG-Face", enforce_detection=True)
        embedding = objs[0]["embedding"]
        analysis = DeepFace.analyze(img, actions=['age', 'gender', 'race'], enforce_detection=False)[0]

        conn = get_iris_connection()
        cursor = conn.cursor()
        
        sql = """
            INSERT INTO dc_facialmatching.FacialData 
            (SSN, Name, Age, Gender, Ethnicity, FaceVector) 
            VALUES (?, ?, ?, ?, ?, TO_VECTOR(?))
        """
        cursor.execute(sql, (
            ssn, name, int(analysis['age']), 
            analysis['dominant_gender'], analysis['dominant_race'], 
            json.dumps(embedding)
        ))
        conn.commit()
        cursor.close()
        conn.close()

4. A função `DeepFace.represent(img, model_name="VGG-Face", enforce_detection=True)` transforma a imagem do rosto em um vetor incorporado.

Para inserir esse vetor incorporado no IRIS, utilize a função `TO_VECTOR`.

INSERT INTO dc_facialmatching.FacialData (SSN, Name, Age, Gender, Ethnicity, FaceVector) VALUES (?, ?, ?, ?, ?, TO_VECTOR(?))

5. Para realizar uma correspondência facial, você deve fazer uma busca vetorial:

		objs = DeepFace.represent(img, model_name="VGG-Face", enforce_detection=True)
        current_vector = objs[0]["embedding"]
        
        conn = get_iris_connection()
        cursor = conn.cursor()
        
        sql = """
            SELECT TOP 1 SSN, Name, Age, Gender, Ethnicity,
                   VECTOR_DOT_PRODUCT(FaceVector, TO_VECTOR(?)) as similarity
            FROM dc_facialmatching.FacialData
            ORDER BY similarity DESC
        """
        cursor.execute(sql, (json.dumps(current_vector),))
        row = cursor.fetchone()

6. Obtenha o vetor de incorporação usando Deepface.represent e utilize-o na função select VECTOR_DOT_PRODUCT(FaceVector, TO_VECTOR(?).

7. Aproveite esta solução!