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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:47:06