← Volver a las guías
Prueba de modelo privadoFace RecognitionEvaluaciónMOUPrivacidad

Cómo realizar una prueba privada de modelo de reconocimiento InsightFace

Guía paso a paso para evaluar los modelos open-source y privados de InsightFace con tus propios datos: requisitos de MOU, preparación de imágenes, cliente Python y controles de privacidad.

8 min de lectura

Qué vas a construir

InsightFace expone sus modelos de reconocimiento open-source y privados mediante una API gestionada de extracción de características, para que los clientes puedan ejecutar una evaluación de precisión sobre sus propios datos antes de firmar un acuerdo comercial.

Esta guía describe el flujo completo: cómo recibir el endpoint, cómo preparar imágenes, cómo llamar al servicio con un cliente Python mínimo, nuestras reglas de privacidad y manejo de datos, y el alcance contractual del periodo de evaluación gratuito.

Antes de empezar

  • Un Memorándum de Entendimiento (MOU) firmado que cubra la intención de cooperación, el periodo de evaluación y el alcance de confidencialidad de los identificadores de modelo que compartimos. La URL del endpoint solo se libera tras la firma.
  • Python 3.9 o superior con numpy, requests y OpenCV (opencv-python).
  • Un conjunto de validación representativo con resultados de detección (cajas de RetinaFace, SCRFD u otro detector).
  • Un conjunto de datos de evaluación claramente definido con etiquetas de verdad y una metodología de evaluación científica.

1. Firmar el MOU y solicitar el acceso

Toda prueba privada arranca con un MOU firmado entre tu organización e InsightFace. Define la intención de cooperación, el periodo de evaluación y el alcance de confidencialidad de los identificadores de modelo que compartimos contigo.

La URL del endpoint, los nombres de modelo habilitados (los modelos open-source o privados autorizados en tu MOU) y los límites de tasa por cuenta se envían por correo al contacto técnico nombrado en el MOU. El endpoint nunca se publica y no debe compartirse fuera de los contactos autorizados.

  • La ventana de evaluación es de hasta dos semanas desde la entrega del endpoint. Cualquier uso adicional requiere acuerdo comercial.
  • Cada MOU habilita solo los modelos listados; otros nombres son rechazados por el servidor.
  • Si la URL debe rotarse (por ejemplo al cerrar la ventana), enviaremos la nueva al mismo grupo de contactos.

2. Preparar un conjunto de validación representativo

Los modelos privados son backbones de reconocimiento, no detectores. Cada solicitud acepta un único recorte ajustado de cara y devuelve un embedding. Ejecuta primero tu detector y envía los recortes uno a uno.

Dicho esto, el servidor también realiza una detección y alineación secundaria sobre el retrato enviado antes de extraer el embedding, por lo que pequeñas imperfecciones de encuadre se toleran.

  • Un rostro por imagen. Si la imagen contiene varias personas, recorta cada una en archivos independientes.
  • Documenta consentimiento y base legal de cada imagen, conforme a la cláusula de datos del MOU.

3. Recortar y codificar cada imagen facial

Aplica un margen pequeño alrededor de la caja antes de enviar. Un expansion factor de aproximadamente 0,2 (10 % por lado) preserva contexto útil de cabello, mandíbula y oreja. Opcionalmente acota el lado más largo (por ejemplo 256 píxeles) para mantener tamaños pequeños.

Envía siempre formatos sin pérdida como PNG. JPEG y WebP de baja calidad introducen artefactos en ojos y boca que reducen de forma medible la calidad del embedding. Usa el helper como punto de partida y ajústalo a la convención de cajas de tu detector.

  • Aplica margen (expansion factor); un recorte pegado a la caja del detector baja la precisión.
  • Guarda los recortes como PNG. Re-codificar a JPEG antes de la llamada es la causa más común de scores inesperadamente bajos.
Recorte de retrato individual con margen (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. Llamar al API de extracción de características

El API acepta un POST multipart/form-data con un único archivo en image y la cadena model_name. Devuelve JSON con model_name y feature (el embedding L2-normalizado). Guarda cada embedding como .npy para calcular cosine similarity offline.

El cliente de ejemplo replica el protocolo productivo. Ejecútalo directo o importa extract_feature en tu pipeline. Pasa por --server-url la URL recibida por correo; no la dejes hardcodeada en scripts del repositorio compartido.

  • model_name debe ser uno de los valores listados en el MOU; otros se rechazan.
  • feature vacío indica que no se detectó rostro en el recorte; revisa caja y margen.
  • Compara embeddings con cosine similarity sobre vectores ya L2-normalizados; no renormalices en cliente.
Cliente Python mínimo para el 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. Privacidad y manejo de datos

Las imágenes subidas se utilizan solo para calcular y devolver el embedding durante la solicitud. No conservamos imágenes tras la respuesta, y el tráfico de evaluación no se usa para entrenar ni ajustar modelos.

  • No compartas URL, nombres de modelo ni scores fuera de los contactos del MOU.
  • Notifica filtraciones sospechosas del endpoint o credenciales a tu contacto InsightFace en menos de 24 horas.

6. Alcance de la evaluación y siguientes pasos

La ventana gratuita está limitada a dos semanas desde la entrega de la URL. Dentro de ese plazo puedes ejecutar todas las comparaciones que tu rate limit permita; te recomendamos cerrar antes el conjunto de prueba, el preprocesado y las métricas, para dedicar la ventana a generar números.

Tras la prueba, evalúa los resultados y comparte cuanto antes tu conclusión sobre la cooperación comercial.

¿Necesitas ayuda con el despliegue en producción?

Contacta con InsightFace para licencias de modelos, optimización de runtime y soporte de despliegue en tu hardware objetivo.

Contactar