Saltar al contenido principal
Esta página fue traducida automáticamente. Si encuentra errores o tiene sugerencias, contáctenos.

Descripción general

Esta guía cubre dos capacidades de analítica de cámara distintas que es fácil confundir:
  • Reconocimiento facial (identidad) — registra personas conocidas a partir de imágenes de rostros y luego recibe eventos de coincidencia facial cuando una cámara detecta un rostro que coincide. Cada evento incluye una puntuación de confianza y la persona que mejor coincide. Úsalo para reconocer quién aparece en la cámara.
  • Conteo de personas (aforo) — analítica de cámara agregada y no identificante que cuenta cuántas personas cruzan el campo de visión de una cámara a lo largo del tiempo. Proviene del servicio de reportes como series temporales de conteo y conteos de ocupación. No implica identidad alguna.
A través de la API puedes:
  • Registrar y administrar personas creando registros de persona y subiendo imágenes de rostros
  • Consultar eventos de coincidencia facial con filtros enriquecidos y paginación
  • Ajustar el umbral de coincidencia y corregir eventos mal identificados
  • Obtener analíticas de conteo de personas como series temporales o los conteos más recientes por cámara
No es lo mismo que los sensores de ocupación. Rhombus también ofrece sensores de ocupación físicos (hardware Bluetooth/de movimiento) que reportan la presencia en una sala. Esos son un producto aparte servido por una API diferente — consulta la guía de Sensores IoT. El “conteo de personas” de esta página es analítica de cámara.
Privacidad biométrica. El reconocimiento facial procesa datos biométricos. Muchas jurisdicciones regulan la recopilación, el almacenamiento y el uso de identificadores biométricos, y algunas exigen aviso o consentimiento. Revisa las leyes de privacidad biométrica que apliquen a tus ubicaciones antes de registrar rostros y confirma las políticas de tu organización. Esta guía describe únicamente la superficie de la API — no constituye asesoría legal.

Requisitos previos

Antes de comenzar, asegúrate de tener:
  • Una clave de API de Rhombus. Registrar o administrar rostros requiere permisos de administración de rostros; leer los reportes de conteo de personas requiere acceso de lectura de reportes. Genera y limita el alcance de las claves en la consola de Rhombus, en Configuración > API.
  • Al menos una cámara con la analítica correspondiente habilitada (reconocimiento facial para los flujos de identidad, conteo de personas para las analíticas de aforo).
  • El reconocimiento facial es una función licenciada y restringida. Si los endpoints de rostros no están disponibles para tu organización, contacta a tu equipo de cuenta de Rhombus para confirmar la habilitación.
Todas las solicitudes son POST a https://api2.rhombussystems.com y se autentican con los encabezados x-auth-scheme y x-auth-apikey. Las marcas de tiempo están en milisegundos epoch salvo que se indique lo contrario, y la confianza de coincidencia es un decimal entre 0 y 1.

Registrar y administrar personas conocidas

Una persona es un registro de identidad con nombre para el que registras rostros. Un matchmaker es una plantilla de rostro registrada asociada a una persona; el motor de reconocimiento compara los rostros detectados con tus matchmakers.

Crear una persona

Crea un registro de persona con nombre para registrar rostros contra él.
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/person/createPerson",
    headers=headers,
    json={"name": "Jordan Rivera"}
)

person = response.json().get("person", {})
print(f"Created person {person.get('name')} -> {person.get('uuid')}")
name
string
requerido
Nombre visible de la persona.
La respuesta devuelve un objeto person:
uuid
string
Identificador único de la persona.
name
string
Nombre visible.
email
string
Correo electrónico opcional asociado a la persona.
orgUuid
string
Organización a la que pertenece la persona.
createdOn
string
Cuándo se creó el registro de la persona.
updatedOn
string
Cuándo se actualizó por última vez el registro de la persona.

Subir una imagen de rostro

Registra un rostro subiendo una imagen .jpg o .png (máximo 5 MB) como multipart/form-data. El archivo debe enviarse bajo el nombre de campo de formulario file. Dos parámetros de consulta opcionales controlan la transacción:
  • transaction — un ID de transacción que proporcionas para rastrear y luego consultar la subida. Si se omite, el servidor genera uno y lo devuelve.
  • createPersonIfNotFound — establécelo en true para que el sistema cree una persona nueva automáticamente cuando el rostro subido no coincide con uno existente.
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY"
    # NO establezcas Content-Type manualmente; requests define el límite multipart
}

