在 Chrome 扩展中部署 TensorFlow.js

在本教程中,您将构建并安装一个 Chrome 扩展,它允许您右键单击网页中的图像,并在图像上执行多类对象检测。该扩展将 MobileNetV2 分类器应用于图像,然后用预测的类别标记图像。

示例代码可在 GitHub 上获得。

先决条件

要完成本教程,您需要在开发环境中安装以下内容

构建扩展

获取源代码并构建扩展

  1. 克隆或下载 tfjs-examples 存储库。
  2. 更改到 chrome-extension 目录:cd tfjs-examples/chrome-extension
  3. 安装依赖项:yarn
  4. 运行构建脚本:yarn build

运行构建脚本后,您应该看到以下新文件

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

安装扩展

在 Chrome 中安装扩展

  1. 在 Chrome 浏览器中,导航到 chrome://extensions
  2. 使用浏览器右侧的切换按钮打开 **开发者模式**。
  3. 选择 **加载解压的** 并选择 tfjs-examples/chrome-extension/dist 目录。此目录包含 manifest.json 文件和构建打包的 src/*.js 文件。

您应该看到一张名为 **TF.js mobilenet in a Chrome extension** 的新卡片。

使用扩展

安装扩展后,您可以在浏览器中对图像进行分类

  1. 导航到包含图像的网站。例如,导航到 google.com,搜索“老虎”,然后在结果页面中选择 **图片**。您应该看到一个老虎图片页面。
  2. 右键单击图像,然后选择 **使用 TensorFlow.js 对图像进行分类**。有一个预热阶段,因此您第一次运行应用程序时,推理速度会较慢。(在您自己的应用程序中,您可以通过向模型提供虚拟数据来预热模型。)

该扩展在图像上运行模型,然后叠加文本以指示预测。

删除扩展

完成对扩展的实验后,您可以将其删除

  1. 在 Chrome 中,导航到 chrome://extensions
  2. 在 **TF.js mobilenet in a Chrome extension** 卡片中,选择 **删除** 并确认您要删除扩展。

扩展的工作原理

本节将从较高层次描述扩展的工作原理。

清单 文件,manifest.json,指定了 Chrome 将在后台运行的服务工作线程

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

服务工作线程脚本,service_worker.js,导入 TensorFlow.js 包和 mobilenet 模型

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

package.json 中的构建脚本使用捆绑器,Parcel,将所有内容捆绑在一起,因此在运行时不会加载任何外部脚本。

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

这是为了符合 Chrome 清单 V3,它 禁止远程托管代码。请注意,服务工作线程仍然可以加载外部资源,例如 TensorFlow.js 模型。

服务工作者脚本创建了一个在图像上操作的上下文菜单项。然后脚本监听点击事件。

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

当用户选择菜单项时,回调会发送一条包含当前标签 ID 和右键单击图像 URL 的消息。(请注意,在服务工作者中,DOM 对象不可用。)

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

内容脚本,content.js,监听消息并处理 IMAGE_CLICKED 操作。脚本接收图像 URL,加载图像,在 OffscreenCanvas 上渲染图像,从画布获取图像数据,并将数据发送回服务工作者。

服务工作者接收到图像数据后,使用数据运行 mobilenet 模型并获取预测结果。在上面的 clickMenuCallback 函数中,imageClassifierImageClassifier 类的实例,它加载模型并获取预测结果。然后服务工作者脚本将结果发送回内容脚本以供显示。内容脚本接收到结果后,会在原始图像上叠加结果。

当大约 30 秒内没有活动时,服务工作者线程会进入空闲状态。有关管理服务工作者事件的更多信息,请参阅 Chrome 文档

下一步

本教程展示了如何部署一个使用 TensorFlow.js 和预训练 MobileNet 模型对图像进行分类的 Chrome 扩展程序。要了解有关 TensorFlow.js 预训练模型的更多信息,请参阅 预训练模型存储库