Calcular la distancia de la pantalla a la cara (Android) Ivan Ludvig | Octubre de 2020

Mientras buscaba una forma de detectar la distancia entre la pantalla y la cara en Android, encontré solo un proyecto de código abierto, pero le faltaba alguna explicación y era bastante antiguo y complicado. Lo hice yo mismo.

Papel
Proyecto en GitHub
Un proyecto más avanzado usando este algoritmo

El algoritmo se basa en la distancia entre los ojos. Cuanto más lejos esté tu cara, menor será la distancia entre tus ojos en la cámara.

La fórmula que utilicé es:

El código completo de MainActivity

En lugar de élyUsamos el ancho porque usamos la distancia entre los ojos como un objeto. Explicaré cómo obtener cada uno de los parámetros requeridos.

Conseguir una cámara frontal:

private Camera frontCam() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.e("FAIL", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}

La distancia focal se puede encontrar en CameraParameters:

Camera.Parameters campar = camera.getParameters();
F = campar.getFocalLength();

La distancia entre los ojos representará la altura real en la fórmula. Tomé un valor medio de 63 mm.

El ancho y el alto de la imagen se declararon cuando se inicializó la vista previa de la fuente de la cámara. Variables IMAGE_WIDTH, IMAGE_HEIGHT utilizado para almacenar estos valores.

Las dimensiones del sensor se pueden encontrar en los parámetros de la cámara:

angleX = campar.getHorizontalViewAngle();
angleY = campar.getVerticalViewAngle();
sensorX = (float) (Math.tan(Math.toRadians(angleX/2))*2*F);
sensorY = (float) (Math.tan(Math.toRadians(angleY/2))*2*F);

Clase Face guarda ojos, oídos, etc.en la lista Landmark asignaturas. La lista es accesible llamando getLandmarks(). Luego seleccione los ojos izquierdo y derecho de la lista y guarde sus posiciones.

PointF leftEyePos = face.getLandmarks().get(LEFT_EYE).getPosition();
PointF rightEyePos = face.getLandmarks().get(RIGHT_EYE).getPosition();

Luego calculamos la distancia entre los ojos por separado para cada eje. Estos valores están en unidades abstractas (como píxeles).

float deltaX = Math.abs(leftEyePos.x - rightEyePos.x);
float deltaY = Math.abs(leftEyePos.y - rightEyePos.y);

Luego, la distancia se calcula usando la fórmula principal. Para aumentar la precisión, se calcula utilizando el ancho o la altura, dependiendo del eje a lo largo del cual la diferencia (deltaX, deltaY) es más grande.

if (deltaX >= deltaY) {
distance = F * (AVERAGE_EYE_DISTANCE / sensorX) * (IMAGE_WIDTH / deltaX);
} else {
distance = F * (AVERAGE_EYE_DISTANCE / sensorY) * (IMAGE_HEIGHT / deltaY);
}

¡Y ya está! Gracias por leer.

¡Buena suerte!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *