Conceptos básicos de procesamiento de imagen con Web Worker
Un Web Worker es un contexto de ejecución de JavaScript separado que puede hacer cálculos costosos sin obligar al hilo principal del editor a hacer todo el trabajo. Para el procesamiento de imagen en el navegador, eso significa que la preparación del modelo y la inferencia pueden correr lejos del hilo responsable de botones, progreso, pincel y actualizaciones de pantalla.
El resultado no es “procesamiento de fondo gratis”. El mismo dispositivo sigue haciendo el cálculo y usando memoria. El beneficio arquitectónico es la separación: una operación pesada de modelo es menos probable que bloquee cada respuesta de la interfaz mientras corre.
El hilo principal tiene un trabajo de interfaz de usuario.
Una página de navegador normalmente ejecuta JavaScript en un hilo principal. Ese hilo también coordina el diseño, la pintura y la entrada. Si lo ocupa un cálculo largo, los clics pueden sentirse retrasados, la animación puede detenerse y el navegador puede advertir que la página no responde.
Un editor de imágenes tiene muchas responsabilidades principales incluso antes de que comience la inferencia:
- recibir una selección de archivo, pegarlo o soltarlo;
- decodificar y mostrar una imagen;
- actualizar los estados de progreso y error;
- dibujar el lienzo de vista previa;
- manejar Agregar y Borrar movimiento del pincel;
- preparar acciones de descarga o portapapeles.
Poner el trabajo numérico de un modelo de segmentación en el mismo hilo haría que esas tareas compitieran directamente. Un trabajador crea un límite más claro.
El límite basado en mensajes
El editor y el trabajador no comparten variables ordinarias. Se comunican enviando mensajes. Un flujo simplificado se ve así:
- El editor crea o reutiliza un trabajador.
- Le pide al trabajador que inicialice el tiempo de ejecución y el modelo de inferencia.
- Prepara datos de imagen y envía una solicitud de inferencia.
- El trabajador convierte los datos en la entrada esperada del modelo.
- El trabajador ejecuta el modelo y produce valores de máscara.
- Devuelve la máscara o los datos del resultado.
- El editor compone la vista previa y permite refinarla o exportarla.
Los mensajes deben incluir suficiente contexto para hacer coincidir una respuesta con la solicitud correcta. Esto es importante si un usuario elige otra imagen antes de que finalice el trabajo anterior. La interfaz debe evitar mostrar un resultado antiguo sobre una fuente nueva.
Copiar y transferir datos de imagen
Enviar un pequeño mensaje de texto es barato. Enviar millones de valores de píxeles puede resultar costoso si el navegador tiene que copiar todo el búfer. En su lugar, las API web pueden transferir la propiedad de ciertos buffers binarios. Un búfer transferido queda disponible para el receptor sin retener un duplicado utilizable en el lado del remitente.
Esa optimización viene con una restricción de diseño: después de la transferencia, el remitente no puede seguir usando el mismo búfer como si todavía fuera propietario de los datos. Un editor puede conservar una representación de visualización separada, crear un búfer de inferencia dedicado o reconstruir lo que necesite más adelante.
No todas las implementaciones utilizan la transferencia exactamente en los mismos lugares. La lección general es que la separación de hilos no hace que desaparezca el movimiento de datos. Las dimensiones de la imagen, el tamaño del búfer y la cantidad de conversiones aún afectan la latencia y la memoria.
Lo que Easy Background Remover pone en el trabajador
Easy Background Remover utiliza un Web Worker con un tiempo de ejecución de inferencia del navegador para la segmentación en el dispositivo. El pesado paso de corte automático produce una máscara. Luego, el editor muestra el resultado compuesto y admite el refinamiento del pincel del lienzo de la CPU.
Esta separación les da a las fallas un límite más útil. Si el trabajador no puede inicializarse o falla durante la inferencia, la interfaz puede informar un error relacionado con el trabajador en lugar de depender de una pestaña congelada permanentemente como única señal.
También hace que el reclamo de procesamiento local sea comprensible. Enviar píxeles desde una página de extensión a su propio trabajador es una comunicación dentro del entorno del navegador, no una carga a una API de recorte remoto. La primera sesión puede descargar por separado el activo del modelo reutilizable; consulte Por qué la primera ejecución descarga un modelo.
Un trabajador no hace que el cálculo sea instantáneo.
Los trabajadores mejoran la capacidad de respuesta, no la capacidad bruta del dispositivo. El modelo aún consume CPU, GPU u otros recursos de tiempo de ejecución según lo que pueda proporcionar el navegador. Una entrada grande aún puede tardar más y requerir más memoria que una pequeña.
Quedan varios límites:
- la inicialización del modelo tiene un coste real;
- los buffers de píxeles ocupan memoria en ambos lados si se copian;
- el cambio de tamaño y la conversión de formato llevan tiempo;
- los dispositivos con poca memoria pueden tener problemas con imágenes grandes;
- más trabajadores pueden aumentar la contención en lugar de reducirla;
- Las actualizaciones de exportación y lienzo aún pueden involucrar al hilo principal.
Iniciar cinco trabajadores de inferencia para cinco imágenes no es automáticamente cinco veces más rápido. Los trabajadores comparten la misma máquina. Los trabajos paralelos pueden competir por el ancho de banda de la memoria y los recursos de ejecución, mientras que cada instancia del modelo puede tener su propio costo de memoria.
Los informes de progreso son cooperativos
Un trabajador puede enviar mensajes de estado, pero no sabe automáticamente qué porcentaje de progreso se considerará preciso. La descarga del modelo, la inicialización del tiempo de ejecución, la preparación de la entrada, la inferencia, la conversión de máscara y la representación de vista previa son fases separadas con tiempos diferentes.
Algunas fases tienen recuentos de bytes medibles. La ejecución de un único modelo solo puede exponer “iniciado” y “terminado”. Por lo tanto, un porcentaje suave que avanza uniformemente puede ser más cosmético que una medida precisa.
La interfaz de usuario de progreso útil nombra la fase cuando es posible: preparar el modelo, procesar la imagen o crear el resultado. También maneja fallas y cancelaciones en lugar de dejar una rueda sin explicación.
La cancelación es más que ocultar una ruleta
Si el usuario cierra una imagen o comienza de nuevo, la interfaz puede ignorar la respuesta final de la solicitud desactualizada. Detener el cálculo subyacente inmediatamente puede requerir soporte adicional del tiempo de ejecución o terminar y recrear al trabajador.
Terminar con un trabajador es decisivo, pero descarta su estado inicializado. Es posible que en el siguiente trabajo sea necesario cargar e inicializar el modelo nuevamente. Para una operación corta, marcar el resultado como obsoleto puede resultar más económico que derribarlo todo.
La elección correcta depende de la presión de la memoria, la duración de la operación y las capacidades de tiempo de ejecución. Desde la perspectiva del usuario, la regla importante es que el trabajo obsoleto no debe sobrescribir la edición actual.
Los errores también deben cruzar el límite
Una excepción dentro de un trabajador no se convierte en una excepción normal del hilo principal. El trabajador debe informar errores utilizables y el editor debe estar atento a las fallas a nivel de trabajador.
Un buen manejo de errores distingue al menos:
- activo modelo no disponible;
- la inicialización del modelo falló;
- Falló la decodificación de la imagen o la preparación de la entrada;
- la inferencia falló;
- el trabajador se detuvo inesperadamente;
- el resultado ya no pertenece a la solicitud actual.
Esto es más práctico que un genérico “algo salió mal”, especialmente cuando la configuración inicial y el procesamiento normal de imágenes tienen soluciones diferentes.
La producción de los trabajadores sigue siendo sólo una primera máscara
La arquitectura de subprocesos no mejora una ventaja ambigua por sí sola. El trabajador puede devolver una máscara técnicamente válida a la que todavía le falta piel, material transparente, tirantes estrechos o una sombra deseada. Esas son preguntas de segmentación e intención.
El trabajo del editor se reanuda después de la inferencia: escalar la máscara al sistema de coordenadas de trabajo, componer una vista previa, dejar que el usuario la refine y exportar el estado actual. Resolución de máscara frente a tamaño de vista previa explica por qué no se deben confundir esos sistemas de coordenadas.
Un modelo mental conciso
Piense en el trabajador como un especialista local detrás de una ventana de mensaje:
- el editor es dueño de la interacción;
- el trabajador es dueño de la pesada tarea de inferencia;
- los datos de imágenes binarias cruzan un límite definido;
- el trabajador devuelve una máscara, no un juicio final sobre cada aspecto;
- el editor sigue siendo responsable del estado actual, revisión, refinamiento y exportación.
Para ver la vista del modelo de los píxeles en sí, continúe con Lo que ve un modelo recortado en el dispositivo. Para obtener una descripción práctica integral, consulte Cómo funciona la eliminación de fondo local.