OpenCV.js调用摄像头报错:TypeError: cv.Mat is not a constructor
解决OpenCV.js中「TypeError: cv.Mat is not a constructor」错误及摄像头帧处理问题
错误原因
核心问题是OpenCV.js脚本加载完成后,其WebAssembly运行时还未初始化完成,直接调用cv.Mat会导致API不可用。仅依赖<script>标签的onload事件不够,因为这个事件仅表示脚本文件下载完成,而非OpenCV的运行环境准备就绪。
同时你的代码还有两处逻辑问题:
- 在获取摄像头流之前就创建
Mat对象,此时视频的实际分辨率还未确定(即使设置了height/width属性,媒体流的真实尺寸可能不同) - 直接显示空的
Mat对象,没有从视频中捕获有效帧
修复步骤
1. 等待OpenCV运行时初始化完成
替换<script>标签的onload回调,改用OpenCV提供的cv.onRuntimeInitialized事件,确保所有API可用后再执行业务代码。
2. 调整视频流与帧捕获逻辑
等视频元数据加载完成后再创建匹配尺寸的Mat,并通过循环捕获视频帧、处理后显示到canvas中,实现持续的画面输出。
完整修复代码
<!DOCTYPE html> <html> <head> <title>Learning</title> </head> <body> <video id="input_video" height="480" width="640" autoplay muted playsinline></video> <canvas id="output_video" height="480" width="640"></canvas> <script> function processVideo() { const video = document.getElementById('input_video'); const capture = new cv.VideoCapture(video); function renderFrame() { // 创建与当前视频帧尺寸匹配的Mat const frame = new cv.Mat(video.videoHeight, video.videoWidth, cv.CV_8UC4); // 从视频捕获帧数据 capture.read(frame); // 在这里添加滤镜处理,示例:转为灰度图 // const grayMat = new cv.Mat(); // cv.cvtColor(frame, grayMat, cv.COLOR_RGBA2GRAY); // cv.cvtColor(grayMat, frame, cv.COLOR_GRAY2RGBA); // grayMat.delete(); // 释放内存 // 将处理后的帧显示到canvas cv.imshow('output_video', frame); frame.delete(); // 释放内存 // 循环处理下一帧 requestAnimationFrame(renderFrame); } // 视频元数据加载完成后启动帧处理 video.onloadedmetadata = renderFrame; } // 等待OpenCV运行时完全初始化 function onOpenCVReady() { navigator.mediaDevices.getUserMedia({ video: true, audio: false }) .then(stream => { document.getElementById('input_video').srcObject = stream; processVideo(); }) .catch(err => console.error('摄像头获取失败:', err)); } </script> <script src="https://docs.opencv.org/4.5.5/opencv.js" id="opencvjs" onload="cv.onRuntimeInitialized = onOpenCVReady;"></script> </body> </html>
关键说明
cv.onRuntimeInitialized: OpenCV.js特有的回调,确保WebAssembly环境完全就绪,所有API(包括cv.Mat)可正常调用requestAnimationFrame: 实现流畅的帧循环,保证画面更新频率与浏览器刷新同步- 内存管理: 使用
delete()方法手动释放Mat对象,避免WebAssembly内存泄漏 - 视频属性: 添加
autoplay muted playsinline,适配浏览器自动播放规则,确保视频正常加载
内容的提问来源于stack exchange,提问作者JSVJ
相关产品推荐
相关产品推荐