with open("jordan_rivera.jpg", "rb") as f:
    files = {"file": ("jordan_rivera.jpg", f, "image/jpeg")}
    response = requests.post(
        "https://api2.rhombussystems.com/api/faceRecognition/matchmaker/uploadFaceMatchmakers",
        headers=headers,
        params={"transaction": "enroll-jordan-001", "createPersonIfNotFound": "true"},
        files=files
    )

data = response.json()
print(f"Transaction: {data.get('transactionId')}")
for result in data.get("fileUploadResults", []):
    print(f"  {result.get('fileName')}: success={result.get('success')} {result.get('message', '')}")
Sube una imagen por solicitud. Envía exactamente una parte file, mantenla por debajo de 5 MB y usa .jpg o .png. Deja que tu cliente HTTP defina el límite de Content-Type: multipart/form-data — no lo establezcas manualmente.
La respuesta devuelve:
transactionId
string
El ID de transacción de esta subida (devuelto tal cual, o generado si lo omitiste). Úsalo para consultar el estado de procesamiento.
fileUploadResults
array
Resultados de subida por archivo, cada uno con fileName, success (booleano) y message.

Consultar la transacción de subida

Las imágenes de rostros se procesan de forma asíncrona. Consulta la transacción para conocer el faceId resultante y el personUuid al que se registró o vinculó el rostro.
import requests
import time

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

for _ in range(10):
    response = requests.post(
        "https://api2.rhombussystems.com/api/faceRecognition/matchmaker/findFaceUploadMetadataByTransaction",
        headers=headers,
        json={"transactionId": "enroll-jordan-001"}
    )
    metadata = response.json().get("faceUploadMetadata", [])
    if metadata and all(m.get("success") is not None for m in metadata):
        for m in metadata:
            print(f"faceId={m.get('faceId')} personUuid={m.get('personUuid')} "
                  f"success={m.get('success')} {m.get('errorMsg', '')}")
        break
    time.sleep(2)
Cada entrada de faceUploadMetadata incluye:
CampoTipoDescripción
transactionIdstringLa transacción a la que pertenece esta subida
faceIdstringIdentificador del matchmaker de rostro registrado (una vez procesado)
personUuidstringPersona a la que se registró o vinculó el rostro
successbooleanSi el procesamiento tuvo éxito
errorMsgstringDetalle del error cuando success es false
createdAtMillisintegerMarca de tiempo de la subida en milisegundos epoch
origS3KeystringClave de almacenamiento de la imagen original subida
¿Prefieres registrar a una persona a partir de un rostro que la cámara ya capturó? Usa createFaceMatchmakerFromSighting con el faceEventUuid de un evento facial existente y el personUuid de destino para convertir ese avistamiento en una plantilla registrada — sin necesidad de subir nada.

Etiquetar a una persona

Adjunta etiquetas (por ejemplo, employee o visitor) para organizar a las personas y filtrar los eventos faciales más adelante.
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/person/addPersonLabel",
    headers=headers,
    json={"personUuid": "YOUR_PERSON_UUID", "label": "employee"}
)
print(response.json())
Usa removePersonLabel con el mismo cuerpo para quitar una etiqueta, y findPersonLabelsByOrg (cuerpo vacío {}) para obtener un mapa labelsByPerson con las etiquetas de cada persona.

Listar personas y matchmakers

Lista todas las personas registradas con findPeopleByOrg, y lista las plantillas de rostro registradas con findFaceMatchmakersByOrg (o findFaceMatchmakersByPerson para una sola persona).
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

people = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/person/findPeopleByOrg",
    headers=headers, json={}
).json().get("people", [])

for person in people:
    print(f"{person.get('name')} ({person.get('uuid')})")

matchmakers = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/matchmaker/findFaceMatchmakersByOrg",
    headers=headers, json={}
).json().get("faceMatchmakers", [])

for mm in matchmakers:
    print(f"faceId={mm.get('id')} personUuid={mm.get('personUuid')} uploaded={mm.get('uploaded')}")
Cada matchmaker de rostro incluye id (el ID del rostro), personUuid, orgUuid, uploaded (booleano) y createdOn.

Actualizar o eliminar personas y rostros

EndpointCuerpoPropósito
/api/faceRecognition/person/getPerson{ "personUuid": "..." }Obtener una persona
/api/faceRecognition/person/updatePerson{ "personSelectiveUpdate": { "uuid": "...", "name": "..." } }Actualizar nombre/correo (selectivo)
/api/faceRecognition/person/deletePerson{ "personUuid": "..." }Eliminar una persona
/api/faceRecognition/matchmaker/getFaceMatchmaker{ "faceId": "..." }Obtener un rostro registrado
/api/faceRecognition/matchmaker/deleteFaceMatchmaker{ "faceId": "..." }Eliminar una plantilla de rostro registrada
Para administrar la retención y eliminación de datos biométricos, usa deletePerson (elimina la persona y su registro) y deleteFaceMatchmaker (elimina un solo rostro registrado). Los eventos faciales se pueden eliminar individualmente con deleteFaceEvent (más abajo).

