Estensione Chrome gratuita — ritagli sul dispositivo

Basi dell’elaborazione immagini con web worker

I web worker eseguono lavoro pesante fuori dal thread dell’interfaccia. Nell’elaborazione immagini questo significa che il ritaglio può procedere mentre la UI resta reattiva, entro i limiti di memoria e CPU del dispositivo.

Non cambia dove vanno i pixel: cambia come il browser organizza il lavoro in locale.

Il thread principale ha un lavoro di interfaccia utente

Una pagina del browser normalmente esegue JavaScript su un thread principale. Questo thread coordina anche il layout, la pittura e l’input. Se lo occupa un lungo calcolo, i clic potrebbero risultare ritardati, l’animazione potrebbe interrompersi e il browser potrebbe avvisare che la pagina non risponde.

Un editor di immagini ha molte responsabilità sul thread principale prima ancora che inizi l’inferenza:

Mettere il lavoro numerico di un modello di segmentazione sullo stesso thread farebbe sì che tali compiti competano direttamente. Un lavoratore crea un confine più chiaro.

Il confine basato sul messaggio

L’editor e il lavoratore non condividono variabili ordinarie. Comunicano inviando messaggi. Un flusso semplificato è simile al seguente:

  1. L’editor crea o riutilizza un lavoratore.
  2. Chiede al lavoratore di inizializzare il runtime e il modello di inferenza.
  3. Prepara i dati dell’immagine e invia una richiesta di inferenza.
  4. Il lavoratore converte i dati nell’input previsto del modello.
  5. Il lavoratore esegue il modello e produce i valori della maschera.
  6. Restituisce la maschera o i dati dei risultati.
  7. L’editor compone l’anteprima e consente il perfezionamento o l’esportazione.

I messaggi dovrebbero includere un contesto sufficiente per abbinare una risposta alla richiesta corretta. Ciò è importante se un utente sceglie un’altra immagine prima che finisca il lavoro precedente. L’interfaccia deve evitare di visualizzare un vecchio risultato su una nuova fonte.

Copia e trasferimento dei dati dell’immagine

Inviare un piccolo SMS è economico. L’invio di milioni di valori di pixel può essere costoso se il browser deve copiare l’intero buffer. Le API Web possono invece trasferire la proprietà di determinati buffer binari. Un buffer trasferito diventa disponibile per il destinatario senza conservare un duplicato utilizzabile dal lato mittente.

Questa ottimizzazione comporta un vincolo di progettazione: dopo il trasferimento, il mittente non può continuare a utilizzare lo stesso buffer come se fosse ancora proprietario dei dati. Un editor può mantenere una rappresentazione di visualizzazione separata, creare un buffer di inferenza dedicato o ricostruire ciò di cui ha bisogno in seguito.

Non tutte le implementazioni utilizzano il trasferimento esattamente negli stessi posti. La lezione generale è che la separazione dei thread non fa scomparire lo spostamento dei dati. Le dimensioni dell’immagine, la dimensione del buffer e il numero di conversioni influiscono ancora sulla latenza e sulla memoria.

Cosa mette Easy Background Remover nel lavoratore

Easy Background Remover utilizza un Web Worker con un runtime di inferenza del browser per la segmentazione sul dispositivo. La pesante fase di ritaglio automatico produce una maschera. L’editor visualizza quindi il risultato composito e supporta il perfezionamento del pennello CPU-canvas.

Questa separazione fornisce ai fallimenti un confine più utile. Se il lavoratore non riesce a inizializzarsi o si blocca durante l’inferenza, l’interfaccia può segnalare un errore relativo al lavoratore invece di fare affidamento su una scheda permanentemente bloccata come unico segnale.

Inoltre, mantiene comprensibile la richiesta di elaborazione locale. L’invio di pixel da una pagina di estensione al proprio lavoratore è una comunicazione all’interno dell’ambiente del browser, non un caricamento su un’API di ritaglio remota. La prima sessione può scaricare separatamente l’asset modello riutilizzabile; vedere Perché la prima esecuzione scarica un modello.

