You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Google Teachable Machine模型以识别静态JPG图片而非摄像头流?

关于Google Teachable Machine TensorFlow.js模型识别静态图片的问题及解决建议

我有使用Google Teachable Machine生成的TensorFlow.js模型的需求,原生成代码能正常识别摄像头流,但修改为识别静态JPG图片时,无论用canvas还是img元素,预测结果都完全相同且错误。以下是原标准代码和我尝试的修改代码,求经验或建议:

原标准代码

<button type="button" onclick="init()">Start</button>
<div id="webcam-container"></div>
<div id="label-container"></div>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@latest/dist/teachablemachine-image.min.js"></script>
<script type="text/javascript">
    // the link to your model provided by Teachable Machine export panel
    const URL = "myModel";

    let model, webcam, labelContainer, maxPredictions;

    // Load the image model and setup the webcam
    async function init() {
        const modelURL = URL + "model.json";
        const metadataURL = URL + "metadata.json";

        model = await tmImage.load(modelURL, metadataURL);
        maxPredictions = model.getTotalClasses();

        const flip = true;
        webcam = new tmImage.Webcam(200, 200, flip);
        await webcam.setup();
        await webcam.play();
        window.requestAnimationFrame(loop);

        document.getElementById("webcam-container").appendChild(webcam.canvas);
        labelContainer = document.getElementById("label-container");
        for (let i = 0; i < maxPredictions; i++) {
            labelContainer.appendChild(document.createElement("div"));
        }
    }

    async function loop() {
        webcam.update();
        await predict();
        window.requestAnimationFrame(loop);
    }

    async function predict() {
        const prediction = await model.predict(webcam.canvas);
        for (let i = 0; i < maxPredictions; i++) {
            const classPrediction =
                prediction[i].className + ": " + prediction[i].probability.toFixed(2);
            labelContainer.childNodes[i].innerHTML = classPrediction;
        }
    }
</script>

尝试的修改代码(未成功)

// predict can take in an image, video or canvas html element

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

const image = new Image();
image.onload = function() {
    ctx.drawImage(image, 0, 0);
};
image.src = '1.jpg';

const prediction = await model.predict(canvas); //webcam.canvas
for (let i = 0; i < maxPredictions; i++) {
    const classPrediction =
        prediction[i].className + ": " + prediction[i].probability.toFixed(2);
    labelContainer.childNodes[i].innerHTML = classPrediction;
}

解决建议

核心问题:图片加载时机错误

你的修改代码中,model.predict(canvas)是在图片onload回调外部执行的,此时图片还未加载完成,画布上没有内容,模型预测的是空画布,结果必然错误。必须等待图片完全加载后再执行预测逻辑。

修正方案

方案1:直接使用img元素预测(更简洁)

Teachable Machine的model.predict()支持直接传入img元素,无需转成canvas,只需确保图片加载完成:

// 可在init函数完成后调用此方法
async function predictStaticImage() {
    const image = new Image();
    // 处理跨域问题,本地测试或跨域图片必须设置
    image.crossOrigin = 'anonymous';
    image.onload = async function() {
        const prediction = await model.predict(image);
        for (let i = 0; i < maxPredictions; i++) {
            const classPrediction =
                prediction[i].className + ": " + prediction[i].probability.toFixed(2);
            labelContainer.childNodes[i].innerHTML = classPrediction;
        }
    };
    image.src = '1.jpg';
}

方案2:正确使用canvas预测

如果必须用canvas,需确保图片加载后再执行预测,同时保证canvas尺寸与模型输入一致(原代码中为200x200):

async function predictWithCanvas() {
    const canvas = document.getElementById('myCanvas');
    // 设置canvas尺寸匹配模型输入
    canvas.width = 200;
    canvas.height = 200;
    const ctx = canvas.getContext('2d');

    const image = new Image();
    image.crossOrigin = 'anonymous';
    image.onload = async function() {
        // 将图片绘制到canvas,按模型尺寸缩放
        ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
        const prediction = await model.predict(canvas);
        for (let i = 0; i < maxPredictions; i++) {
            const classPrediction =
                prediction[i].className + ": " + prediction[i].probability.toFixed(2);
            labelContainer.childNodes[i].innerHTML = classPrediction;
        }
    };
    image.src = '1.jpg';
}

额外注意事项

  • 跨域问题:本地测试时,直接打开HTML文件可能无法加载本地图片,建议用本地服务器(如python -m http.server)运行项目。
  • 路径正确性:确保图片路径与HTML文件相对位置正确,或使用绝对路径。
  • 模型输入尺寸:必须保证传入的图片/canvas尺寸与训练时的输入尺寸一致(原代码中为200x200),否则会导致识别偏差。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:53:27