Implementar TensorFlow.js en una extensión de Chrome

En este tutorial, creará e instalará una extensión de Chrome que le permitirá hacer clic derecho en una imagen en una página web y realizar una detección de objetos multiclase en la imagen. La extensión aplica un clasificador MobileNetV2 a la imagen y luego etiqueta la imagen con la clase predicha.

El código de ejemplo está disponible en GitHub .

Requisitos previos

Para completar este tutorial, necesita lo siguiente instalado en su entorno de desarrollo:

Construye la extensión

Obtenga el código fuente y cree la extensión:

  1. Clona o descarga el repositorio tfjs-examples .
  2. Cambie al directorio chrome-extension : cd tfjs-examples/chrome-extension .
  3. Instalar dependencias: yarn .
  4. Ejecute el script de compilación: yarn build .

Después de ejecutar el script de compilación, debería ver los siguientes archivos nuevos:

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

Instalar la extensión

Instale la extensión en Chrome:

  1. En el navegador Chrome, navegue hasta chrome://extensions .
  2. Active el modo Desarrollador usando el interruptor en el lado derecho del navegador.
  3. Seleccione Cargar descomprimido y seleccione el directorio tfjs-examples/chrome-extension/dist . Este directorio contiene el archivo manifest.json y los archivos src/*.js empaquetados por la compilación.

Debería ver una nueva tarjeta para TF.js mobilenet en una extensión de Chrome .

Usa la extensión

Con la extensión instalada, puedes clasificar imágenes en el navegador:

  1. Navegue a un sitio con imágenes. Por ejemplo, navegue hasta google.com , busque "tigres" y seleccione Imágenes en la página de resultados. Deberías ver una página de imágenes de tigres.
  2. Haga clic derecho en una imagen y seleccione Clasificar imagen con TensorFlow.js . Hay un período de calentamiento, por lo que la primera vez que ejecute la aplicación, la inferencia será más lenta. (En sus propias aplicaciones, puede preparar el modelo alimentándolo con datos ficticios).

La extensión ejecuta el modelo en la imagen y luego superpone texto que indica la predicción.

Quitar la extensión

Cuando haya terminado de experimentar con la extensión, puede eliminarla:

  1. En Chrome, navegue hasta chrome://extensions .
  2. En TF.js mobilenet en una tarjeta de extensión de Chrome , seleccione Eliminar y confirme que desea eliminar la extensión.

Cómo funciona la extensión

Esta sección describe cómo funciona la extensión, en un nivel alto.

El archivo de manifiesto , manifest.json , especifica un trabajador de servicio que Chrome ejecutará en segundo plano:

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

El script del trabajador del servicio, service_worker.js , importa el paquete TensorFlow.js y el modelo mobilenet .

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

El script de compilación en package.json utiliza un paquete, Parcel , para agrupar todo de modo que no se carguen scripts externos en tiempo de ejecución.

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

Esto es para cumplir con Chrome Manifest V3, que prohíbe el código alojado de forma remota . Tenga en cuenta que un trabajador de servicio aún puede cargar recursos externos, como los modelos TensorFlow.js.

El script del trabajador del servicio crea un elemento del menú contextual que opera con imágenes. Luego, el script escucha los clics.

/**
 * 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);

Cuando el usuario selecciona el elemento del menú, una devolución de llamada envía un mensaje que contiene el ID de la pestaña actual y la URL de la imagen en la que se hizo clic con el botón derecho. (Tenga en cuenta que en un trabajador de servicio, los objetos DOM no están disponibles).

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);
  });
}

El script de contenido, content.js , escucha los mensajes y maneja la acción IMAGE_CLICKED . El script recibe la URL de la imagen, carga la imagen, la representa en OffscreenCanvas , obtiene los datos de la imagen del lienzo y envía los datos al trabajador del servicio.

Una vez que el trabajador del servicio recibe los datos de la imagen, ejecuta el modelo de red móvil con los datos y obtiene los resultados de la predicción. En la función clickMenuCallback anterior, imageClassifier es una instancia de la clase ImageClassifier , que carga el modelo y obtiene predicciones. Luego, el script del trabajador del servicio envía los resultados al script de contenido para su visualización. Una vez que el script de contenido recibe los resultados, los superpone sobre la imagen original.

El subproceso del trabajador de servicio queda inactivo cuando no se produce ninguna actividad durante aproximadamente 30 segundos. Para obtener más información sobre la gestión de eventos de trabajadores de servicios, consulte la documentación de Chrome .

Que sigue

Este tutorial mostró cómo implementar una extensión de Chrome que usa TensorFlow.js y un modelo MobileNet previamente entrenado para clasificar imágenes. Para obtener más información sobre los modelos previamente entrenados para TensorFlow.js, consulte el repositorio de modelos previamente entrenados .