Un lavoratore non effettua il calcolo istantaneo

I lavoratori migliorano la reattività, non la capacità grezza del dispositivo. Il modello consuma comunque CPU, GPU o altre risorse di runtime in base a ciò che il browser può fornire. Un input di grandi dimensioni può comunque richiedere più tempo e più memoria di uno piccolo.

Rimangono diversi limiti:

Avviare cinque inferenceworker per cinque immagini non è automaticamente cinque volte più veloce. Gli operai condividono la stessa macchina. I lavori paralleli possono competere per la larghezza di banda della memoria e le risorse di esecuzione, mentre ciascuna istanza del modello può comportare il proprio costo di memoria.

Il reporting sui progressi è cooperativo

Un lavoratore può inviare messaggi di stato, ma non sa automaticamente quale percentuale di avanzamento riterrà accurata. Il download del modello, l’inizializzazione del runtime, la preparazione dell’input, l’inferenza, la conversione della maschera e il rendering dell’anteprima sono fasi separate con tempistiche diverse.

Alcune fasi hanno conteggi di byte misurabili. L’esecuzione di un singolo modello può esporre solo “iniziato” e “finito”. Una percentuale uniforme che avanza in modo uniforme può quindi essere estetica piuttosto che una misurazione precisa.

L’utile interfaccia utente di avanzamento nomina la fase quando possibile: preparazione del modello, elaborazione dell’immagine o risultato della costruzione. Gestisce anche il fallimento e la cancellazione invece di lasciare uno spinner senza spiegazione.

La cancellazione è più che nascondere uno spinner

Se l’utente chiude un’immagine o ricomincia, l’interfaccia può ignorare l’eventuale risposta dalla richiesta obsoleta. L’interruzione immediata del calcolo sottostante potrebbe richiedere ulteriore supporto da parte del runtime o la terminazione e la ricreazione del lavoratore.

Terminare un lavoratore è decisivo, ma ne scarta lo stato inizializzato. Il lavoro successivo potrebbe dover caricare e inizializzare nuovamente il modello. Per un’operazione breve, contrassegnare il risultato come obsoleto può essere più economico che abbattere tutto.

La scelta corretta dipende dal carico di memoria, dalla durata dell’operazione e dalle capacità di runtime. Dal punto di vista dell’utente, la regola importante è che il lavoro obsoleto non deve sovrascrivere la modifica corrente.

Anche gli errori devono oltrepassare il limite

Un’eccezione all’interno di un lavoratore non diventa una normale eccezione del thread principale. Il lavoratore deve segnalare errori utilizzabili e l’editor deve ascoltare gli errori a livello di lavoratore.

Una buona gestione degli errori distingue almeno:

Questo è più attuabile di un generico “qualcosa è andato storto”, soprattutto quando la configurazione di prima esecuzione e la normale elaborazione delle immagini hanno rimedi diversi.

L’output dei lavoratori è ancora solo una prima maschera

L’architettura del thread non migliora di per sé un bordo ambiguo. L’operatore può restituire una maschera tecnicamente valida a cui mancano ancora pelliccia, materiale trasparente, spalline strette o un’ombra desiderata. Queste sono domande sulla segmentazione e sull’intento.

Il lavoro dell’editor riprende dopo l’inferenza: ridimensiona la maschera nel sistema di coordinate di lavoro, componi un’anteprima, lascia che l’utente la rifinisca ed esporta lo stato corrente. Risoluzione della maschera e dimensione dell’anteprima spiega perché questi sistemi di coordinate non devono essere confusi.

Un modello mentale conciso

Pensa al lavoratore come a uno specialista locale dietro una finestra di messaggio:

Per la visualizzazione dei pixel stessi da parte del modello, continuare con Cosa vede un modello di ritaglio sul dispositivo. Per una panoramica pratica end-to-end, vedere Come funziona la rimozione dello sfondo locale.

Continua a esplorare

Contenuti interessanti