Extensão gratuita para Chrome — recortes no seu dispositivo

Noções básicas de processamento de imagem do Web Worker

Um Web Worker é um contexto de execução JavaScript separado que pode realizar cálculos caros sem fazer com que o thread principal do editor faça todo o trabalho. Para o processamento de imagens do navegador, isso significa que a configuração e a inferência do modelo podem fugir do thread responsável pelos botões, mensagens de progresso, entrada de pincel e atualizações de tela.

O resultado não é “processamento gratuito em segundo plano”. O mesmo dispositivo ainda executa o cálculo e usa memória. O benefício arquitetônico é a separação: uma operação pesada do modelo tem menos probabilidade de bloquear todas as respostas da interface enquanto é executada.

O thread principal tem um trabalho de interface de usuário

Uma página do navegador normalmente executa JavaScript em um thread principal. Esse thread também coordena o layout, a pintura e a entrada. Se um cálculo longo o ocupar, os cliques podem parecer atrasados, a animação pode parar e o navegador pode avisar que a página não está respondendo.

Um editor de imagens tem muitas responsabilidades de thread principal antes mesmo de a inferência começar:

Colocar o trabalho numérico de um modelo de segmentação no mesmo thread faria com que essas tarefas competissem diretamente. Um trabalhador cria um limite mais claro.

O limite baseado em mensagem

O editor e o trabalhador não compartilham variáveis comuns. Eles se comunicam enviando mensagens. Um fluxo simplificado é assim:

  1. O editor cria ou reutiliza um trabalhador.
  2. Ele pede ao trabalhador para inicializar o tempo de execução e o modelo de inferência.
  3. Prepara dados de imagem e envia uma solicitação de inferência.
  4. O trabalhador converte os dados na entrada esperada do modelo.
  5. O trabalhador executa o modelo e produz valores de máscara.
  6. Ele envia de volta a máscara ou os dados do resultado.
  7. O editor compõe a visualização e permite refinamento ou exportação.

As mensagens devem incluir contexto suficiente para corresponder uma resposta à solicitação correta. Isso é importante se um usuário escolher outra imagem antes da conclusão do trabalho anterior. A interface deve evitar exibir um resultado antigo sobre uma nova fonte.

Copiando e transferindo dados de imagem

Enviar uma pequena mensagem de texto é barato. O envio de milhões de valores de pixels pode ser caro se o navegador precisar copiar todo o buffer. Em vez disso, as APIs da Web podem transferir a propriedade de determinados buffers binários. Um buffer transferido fica disponível para o receptor sem reter uma duplicata utilizável no lado do remetente.

Essa otimização vem com uma restrição de design: após a transferência, o remetente não pode continuar usando o mesmo buffer como se ainda fosse o proprietário dos dados. Um editor pode manter uma representação de exibição separada, criar um buffer de inferência dedicado ou reconstruir o que for necessário posteriormente.

Nem toda implementação usa transferência exatamente nos mesmos lugares. A lição geral é que a separação de threads não faz desaparecer a movimentação de dados. As dimensões da imagem, o tamanho do buffer e o número de conversões ainda afetam a latência e a memória.

O que Easy Background Remover coloca no trabalhador

Easy Background Remover usa um Web Worker com um tempo de execução de inferência de navegador para segmentação no dispositivo. A pesada etapa de recorte automático produz uma máscara. O editor então exibe o resultado composto e oferece suporte ao refinamento do pincel CPU-canvas.

Essa separação dá às falhas um limite mais útil. Se o trabalhador não puder inicializar ou travar durante a inferência, a interface poderá relatar um erro relacionado ao trabalhador em vez de depender de uma guia permanentemente congelada como único sinal.

Também mantém a declaração de processamento local compreensível. O envio de pixels de uma página de extensão para seu próprio trabalhador é uma comunicação dentro do ambiente do navegador, não um upload para uma API de recorte remoto. A primeira sessão pode baixar separadamente o ativo do modelo reutilizável; consulte Por que primeiro executar o download de um modelo.

Um trabalhador não torna a computação instantânea

Os trabalhadores melhoram a capacidade de resposta, e não a capacidade bruta do dispositivo. O modelo ainda consome CPU, GPU ou outros recursos de tempo de execução de acordo com o que o navegador pode fornecer. Uma entrada grande ainda pode demorar mais e exigir mais memória do que uma entrada pequena.

Vários limites permanecem:

Iniciar cinco trabalhos de inferência para cinco imagens não é automaticamente cinco vezes mais rápido. Os trabalhadores compartilham a mesma máquina. Trabalhos paralelos podem competir por largura de banda de memória e recursos de execução, enquanto cada instância de modelo pode ter seu próprio custo de memória.

Os relatórios de progresso são cooperativos

Um trabalhador pode enviar mensagens de status, mas não sabe automaticamente qual porcentagem de progresso será precisa. Download do modelo, inicialização do tempo de execução, preparação de entrada, inferência, conversão de máscara e renderização de visualização são fases separadas com tempos diferentes.

Algumas fases têm contagens de bytes mensuráveis. Uma única execução de modelo pode expor apenas “iniciado” e “terminado”. Uma porcentagem suave que avança uniformemente pode, portanto, ser mais cosmética do que uma medição precisa.

A interface de progresso útil nomeia a fase quando possível: preparação do modelo, processamento da imagem ou construção do resultado. Ele também lida com falhas e cancelamentos, em vez de deixar um botão giratório sem explicação.

Cancelar é mais do que esconder um botão giratório

Se o usuário fechar uma imagem ou recomeçar, a interface poderá ignorar a eventual resposta da solicitação desatualizada. Interromper imediatamente a computação subjacente pode exigir suporte adicional do tempo de execução ou encerrar e recriar o trabalhador.

Terminar um trabalhador é decisivo, mas descarta o seu estado inicializado. O próximo trabalho pode precisar carregar e inicializar o modelo novamente. Para uma operação curta, marcar o resultado como obsoleto pode ser mais barato do que destruir tudo.

A escolha correta depende da pressão da memória, da duração da operação e dos recursos de tempo de execução. Da perspectiva do usuário, a regra importante é que o trabalho obsoleto não deve substituir a edição atual.

Erros também precisam ultrapassar os limites

Uma exceção dentro de um trabalhador não se torna uma exceção normal do thread principal. O trabalhador deve relatar erros utilizáveis ​​e o editor deve escutar falhas no nível do trabalhador.

Um bom tratamento de erros distingue pelo menos:

Isso é mais prático do que um genérico “algo deu errado”, especialmente quando a configuração inicial e o processamento normal de imagem têm soluções diferentes.

A saída do trabalhador ainda é apenas uma primeira máscara

A arquitetura de threads não melhora uma vantagem ambígua por si só. O trabalhador pode devolver uma máscara tecnicamente válida que ainda falte pelo, material transparente, alças estreitas ou sombra desejada. Essas são questões de segmentação e intenção.

O trabalho do editor é retomado após a inferência: dimensionar a máscara no sistema de coordenadas de trabalho, compor uma visualização, deixar o usuário refiná-la e exportar o estado atual. Resolução da máscara versus tamanho da visualização explica por que esses sistemas de coordenadas não devem ser confundidos.

Um modelo mental conciso

Pense no trabalhador como um especialista local atrás de uma janela de mensagens:

Para ver os próprios pixels do modelo, continue com O que um modelo recortado no dispositivo vê. Para uma visão geral prática de ponta a ponta, consulte Como funciona a remoção local de plano de fundo.

Continue explorando

Conteúdo interessante