Distribuisci TensorFlow.js in un'estensione di Chrome

In questo tutorial creerai e installerai un'estensione di Chrome che ti consentirà di fare clic con il pulsante destro del mouse su un'immagine in una pagina Web ed eseguire il rilevamento di oggetti multiclasse sull'immagine. L'estensione applica un classificatore MobileNetV2 all'immagine e quindi etichetta l'immagine con la classe prevista.

Il codice di esempio è disponibile su GitHub .

Prerequisiti

Per completare questo tutorial, è necessario che quanto segue sia installato nel tuo ambiente di sviluppo:

Costruisci l'estensione

Ottieni il codice sorgente e crea l'estensione:

  1. Clona o scarica il repository tfjs-examples .
  2. Passare alla directory chrome-extension : cd tfjs-examples/chrome-extension .
  3. Installa le dipendenze: yarn .
  4. Esegui lo script di build: yarn build .

Dopo aver eseguito lo script di compilazione, dovresti vedere i seguenti nuovi file:

  • dist/src/content.js
  • dist/src/service_worker.js
  • dist/src/service_worker.js.map

Installa l'estensione

Installa l'estensione in Chrome:

  1. Nel browser Chrome, vai a chrome://extensions .
  2. Attiva la modalità sviluppatore utilizzando l'interruttore sul lato destro del browser.
  3. Seleziona Carica unpacked e seleziona la directory tfjs-examples/chrome-extension/dist . Questa directory contiene il file manifest.json e i file src/*.js compressi dalla build.

Dovresti vedere una nuova scheda per la rete mobile TF.js in un'estensione di Chrome .

Utilizza l'estensione

Con l'estensione installata, puoi classificare le immagini nel browser:

  1. Passare a un sito contenente immagini. Ad esempio, vai su google.com , cerca "tigri" e seleziona Immagini nella pagina dei risultati. Dovresti vedere una pagina di immagini di tigri.
  2. Fare clic con il tasto destro su un'immagine e selezionare Classifica immagine con TensorFlow.js . È previsto un periodo di riscaldamento, quindi la prima volta che esegui l'app, l'inferenza sarà più lenta. (Nelle tue applicazioni, puoi innescare il modello fornendogli dati fittizi.)

L'estensione esegue il modello sull'immagine e quindi sovrappone il testo che indica la previsione.

Rimuovere l'estensione

Una volta terminata la sperimentazione con l'estensione, puoi rimuoverla:

  1. In Chrome, vai a chrome://extensions .
  2. Nella rete mobile TF.js in una scheda di estensione Chrome , seleziona Rimuovi e conferma che desideri rimuovere l'estensione.

Come funziona l'estensione

Questa sezione descrive come funziona l'estensione, ad alto livello.

Il file manifest , manifest.json , specifica un serviceworker che Chrome eseguirà in background:

"background": {
   "service_worker": "src/service_worker.js"
},

Lo script del service work, service_worker.js , importa il pacchetto TensorFlow.js e il modello mobilenet .

import * as mobilenet from '@tensorflow-models/mobilenet';
import * as tf from '@tensorflow/tfjs';

Lo script di build in package.json utilizza un bundler, Parcel , per raggruppare tutto insieme in modo che nessuno script esterno venga caricato in fase di runtime.

"build": "parcel build src/service_worker.js --dist-dir dist/src/ && npm run copy",

Ciò è conforme a Chrome Manifest V3, che vieta il codice ospitato in remoto . Tieni presente che un operatore del servizio può comunque caricare risorse esterne, come i modelli TensorFlow.js.

Lo script del lavoratore del servizio crea una voce del menu contestuale che opera sulle immagini. Quindi lo script ascolta i clic.

/**
 * Adds a right-click menu option to trigger classifying the image.
 * The menu option should only appear when right-clicking an image.
 */
chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    id: 'contextMenu0',
    title: 'Classify image with TensorFlow.js ',
    contexts: ['image'],
  });
});

chrome.contextMenus.onClicked.addListener(clickMenuCallback);

Quando l'utente seleziona la voce di menu, una richiamata invia un messaggio contenente l'ID della scheda corrente e l'URL dell'immagine su cui si è fatto clic con il pulsante destro del mouse. (Nota che in un serviceworker gli oggetti DOM non sono disponibili.)

function clickMenuCallback(info, tab) {
  const message = { action: 'IMAGE_CLICKED', url: info.srcUrl };
  chrome.tabs.sendMessage(tab.id, message, (resp) => {
    if (!resp.rawImageData) {
      console.error(
        'Failed to get image data. ' +
        'The image might be too small or failed to load. ' +
        'See console logs for errors.');
      return;
    }
    const imageData = new ImageData(
      Uint8ClampedArray.from(resp.rawImageData), resp.width, resp.height);
    imageClassifier.analyzeImage(imageData, info.srcUrl, tab.id);
  });
}

Lo script del contenuto, content.js , ascolta i messaggi e gestisce l'azione IMAGE_CLICKED . Lo script riceve l'URL dell'immagine, carica l'immagine, esegue il rendering dell'immagine su un OffscreenCanvas , ottiene i dati dell'immagine dall'area di disegno e invia i dati all'operatore del servizio.

Dopo che l'operatore del servizio ha ricevuto i dati dell'immagine, esegue il modello mobilenet con i dati e ottiene i risultati della previsione. Nella funzione clickMenuCallback sopra, imageClassifier è un'istanza della classe ImageClassifier , che carica il modello e ottiene previsioni. Lo script del lavoratore del servizio invia quindi i risultati allo script del contenuto per la visualizzazione. Dopo che lo script del contenuto ha ricevuto i risultati, sovrappone i risultati all'immagine originale.

Il thread di lavoro del servizio diventa inattivo quando non si verifica alcuna attività per circa 30 secondi. Per ulteriori informazioni sulla gestione degli eventi dei lavoratori del servizio, consulta la documentazione di Chrome .

Qual è il prossimo

Questo tutorial ha mostrato come distribuire un'estensione di Chrome che utilizza TensorFlow.js e un modello MobileNet preaddestrato per classificare le immagini. Per ulteriori informazioni sui modelli preaddestrati per TensorFlow.js, consulta il repository dei modelli preaddestrati .