You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用TensorFlow.js的fromPixels()时出现ImageData未定义错误求助

问题分析与解决方案

这个错误的核心原因很明确:ImageData是浏览器环境特有的DOM API,Node.js运行时中并没有这个全局对象。你使用的deeplearn.js(TensorFlow.js的前身)的CPU后端代码里,会检查传入的pixels是否是ImageData实例,但在Node环境下找不到这个构造函数,所以抛出了ReferenceError

下面给你两种可行的解决思路:

方案一:使用TensorFlow.js的Node.js专用版本(推荐)

官方提供了@tensorflow/tfjs-node(CPU版)和@tensorflow/tfjs-node-gpu(GPU加速版),它们专门针对Node.js环境做了优化,支持直接读取本地图片文件,不需要依赖canvas手动处理图片对象。

步骤如下:

  1. 安装依赖:
npm install @tensorflow/tfjs-node @tensorflow/tfjs-knn-classifier

(注:deeplearn-knn-image-classifier是旧版库,现在官方维护的对应库是@tensorflow/tfjs-knn-classifier

  1. 修改你的代码:
#!/usr/bin/node
"use strict";
const {KNNClassifier} = require('@tensorflow/tfjs-knn-classifier');
const tf = require('@tensorflow/tfjs-node');
const fs = require('fs');

const NUM_CLASSES = 3;
const IMAGE_SIZE = 227;
const TOPK = 10;
var filename = 'images.png';

var knn = new KNNClassifier();

// 读取图片文件并解码为张量
fs.readFile(filename, function(err, squid){
  if (err) throw err;
  tf.tidy(() => {
    // 解码PNG图片,得到形状为[height, width, 3]的张量
    const imgTensor = tf.node.decodePng(squid, 3);
    // 调整图片尺寸到模型需要的227x227
    const resizedImg = tf.image.resizeBilinear(imgTensor, [IMAGE_SIZE, IMAGE_SIZE]);
    // 后续可将resizedImg传入KNN分类器进行训练/预测
    // knn.addExample(resizedImg, classId);
  });
});

方案二:基于现有canvas依赖修改代码

如果你想继续使用当前的deeplearncanvas库,需要手动将canvas的Image对象转换为ImageData对象,再传给fromPixels

修改你的代码中读取文件后的部分:

fs.readFile(filename, function(err, squid){
  if (err) throw err;
  var img = new Image();
  img.onload = function() {
    // 创建canvas元素并获取绘图上下文
    const { createCanvas } = require('canvas');
    const canvas = createCanvas(img.width, img.height);
    const ctx = canvas.getContext('2d');
    // 将图片绘制到canvas上
    ctx.drawImage(img, 0, 0);
    // 获取符合要求的ImageData对象
    const imageData = ctx.getImageData(0, 0, img.width, img.height);
    // 现在可以正常传入fromPixels了
    const img1 = _deeplearn.fromPixels(imageData);
    // 后续处理逻辑...
  };
  img.src = squid;
});

这里必须在img.onload回调里处理逻辑,因为图片加载是异步操作,否则可能出现图片未加载完成就尝试获取数据的情况,导致无效数据。


内容的提问来源于stack exchange,提问作者ShuuRi

火山引擎 最新活动