← Voltar aos guias
Teste de modelo privadoFace RecognitionAvaliaçãoMOUPrivacidade

Como executar um teste privado de modelo de reconhecimento InsightFace

Guia passo a passo para avaliar os modelos open-source e privados InsightFace com seus próprios dados: requisitos de MOU, preparação de imagens, cliente Python e controles de privacidade.

8 min de leitura

O que você vai construir

A InsightFace expõe seus modelos de reconhecimento open-source e privados por meio de uma API gerenciada de extração de features para que clientes possam executar uma avaliação de acurácia em seus próprios dados antes de qualquer acordo comercial.

Este guia descreve o fluxo completo: como receber o endpoint, como preparar imagens, como chamar o serviço com um cliente Python mínimo, nossas regras de privacidade e tratamento de dados, e o escopo contratual da janela gratuita de avaliação.

Antes de começar

  • Um Memorando de Entendimento (MOU) assinado cobrindo a intenção de cooperação, o período de avaliação e o escopo de confidencialidade dos identificadores de modelo compartilhados. A URL do endpoint só é liberada após a assinatura.
  • Python 3.9+ com numpy, requests e OpenCV (opencv-python).
  • Um conjunto de validação representativo com resultados de detecção (caixas de RetinaFace, SCRFD ou seu detector).
  • Um conjunto de dados de avaliação claramente definido com rótulos de verdade-base e uma metodologia de avaliação científica.

1. Assinar o MOU e solicitar acesso

Todo teste privado começa com um MOU assinado entre sua organização e a InsightFace. Ele define a intenção de cooperação, o período de avaliação e o escopo de confidencialidade dos identificadores de modelo que compartilhamos com você.

A URL do endpoint, os nomes de modelo habilitados (modelos open-source ou privados autorizados no seu MOU) e quaisquer rate-limits são enviados por e-mail ao contato técnico nomeado no MOU. O endpoint não é publicado e não deve ser compartilhado fora dos contatos autorizados.

  • A janela máxima é de duas semanas a partir da entrega do endpoint. Mais que isso requer acordo comercial.
  • Cada MOU habilita apenas os modelos listados; outros nomes são rejeitados pelo servidor.
  • Se a URL precisar ser rotacionada, enviaremos a nova ao mesmo grupo de contatos.

2. Preparar um conjunto de validação representativo

Os modelos privados são backbones de reconhecimento, não detectores. Cada requisição aceita um único recorte ajustado de rosto e devolve um embedding. Execute primeiro seu detector e envie os recortes um a um.

Dito isso, o servidor também executa uma detecção e alinhamento secundários sobre o retrato enviado antes de extrair o embedding, tolerando pequenas imperfeições de enquadramento.

  • Um rosto por imagem. Se a fonte tiver várias pessoas, salve cada recorte em arquivo separado.
  • Documente consentimento e base legal de cada imagem conforme a cláusula de dados do MOU.

3. Recortar e codificar cada imagem facial

Aplique uma pequena margem ao redor da caixa antes do envio. Um expansion factor por volta de 0,2 (10 % por lado) preserva contexto útil de cabelo, mandíbula e orelha. Opcionalmente limite o lado mais longo (por exemplo 256 px) para reduzir o tamanho.

Envie sempre formatos sem perdas (PNG). JPEG ou WebP de baixa qualidade introduzem artefatos em olhos e boca que reduzem mensuravelmente a qualidade do embedding. Use o helper como ponto de partida e adapte à convenção de caixas do seu detector.

  • Use margem (expansion factor); recorte colado na caixa do detector reduz a precisão.
  • Salve recortes em PNG. Re-codificar para JPEG antes da chamada é a causa mais comum de scores baixos inesperados.
Recortar retrato individual com margem (Python)
import cv2


def crop_face_with_expansion(image, bbox, expansion_factor=0.2, max_side=256):
    """
    Crop a single-person headshot with a small margin around the detected
    face box, and optionally downscale so the longest side is <= max_side.

    image:             input image as a numpy array (BGR or RGB).
    bbox:              face bounding box [x, y, width, height] from your
                       detector of choice (RetinaFace, SCRFD, etc.).
    expansion_factor:  total margin ratio (0.2 means +10% on each side).
    max_side:          if set, the longest side of the result is bounded.
    """
    img_h, img_w = image.shape[:2]
    x, y, w, h = bbox

    # 1. Margin distributed evenly to both sides.
    dw = int(w * expansion_factor / 2)
    dh = int(h * expansion_factor / 2)

    # 2. Expanded box, clamped to image bounds.
    x1 = max(0, x - dw)
    y1 = max(0, y - dh)
    x2 = min(img_w, x + w + dw)
    y2 = min(img_h, y + h + dh)

    face_img = image[y1:y2, x1:x2]

    # 3. Optional bounded downscale with a high-quality filter.
    if max_side is not None:
        curr_h, curr_w = face_img.shape[:2]
        longest = max(curr_h, curr_w)
        if longest > max_side:
            scale = max_side / longest
            new_w = int(curr_w * scale)
            new_h = int(curr_h * scale)
            face_img = cv2.resize(
                face_img, (new_w, new_h), interpolation=cv2.INTER_AREA,
            )

    return face_img


