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

OpenCV.js报错cv未定义:图像转二进制功能异常排查

问题排查:OpenCV.js 中 cv 未定义错误

问题现象

实现图像转二进制功能,设置两个Canvas分别显示原始图像和二值化图像。原始图像显示功能正常,但添加二值化代码后控制台报错:

script.js:26 Uncaught ReferenceError: cv is not defined
at file:///***script.js:26:11

原始HTML代码

<p id="status">OpenCV.js is loading...</p>
<div>
  <div class="inputoutput">
    <img id="imageSrc" alt="No Image" />
    <div class="caption">imageSrc <input type="file" id="fileInput" name="file" /></div>
  </div>
  <div class="inputoutput">
    <canvas id="canvasOutput" ></canvas>
    <div class="caption">canvasOutput</div>
  </div>
  
  <div class="inputoutput">
    <canvas id="canvasBinary"></canvas>
    <div class="caption">Binary</div>
  </div>
</div>
<script type="text/javascript" src="scriptOCV.js">
</script>
<script async src="opencv.js" type="text/javascript"></script>

原始JavaScript代码

let imgElement = document.getElementById('imageSrc');
let inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', (e) => {
  imgElement.src = URL.createObjectURL(e.target.files[0]);
}, false);

//read image
imgElement.onload = function () {
  let mat = cv.imread(imgElement);
  cv.imshow('canvasOutput', mat);
  mat.delete();
};

//check openCV
var Module = {
  onRuntimeInitialized() {
    document.getElementById('status').innerHTML = 'OpenCV.js is ready.';
  }
};

//convert img -> binary
let src = cv.imread('canvasOutput');
let dst = new cv.Mat();
cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
cv.adaptiveThreshold(src, dst, 200, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 3, 2);
cv.imshow('canvasBinary', dst);
src.delete();
dst.delete();

问题根源

  1. 异步加载时序问题:OpenCV.js 通过async属性加载,属于异步资源,会在页面其他同步脚本执行完毕后才完成加载。你的二值化代码直接写在全局作用域,会在OpenCV.js还未初始化完成时就执行,此时cv对象尚未定义,触发报错。
  2. 偶发性正常的假象:原图显示的代码(imgElement.onload内的cv调用)看似正常,是因为用户选择文件并加载图片的过程耗时较长,大概率此时OpenCV.js已经加载完成,但这是偶然情况,并非可靠的写法。

修复方案

将所有依赖cv对象的逻辑(包括图像加载、显示、二值化)全部放到Module.onRuntimeInitialized回调函数内,确保只有当OpenCV.js完全加载就绪后才执行这些代码。同时,调整图像加载逻辑,确保每次用户选择新图片时都能重新生成二值图。

修复后的JavaScript代码

var Module = {
  onRuntimeInitialized() {
    document.getElementById('status').innerHTML = 'OpenCV.js is ready.';
    
    let imgElement = document.getElementById('imageSrc');
    let inputElement = document.getElementById('fileInput');
    
    // 处理文件选择事件
    inputElement.addEventListener('change', (e) => {
      imgElement.src = URL.createObjectURL(e.target.files[0]);
    }, false);
    
    // 图像加载完成后执行显示与二值化
    imgElement.onload = function () {
      // 显示原始图像到canvasOutput
      let mat = cv.imread(imgElement);
      cv.imshow('canvasOutput', mat);
      
      // 执行二值化处理
      let src = mat.clone();
      let dst = new cv.Mat();
      cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
      cv.adaptiveThreshold(src, dst, 200, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 3, 2);
      cv.imshow('canvasBinary', dst);
      
      // 释放内存
      mat.delete();
      src.delete();
      dst.delete();
    };
  }
};

额外注意事项

  • OpenCV.js的Mat对象占用内存,使用后务必调用delete()方法释放,避免内存泄漏。
  • 确保Module对象的定义在opencv.js加载脚本之前,这样OpenCV.js才能正确绑定到这个自定义的Module配置上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:25:23