Consultar eventos de coincidencia facial

Cuando una cámara detecta un rostro, genera un evento facial. Recupera eventos con findFaceEventsByOrg, que toma un searchFilter y un pageRequest.
import requests
import time

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

now_ms = int(time.time() * 1000)
one_day_ago_ms = now_ms - (24 * 60 * 60 * 1000)

response = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/faceEvent/findFaceEventsByOrg",
    headers=headers,
    json={
        "searchFilter": {
            "hasName": True,
            "timestampFilter": {
                "rangeStart": str(one_day_ago_ms),
                "rangeEnd": str(now_ms)
            }
        },
        "pageRequest": {"maxPageSize": 50}
    }
)

data = response.json()
for event in data.get("faceEvents", []):
    match = event.get("selectedPersonMatch") or {}
    print(f"{event.get('faceName')} on {event.get('deviceUuid')} "
          f"confidence={match.get('confidence')} at {event.get('eventTimestamp')}")

# Obtén la página siguiente si hay lastEvaluatedKey presente
next_key = data.get("lastEvaluatedKey")

Filtro de búsqueda

Todos los campos de searchFilter son opcionales. Cuando se omite timestampFilter, la búsqueda usa por defecto los últimos 7 días.
personUuids
string[]
Filtra por un conjunto de personas.
faceNames
string[]
Filtra por nombres exactos de personas.
faceNameContains
string
Filtra por una subcadena del nombre (mínimo 3 caracteres tras recortar). Tiene precedencia sobre faceNames si ambos están definidos.
labels
string[]
Filtra por etiquetas de persona.
deviceUuids
string[]
Filtra por un conjunto de cámaras.
locationUuids
string[]
Filtra por un conjunto de ubicaciones.
hasName
boolean
Filtra por la presencia (true) o ausencia (false) de un nombre de persona coincidente.
hasEmbedding
boolean
Filtra por la presencia o ausencia de una firma facial.
timestampFilter
object
Ventana temporal con rangeStart y rangeEnd, cada uno una cadena que contiene un valor en milisegundos epoch (inclusive). Por defecto usa los últimos 7 días.

Solicitud de página

maxPageSize
integer
Número máximo de eventos a devolver en una página.
lastEvaluatedKey
string
Cursor de paginación. Pasa el lastEvaluatedKey de la respuesta anterior para obtener la página siguiente. Ausente cuando no hay más resultados.

Interpretar un evento facial

Cada evento en faceEvents es un objeto con estos campos:
uuid
string
Identificador único del evento facial.
eventTimestamp
integer
Cuándo se detectó el rostro, en milisegundos epoch.
faceName
string
Nombre de la persona coincidente. Igual al name de selectedPersonMatch cuando se seleccionó una coincidencia.
personUuid
string
UUID de la persona coincidente, si la hay.
deviceUuid
string
Cámara que generó el evento.
locationUuid
string
Ubicación de la cámara.
detectionConfidence
number
Confianza (0–1) de que la imagen detectada es un rostro.
embeddingConfidence
number
Confianza (0–1) asociada a la firma facial generada.
hasEmbedding
boolean
Si el evento tiene una firma facial.
selectedPersonMatch
object
La coincidencia de persona elegida, con uuid, name, faceId y confidence (0–1). Nula cuando no se seleccionó ninguna coincidencia.
topPersonMatches
array
Las mejores coincidencias candidatas para el rostro, cada una con uuid, name, faceId y confidence (0–1). Útil para revisar coincidencias cercanas.
imageS3Key
string
Clave de almacenamiento de la imagen del evento.
thumbnailS3Key
string
Clave de almacenamiento de la miniatura del evento.
Obtén un solo evento por su UUID con getFaceEvent (cuerpo { "eventUuid": "..." }).

Ajustar la coincidencia y corregir eventos

Leer y actualizar el umbral de coincidencia

El umbral de coincidencia controla qué tan estricta es la coincidencia facial. Es un valor de confianza entre 0 y 1 — un valor más alto exige una coincidencia más cercana (menos falsos positivos, más omisiones); un valor más bajo es más permisivo.
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

# Leer el umbral actual
current = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/matchmaker/getFaceMatchingConfig",
    headers=headers, json={}
).json()
print(f"Current threshold: {current.get('faceMatchConfidenceThreshold')}")