# Save the crop with a lossless format (PNG) before sending it to the API.
# Lossy formats (JPEG, WebP at low quality) introduce compression artifacts
# that can measurably reduce face recognition accuracy.
# cv2.imwrite("probe.png", crop)

4. Chamar a API de extração de features

A API recebe um POST multipart/form-data: um arquivo no campo image e a string model_name. Devolve JSON com model_name e feature (o embedding L2-normalizado). Salve cada embedding como .npy para calcular cosine similarity offline.

O cliente de exemplo abaixo segue exatamente o protocolo de produção. Rode direto ou importe extract_feature em seu pipeline. Passe a URL recebida por e-mail via --server-url; não a coloque hard-coded em scripts que vão para repositórios compartilhados.

  • model_name deve ser um valor listado no MOU; outros são rejeitados pelo servidor.
  • Um feature vazio significa que nenhum rosto foi detectado no recorte – revise caixa e margem.
  • Compare embeddings via cosine similarity em vetores já L2-normalizados; não renormalize no cliente.
Cliente Python mínimo para o endpoint privado
"""Example client for the private InsightFace feature extraction service.

Uploads a single-person face image to the test endpoint, reads the returned
embedding, and saves it locally with np.save for offline evaluation.
"""

import argparse
import os.path as osp

import numpy as np
import requests


def extract_feature(image_path, output_path, url, model_name, timeout=120.0):
    filename = osp.basename(image_path)
    data = {"model_name": model_name}

    with open(image_path, "rb") as infile:
        files = {
            "image": (filename, infile, "application/octet-stream"),
        }
        try:
            resp = requests.post(
                url=url, files=files, data=data, timeout=timeout,
            )
            resp.raise_for_status()
        except requests.RequestException as ex:
            raise SystemExit(
                "request failed: %s: %s" % (type(ex).__name__, str(ex))
            )

    payload = resp.json()
    feature = payload.get("feature")
    if not isinstance(feature, list):
        raise SystemExit("server response feature must be a list")
    if len(feature) == 0:
        raise SystemExit(
            "server returned no features; verify the image contains a "
            "detectable face"
        )

    feat = np.asarray(feature, dtype=np.float32)
    np.save(output_path, feat)
    print("saved feature:", output_path, feat.shape, payload.get("model_name"))
    return feat


def main():
    parser = argparse.ArgumentParser(
        description=(
            "Upload a face image to the private InsightFace test server and "
            "save the embedding with np.save."
        ),
    )
    # The --server-url value is delivered to evaluators by email.
    parser.add_argument(
        "--server-url", required=True,
        help="Feature extraction API URL (sent privately by InsightFace)",
    )
    # The set of choices below is illustrative; the models actually unlocked
    # for your account are listed in your MOU and may evolve over time.
    parser.add_argument(
        "--model-name", required=True,
        choices=["buffalo", "dingo", "eagle"],
        help="Recognition model to evaluate (must match an entry in your MOU)",
    )
    parser.add_argument("--image", required=True, help="Input face image path (PNG recommended)")
    parser.add_argument("--output", required=True, help="Output .npy file path")
    parser.add_argument("--timeout", type=float, default=120.0, help="HTTP timeout in seconds")
    args = parser.parse_args()

    extract_feature(
        args.image, args.output, args.server_url, args.model_name,
        timeout=args.timeout,
    )


if __name__ == "__main__":
    main()

5. Privacidade e tratamento de dados

As imagens enviadas são utilizadas apenas para calcular e devolver o embedding durante a requisição. Não retemos imagens após a resposta e o tráfego de avaliação não é usado para treinar nem ajustar modelos.

  • Não compartilhe URL, nomes de modelo ou scores fora dos contatos do MOU.
  • Reporte vazamentos suspeitos de URL ou credenciais ao seu contato InsightFace em até 24 horas.

6. Escopo da avaliação e próximos passos

A janela gratuita é limitada a duas semanas a partir da entrega da URL. Dentro desse prazo você pode realizar quantas comparações o rate limit permitir; recomendamos fechar antes o conjunto de teste, o pré-processamento e as métricas para dedicar a janela à coleta dos números.

Após o teste, avalie os resultados e compartilhe o quanto antes sua conclusão sobre a cooperação comercial.

Precisa de ajuda com implantação em produção?

Fale com a InsightFace sobre licenciamento de modelos, otimização de runtime e suporte para o hardware alvo.

Entrar em contato