Pintar un rectángulo sobre el rostro detectado por la cámara es el paso que conecta la captura de video con el reconocimiento facial real. Aquí se construye la clase LocalFaceGraphic, se configura el Canvas de Android para trabajar con píxeles reales y se dibuja un cuadro que sigue los límites exactos de la cara usando un objeto de machine learning.
¿Por qué convertir density pixels a píxeles reales en Android?
Android utiliza density pixels (dp) para adaptar las interfaces a distintas pantallas, pero el componente Canvas —que es el lienzo donde se dibujan formas— solo entiende píxeles reales. Si se pasan valores en dp directamente, el cuadro se pintaría con un tamaño incorrecto.
Para resolver esto se crea un paquete llamado Utils [01:02] y dentro de él un objeto CommonUtils con una función dp2px (density pixels to pixels). Esta función recibe un contexto y un valor flotante, y retorna el resultado de multiplicar ese valor por la densidad del display obtenida de context.resources.displayMetrics.density, sumándole 0.5f como redondeo. Con esa única línea se garantiza que cualquier medida en dp se traduzca correctamente al Canvas.
¿Cómo se estructura la clase LocalFaceGraphic para reconocer rostros?
Dentro de la carpeta overlay se crea la clase LocalFaceGraphic [01:52]. Su constructor recibe dos parámetros principales:
- Un overlay de tipo
GraphicOverlay, que es la capa visual sobre la cámara.
- Una variable volátil de tipo rostro, vinculada al objeto
MLFace [02:22], el segundo componente de machine learning que determina si lo que ve la cámara es efectivamente una cara.
La clase hereda de BaseGraphic y, al hacerlo, debe implementar obligatoriamente el método draw [02:50], que es donde se ejecuta toda la lógica de dibujo.
¿Qué papel cumple el objeto FacePaint?
Antes de dibujar, se configura un objeto FacePaint de tipo Paint (de android.graphics) [03:08]. En el bloque init se definen tres propiedades clave:
- Color de la línea: se asigna el rojo corporativo de Huawei (
#F4484B) [03:42].
- Estilo Stroke: indica que el rectángulo se pintará solo con bordes, sin relleno [03:58].
- Ancho del trazo (strokeWidth): utiliza la función
dp2px para convertir 1f dp al grosor correcto en píxeles reales [03:22].
¿Cómo se delimitan los bordes del rostro con puntos?
Dentro de la función draw, lo primero es validar: si la cara es nula, se retorna vacío y no se pinta nada [04:18]. Si existe, se obtiene el faceShape de tipo face [04:32]. El faceShape puede representar toda la cara, el ojo izquierdo o el ojo derecho; en este caso se necesita el rostro completo.
Se extraen los face points [04:52] y se declaran cuatro variables de control:
verticalMin y verticalMax para la altura.
horizontalMin y horizontalMax para el ancho.
Estas variables se inicializan con Float.MAX_VALUE o 0f según corresponda [05:08]. Un ciclo for recorre cada punto del rostro [05:28] y, si sus coordenadas X e Y no son nulas, actualiza los valores mínimos y máximos comparando cada coordenada. Así se obtiene el bounding box exacto que encierra la cara sin salirse de sus bordes [05:42].
¿Cómo se dibuja el rectángulo de reconocimiento facial en el Canvas?
Con los límites calculados se construye un Rect (rectángulo) [06:42] cuyos vértices se definen mediante funciones translateX y translateY que convierten las coordenadas del modelo a posiciones reales en pantalla:
- Esquina superior izquierda:
translateX(horizontalMin), translateY(verticalMin).
- Esquina inferior derecha:
translateX(horizontalMax), translateY(verticalMax).
Cada valor se convierte a entero con .toInt() [07:02]. Finalmente, el rectángulo se agrega al Canvas con canvas.drawRect(rect, facePaint) [07:18], y el cuadro rojo aparece rodeando el rostro detectado en tiempo real.
Este flujo completo —conversión de dp a px, configuración del Paint, cálculo dinámico de límites y traslación de coordenadas— es la base sobre la que se construyen funcionalidades más avanzadas como la comparación de rostros o la autenticación biométrica. ¿Ya probaste cambiar el color del cuadro o agregar detección de ojos? Comparte tu experiencia en los comentarios.