# Subir el umbral para reducir falsos positivos
updated = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/matchmaker/updateFaceMatchingConfig",
    headers=headers,
    json={"faceMatchConfidenceThreshold": 0.8}
).json()
print(f"New threshold: {updated.get('faceMatchConfidenceThreshold')}")
faceMatchConfidenceThreshold
number
Confianza mínima de coincidencia (0–1) requerida para considerar que un rostro detectado es una coincidencia.

Corregir un evento mal identificado

Reasigna un evento facial a la persona correcta (o establece un nombre directamente) con updateFaceEvent. Así corriges coincidencias erróneas.
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/faceRecognition/faceEvent/updateFaceEvent",
    headers=headers,
    json={
        "eventUuid": "YOUR_FACE_EVENT_UUID",
        "personUuid": "CORRECT_PERSON_UUID"
    }
)
print(response.json())
eventUuid
string
requerido
El evento facial a actualizar.
personUuid
string
UUID de la persona correcta a asociar con el evento.
personName
string
Nombre a asociar con el evento. Se ignora si personUuid coincide con una de las mejores coincidencias de persona del evento.
Para eliminar un evento por completo, llama a deleteFaceEvent con { "eventUuid": "..." }.

Analíticas de conteo de personas

El conteo de personas es analítica de cámara agregada — cuenta personas sin identificarlas, servida por el servicio de reportes. Úsalo para tráfico de personas, aforo y paneles de tendencias.

Serie temporal de conteo

getCountReportV2 devuelve una serie temporal de conteos agrupados por intervalo. Para el conteo de personas, establece types en ["PEOPLE"].
import requests
import time

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

now_ms = int(time.time() * 1000)
week_ago_ms = now_ms - (7 * 24 * 60 * 60 * 1000)

response = requests.post(
    "https://api2.rhombussystems.com/api/report/getCountReportV2",
    headers=headers,
    json={
        "startTimeMs": week_ago_ms,
        "endTimeMs": now_ms,
        "interval": "DAILY",
        "scope": "DEVICE",
        "types": ["PEOPLE"],
        "uuid": "YOUR_CAMERA_UUID",
        "timeZone": "America/Los_Angeles"
    }
)

data = response.json()
for point in data.get("timeSeriesDataPoints", []):
    counts = point.get("eventCountMap", {})
    print(f"{point.get('dateLocal')}: {counts.get('PEOPLE', 0)} people")
startTimeMs
integer
requerido
Inicio del rango en milisegundos epoch.
endTimeMs
integer
requerido
Fin del rango en milisegundos epoch.
interval
string
requerido
Tamaño del bucket. Uno de MINUTELY, QUARTERHOURLY, HOURLY, DAILY, WEEKLY, MONTHLY.
scope
string
requerido
Alcance de agregación. Uno de REGION, DEVICE, LOCATION, ORG.
types
string[]
requerido
Tipos de reporte a incluir. Usa ["PEOPLE"] para el conteo de personas.
uuid
string
UUID de destino para el alcance elegido (por ejemplo, un UUID de cámara cuando scope es DEVICE). Omítelo para el alcance ORG.
timeZone
string
Zona horaria IANA usada para agrupar los datos (por ejemplo, America/Los_Angeles).
Cada entrada en timeSeriesDataPoints incluye:
dateUtc
string
Inicio del bucket en UTC.
dateLocal
string
Inicio del bucket en la zona horaria solicitada.
eventCountMap
object
Mapa de tipo de reporte a conteo para el bucket (por ejemplo, { "PEOPLE": 42 }).
reportingDevicesMap
object
Mapa que describe qué dispositivos reportaron en el bucket.
getCountReportV2 admite muchos types además de PEOPLE — consulta la guía de Reportes y analíticas para conocer el modelo completo de reportes, endpoints de analítica adicionales y la exportación CSV.

Conteos de personas más recientes

getMostRecentPeopleCountEvents devuelve los últimos eventos de conteo de personas sin procesar para una cámara — útil para un mosaico de aforo en vivo.
import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/report/getMostRecentPeopleCountEvents",
    headers=headers,
    json={"deviceUuid": "YOUR_CAMERA_UUID", "numMostRecent": 10}
)

for event in response.json().get("events", []):
    print(f"{event.get('eventTimestamp')}: {event.get('peopleCount')} people")
deviceUuid
string
requerido
Cámara de la que leer los conteos de personas.
numMostRecent
integer
requerido
Número de eventos de conteo más recientes a devolver.
Cada evento incluye eventTimestamp (ms epoch), peopleCount, deviceUuid, locationUuid y uuid.

