在本教程中,您将构建并安装一个 Chrome 扩展,它允许您右键单击网页中的图像,并在图像上执行多类对象检测。该扩展将 MobileNetV2 分类器应用于图像,然后用预测的类别标记图像。
示例代码可在 GitHub 上获得。
先决条件
要完成本教程,您需要在开发环境中安装以下内容
构建扩展
获取源代码并构建扩展
- 克隆或下载 tfjs-examples 存储库。
- 更改到
chrome-extension
目录:cd tfjs-examples/chrome-extension
。 - 安装依赖项:
yarn
。 - 运行构建脚本:
yarn build
。
运行构建脚本后,您应该看到以下新文件
dist/src/content.js
dist/src/service_worker.js
dist/src/service_worker.js.map
安装扩展
在 Chrome 中安装扩展
- 在 Chrome 浏览器中,导航到
chrome://extensions
。 - 使用浏览器右侧的切换按钮打开 **开发者模式**。
- 选择 **加载解压的** 并选择
tfjs-examples/chrome-extension/dist
目录。此目录包含manifest.json
文件和构建打包的src/*.js
文件。
您应该看到一张名为 **TF.js mobilenet in a Chrome extension** 的新卡片。
使用扩展
安装扩展后,您可以在浏览器中对图像进行分类
- 导航到包含图像的网站。例如,导航到
google.com
,搜索“老虎”,然后在结果页面中选择 **图片**。您应该看到一个老虎图片页面。 - 右键单击图像,然后选择 **使用 TensorFlow.js 对图像进行分类**。有一个预热阶段,因此您第一次运行应用程序时,推理速度会较慢。(在您自己的应用程序中,您可以通过向模型提供虚拟数据来预热模型。)
该扩展在图像上运行模型,然后叠加文本以指示预测。
删除扩展
完成对扩展的实验后,您可以将其删除
- 在 Chrome 中,导航到
chrome://extensions
。 - 在 **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
函数中,imageClassifier
是 ImageClassifier
类的实例,它加载模型并获取预测结果。然后服务工作者脚本将结果发送回内容脚本以供显示。内容脚本接收到结果后,会在原始图像上叠加结果。
当大约 30 秒内没有活动时,服务工作者线程会进入空闲状态。有关管理服务工作者事件的更多信息,请参阅 Chrome 文档。
下一步
本教程展示了如何部署一个使用 TensorFlow.js 和预训练 MobileNet 模型对图像进行分类的 Chrome 扩展程序。要了解有关 TensorFlow.js 预训练模型的更多信息,请参阅 预训练模型存储库。