¡Hola, ciudadanos de Habrovsk! EastBanc Technologies tiene una gran cantidad de proyectos relacionados con el desarrollo móvil. En este sentido, se necesita un zoológico completo de dispositivos para realizar pruebas en todas las etapas. Y, característicamente, una variedad de personas necesita constantemente cada dispositivo, y encontrarlo incluso en un departamento de desarrollo móvil de varias docenas de personas es una historia completa. ¡Sin mencionar que hay probadores, diseñadores, PM, al final!
Y para no perder el teléfono, sino para saber claramente dónde está y con quién, utilizamos una base de datos en línea que reconoce a los empleados por sus caras. Ahora diremos cómo llegamos a esto y cómo lo implementamos.

Contexto histórico
Teníamos un tablero con "tarjetas" de dispositivos con información básica y un lugar para un imán que indicaba a un empleado. Todos notaron acerca de tomar el dispositivo.

Este sistema tiene sus inconvenientes: no es crítico, pero generalmente incómodo:
- Los imanes no son tan fáciles de mover de un lugar a otro.
- Para ver un tablero de este tipo, definitivamente tendrá que ir a otra oficina.
- Y aún así, alguien puede necesitar muchos dispositivos a la vez ... Lo que significa que necesita varios imanes por empleado.
- Ah, sí, incluso los empleados a veces renuncian y aparecen nuevos, en los que también se deben hacer imanes.
Aplicación móvil
En una empresa que se dedica a automatizar procesos comerciales, el uso de la solución "analógica" descrita anteriormente no es muy saludable. Naturalmente, decidimos automatizar la tarea de encontrar el dispositivo adecuado. El primer paso fue escribir una aplicación móvil que pueda determinar e informar su ubicación en las habitaciones a través de puntos de acceso Wi-Fi. En el camino, por conveniencia, le dieron al dispositivo la capacidad de informar al servidor sobre la versión del sistema operativo, y también mostraron una característica tan importante como la carga de la batería.
Parece que el problema está resuelto. Miras la lista en la base de datos donde la última vez que el dispositivo vio Wi-Fi, vas allí y ...
En funcionamiento, resultó que no todo es tan simple. Instalamos la aplicación en dispositivos de prueba y trabajamos con ella durante varios meses. Resultó que esta opción es conveniente, pero tampoco ideal.
Los dispositivos se descargan, simplemente se apagan, los puntos de acceso a Wi-Fi se reorganizan de un lugar a otro, y la geolocalización por sí sola solo dice que el dispositivo está en la oficina. ¡Gracias capitán!
Por supuesto, puede intentar optimizar el sistema existente, pero ¿por qué no reinventarlo en base a las tecnologías del siglo XXI? Apenas dicho que hecho.
Cómo queríamos que fuera
Se nos ocurrió un concepto para un sistema que reconocería a los empleados por sus caras, probaría dispositivos con etiquetas especiales, solicitaría la confirmación de un cambio en el estado del dispositivo y luego realizaría cambios en la base de datos en línea, que cualquier empleado puede ver sin levantarse de su silla.
Reconocimiento facial
El reconocimiento facial en su conjunto resolvió el problema en 2018. Por lo tanto, no reinventamos la rueda e intentamos entrenar nuestros propios modelos, sino que aprovechamos una solución preparada. El módulo
FaceRecognition parecía ser la opción más conveniente, ya que no requiere entrenamiento adicional y funciona muy rápido incluso sin aceleración en la GPU.
Usando la función
face_locations ,
se detectaron caras en las fotos de los empleados, y usando
face_encodings, se extrajeron las características faciales de un empleado en particular.
Los datos recibidos se recopilaron en la base de datos. Para determinar un empleado específico utilizando la función
face_distance , se consideró la "diferencia" entre la codificación del empleado detectado y las codificaciones de la base de datos.
En general, en esta etapa se podría ir más allá y crear un clasificador, por ejemplo, basado en
KNN , de modo que el sistema fuera menos sensible a la dinámica de los rostros de los empleados. Sin embargo, en la práctica esto requiere significativamente más tiempo. Y el promedio banal de la codificación de la cara de una persona entre el que ahora está en la base de datos y el que el sistema descubrió que cambiaba el estado del dispositivo resultó ser suficiente para evitar la acumulación de errores en la práctica.
Código de reconocimiento facialface_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) face_names = [] for face_encoding in face_encodings: matches = face_recognition.face_distance( known_face_encodings, face_encoding) name = "Unknown" if np.min(matches) <= 0.45: best_match_index = np.argmin(matches) name = known_face_info[str(best_match_index)]['name'] else: best_match_index = None
Reconocimiento de dispositivo
Inicialmente, surgió la idea de utilizar
códigos QR para el reconocimiento del dispositivo, en el que se ingresara al mismo tiempo información sobre el dispositivo. Sin embargo, para un reconocimiento estable del código QR, se tuvo que acercar mucho a la cámara, lo cual es inconveniente.
Como resultado, surgió la idea de utilizar marcadores de realidad aumentada. Llevan menos información, pero son mucho más estables y reconocidos. Durante los experimentos, la cámara reconoció un marcador de 30 milímetros con pequeñas desviaciones de la vertical (3-5 grados) a una distancia de hasta dos metros y medio.
Esta opción ya se veía mucho mejor.
ARuco fue elegido de todo el conjunto de
marcadores de realidad aumentada, como Todas las herramientas necesarias para trabajar con ellas están presentes en la
distribución opencv-contrib-python .
Código de reconocimiento de token ARuco self.video_capture = cv2.VideoCapture(0) ret, frame = self.video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) markers = cv2.aruco.detectMarkers(gray, self.dictionary)
Como resultado, a cada dispositivo se le asignó un índice numérico, con el cual se asoció un marcador con este índice.
¿Es una cosa de sombrero?
Parece que hemos aprendido a reconocer dispositivos y caras, el trabajo está hecho. Fanfarria, aplausos! ¿Qué más se puede necesitar?
De hecho, el trabajo apenas comienza. Ahora todos los componentes del sistema deben funcionar de manera estable y rápida "en batalla".
Es necesario optimizar el costo de los recursos del servidor en inactivo, pensar en los casos de los usuarios y comprender cómo debería verse gráficamente.
Interfaz
Quizás el punto más importante en el desarrollo de tales sistemas es la interfaz. Alguien puede discutir, pero el usuario es el elemento central en esta situación.
Lo más rápido posible, puede implementar la parte frontal utilizando
Tkinter .
Algunas notas sobre Tkinter La interfaz consta de tarjetas con información sobre el dispositivo y el usuario que actualmente utiliza este dispositivo. La mayor parte de la pantalla está ocupada por el catálogo de tarjetas, la principal herramienta de contabilidad. En la parte superior hay un filtro con el que puede filtrar el directorio por plataforma o versión del sistema operativo.