Conteos de ocupación a lo largo del tiempo

getOccupancyCountsV2 devuelve una serie temporal de conteos de ocupación derivados de la cámara para una sola cámara.
import requests
import time

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

now_ms = int(time.time() * 1000)
day_ago_ms = now_ms - (24 * 60 * 60 * 1000)

response = requests.post(
    "https://api2.rhombussystems.com/api/report/getOccupancyCountsV2",
    headers=headers,
    json={
        "deviceUuid": "YOUR_CAMERA_UUID",
        "startTimeMs": day_ago_ms,
        "endTimeMs": now_ms,
        "interval": "HOURLY"
    }
)

for point in response.json().get("timeSeriesDataPoints", []):
    print(f"{point.get('dateLocal')}: {point.get('eventCountMap')}")
deviceUuid
string
requerido
Cámara de la que leer los conteos de ocupación.
startTimeMs
integer
requerido
Inicio del rango en milisegundos epoch.
endTimeMs
integer
requerido
Fin del rango en milisegundos epoch.
interval
string
requerido
Tamaño del bucket (MINUTELY, QUARTERHOURLY, HOURLY, DAILY, WEEKLY, MONTHLY).
Cada punto de datos añade timestampMs y approximateTimestampMsMap a los campos estándar dateUtc, dateLocal, eventCountMap y reportingDevicesMap.
Este reporte de ocupación es derivado de la cámara. Para la presencia en salas medida por sensores de ocupación físicos (Bluetooth/de movimiento), consulta la guía de Sensores IoT — ese es un producto de hardware aparte con su propia API.

Referencia: enums de reportes

EnumValores
Tipo de reporteCROWD, PEOPLE, FACES, MOTION, BANDWIDTH, VEHICLES, LICENSEPLATES, ALERTS, AM_VERIFICATION, DWELL
IntervaloMINUTELY, QUARTERHOURLY, HOURLY, DAILY, WEEKLY, MONTHLY
AlcanceREGION, DEVICE, LOCATION, ORG

Casos de uso

  • Alertas de lista de vigilancia — registra personas de interés y luego consulta findFaceEventsByOrg filtrando por personUuids o labels para marcar avistamientos.
  • Reconciliación de acceso — cruza los eventos faciales con la actividad de control de acceso para confirmar que la persona que usó su credencial coincide con la que vio la cámara.
  • Ciclo de calidad del modelo — revisa topPersonMatches en eventos de baja confianza, corrígelos con updateFaceEvent y ajusta faceMatchConfidenceThreshold para equilibrar falsos positivos y omisiones.
  • Paneles de tráfico de personas — grafica getCountReportV2 con types: ["PEOPLE"] para tendencias de tráfico diarias u horarias por cámara o ubicación.
  • Mosaicos de aforo en vivo — muestra getMostRecentPeopleCountEvents para una pantalla de aforo casi en tiempo real.

Solución de problemas

El reconocimiento facial es una función licenciada y restringida. Confirma que tu organización esté habilitada y que tu clave de API tenga permisos de administración de rostros. Contacta a tu equipo de cuenta de Rhombus si los endpoints no están disponibles.
Envía exactamente un archivo por solicitud bajo el nombre de campo de formulario file, mantenlo por debajo de 5 MB y usa .jpg o .png. Deja que tu cliente HTTP defina el límite multipart de Content-Type — no establezcas Content-Type manualmente.
Las subidas se procesan de forma asíncrona. Consulta la transacción hasta que cada entrada reporte un valor de success. Cuando success es false, lee errorMsg para conocer el motivo.
Si omites timestampFilter, la búsqueda solo cubre los últimos 7 días. Amplía la ventana con rangeStart/rangeEnd (cadenas en milisegundos epoch) y relaja filtros como hasName o personUuids. Recuerda paginar con lastEvaluatedKey.
Ajusta faceMatchConfidenceThreshold con updateFaceMatchingConfig. Súbelo (más cerca de 1) para reducir falsos positivos; bájalo para capturar más coincidencias potenciales. Corrige los errores individuales con updateFaceEvent.

Próximos pasos

Reportes y analíticas

Modelo completo de reportes de conteo, conteos de cruce de umbral y exportación CSV

LPR y vehículos

Detecta y busca placas de matrícula y vehículos en tus cámaras

Sensores IoT

Sensores físicos de ocupación, clima y ambientales

Referencia de la API

Explora y prueba cada endpoint de la API de Rhombus
Última modificación el 8 de julio de 2026