Estos son los componentes clave de la interfaz:
- Dispositivo
Las tarjetas del dispositivo se muestran en la pantalla con la versión del sistema operativo, el nombre y la identificación del dispositivo, así como el usuario en el que este dispositivo está registrado actualmente. - Fotofijación
A la derecha está la unidad de control, donde se muestra la imagen de la cámara web, así como los botones para registrar y editar información personal.
Mostramos la imagen para dar retroalimentación al usuario: definitivamente golpeas la pantalla con la etiqueta del dispositivo. - Selección de versión del sistema operativo
Hicimos una lista con la elección de la versión de SO de interés, porque a menudo para las pruebas no necesita un dispositivo específico, sino una versión determinada de Android o iOS. El filtro de versión se hace horizontal para ahorrar espacio y hacer que la lista de versiones sea accesible sin desplazarse, en una pantalla.
Optimización
Una pasada de cualquier componente del sistema no lleva demasiado tiempo. Sin embargo, si comienza a reconocer marcadores y caras al mismo tiempo, entonces un intento de reconocer los 30 cuadros por segundo proporcionados por la cámara conducirá a un agotamiento total de los recursos de la computadora sin una GPU.
Está claro que el 99% del tiempo el sistema hará este trabajo inactivo.
Para evitar esto, se tomaron las siguientes decisiones de optimización:
- Solo cada octavo cuadro se alimenta al procesamiento.
Código if self.lastseen + self.rec_threshold > time.time() or self.frame_number != 8: ret, frame = self.video_capture.read() self.frame_number += 1 if self.frame_number > 8: self.frame_number = 8 return frame, None, None, None
El retraso de respuesta del sistema aumenta a aproximadamente 8/30 segundos, mientras que el tiempo de reacción humano es de aproximadamente un segundo. En consecuencia, dicho retraso aún no será notorio para el usuario. Y ya hemos reducido ocho veces la carga en el sistema. - Primero, se busca el marcador del dispositivo en el marco, y solo cuando se detecta, se inicia el reconocimiento facial. Dado que la búsqueda de marcadores en el cuadro es aproximadamente 300 veces menos costosa que la búsqueda de caras, decidimos que en el modo de espera solo verificaremos la presencia de un marcador.
- Para reducir los "frenos" al buscar caras cuando no hay caras en la imagen, el parámetro number_of_time_to_upsample se deshabilitó en la función face_locations.
face_locations = face_recognition.face_locations (rgb_small_frame, number_of_times_to_upsample = 0)
Debido a esto, el tiempo de procesamiento del marco, en el que no hay caras, fue igual al tiempo de procesamiento del marco, donde las caras se detectan fácilmente.
Cual es el resultado?
Por el momento, el sistema se ha implementado con éxito en MacMini a finales de 2009, que ha llegado a mano, en dos núcleos Core 2 Duo. Como parte de las pruebas, funcionó con bastante éxito incluso en un núcleo virtual con 1024 megabytes de RAM y 4 gigabytes de memoria de solo lectura en el contenedor Docker. MacMini conectó una pantalla táctil para hacer que el aspecto sea minimalista.
Ahora, incluso aquellos usuarios que no usaron el viejo tablero con entusiasmo y sonrieron al registrar dispositivos en sí mismos, ¡y ha habido muchos menos casos de búsquedas infructuosas!
Que sigue
Indudablemente, hay muchos más puntos en el sistema actual que podemos y nos gustaría mejorar:
- Asegúrese de que los controles del sistema operativo no aparezcan cuando aparezcan cuadros de diálogo (ahora se trata de un cuadro de mensaje del paquete Tkinter).
- Cálculos separados y solicitudes del servidor en diferentes subprocesos con procesamiento de interfaz (ahora se realizan en el subproceso principal, mainloop Tkinter, que congela la interfaz al enviar solicitudes a la base de datos en línea).
- Traiga la interfaz al mismo diseño con otros recursos corporativos.
- Cree una interfaz web completa para la visualización remota de datos.
- Use el reconocimiento de voz para confirmar / cancelar acciones y completar los campos de texto.
- Implemente el registro de varios dispositivos simultáneamente.
PD Y así es como funciona.Video grabado en versión beta de la GUI