如何基于OpenCV.js实现视频文件/流的推理(替代本地摄像头)
实现方案:用OpenCV.js从视频文件/流媒体URL读取帧并推理
步骤1:HTML页面结构
<!DOCTYPE html> <html> <head> <title>OpenCV.js Video Source</title> <style> .controls { margin: 10px 0; } video, canvas { border: 1px solid #ccc; } </style> </head> <body> <div class="controls"> <!-- 选择本地视频文件 --> <input type="file" id="videoFile" accept="video/*"> <!-- 输入流媒体URL --> <input type="text" id="videoUrl" placeholder="输入流媒体URL"> <button id="loadVideo">加载视频</button> </div> <!-- 隐藏的视频元素,用于后台读取帧 --> <video id="video" autoplay muted playsinline style="display: none;"></video> <!-- 显示处理后的帧 --> <canvas id="outputCanvas"></canvas> <!-- 引入OpenCV.js --> <script async src="https://docs.opencv.org/4.x/opencv.js" onload="onOpenCVReady()" type="text/javascript"></script> <script src="main.js"></script> </body> </html>
步骤2:main.js核心逻辑
let videoCapture; let outputCanvas; let ctx; let videoElement; function onOpenCVReady() { initElements(); setupEventListeners(); } function initElements() { videoElement = document.getElementById('video'); outputCanvas = document.getElementById('outputCanvas'); ctx = outputCanvas.getContext('2d'); } function setupEventListeners() { document.getElementById('loadVideo').addEventListener('click', loadVideoSource); } function loadVideoSource() { const fileInput = document.getElementById('videoFile'); const urlInput = document.getElementById('videoUrl'); // 优先加载本地文件 if (fileInput.files.length > 0) { const file = fileInput.files[0]; videoElement.src = URL.createObjectURL(file); } else if (urlInput.value.trim() !== '') { videoElement.src = urlInput.value.trim(); } else { alert('请选择视频文件或输入流媒体URL'); return; } // 视频元数据加载完成后初始化OpenCV捕获器 videoElement.onloadedmetadata = function() { outputCanvas.width = videoElement.videoWidth; outputCanvas.height = videoElement.videoHeight; // 初始化OpenCV视频捕获器 videoCapture = new cv.VideoCapture(videoElement); // 启动帧处理循环 requestAnimationFrame(processFrame); }; } function processFrame() { if (!videoCapture || videoElement.paused) { requestAnimationFrame(processFrame); return; } // 创建Mat对象存储帧数据 const frame = new cv.Mat(videoElement.videoHeight, videoElement.videoWidth, cv.CV_8UC4); // 读取当前帧 videoCapture.read(frame); // -------------------------- // 在这里添加你的OpenCV推理逻辑 // 示例:将帧转为灰度图 const grayFrame = new cv.Mat(); cv.cvtColor(frame, grayFrame, cv.COLOR_RGBA2GRAY); // 可替换为目标检测、图像分割等自定义逻辑 // -------------------------- // 将处理后的帧绘制到canvas cv.imshow(outputCanvas, grayFrame); // 释放Mat内存,避免内存泄漏 frame.delete(); grayFrame.delete(); // 循环处理下一帧 requestAnimationFrame(processFrame); }
关键说明
- OpenCV加载时机:通过
onload="onOpenCVReady()"确保库加载完成后再初始化,避免未定义错误。 - 视频源适配:同时支持本地文件(通过
URL.createObjectURL生成临时访问地址)和流媒体URL,满足不同场景需求。 - VideoCapture初始化:必须等待视频
loadedmetadata事件触发,此时视频的宽高参数已确定,才能正确创建捕获器。 - 内存管理:每次处理帧后必须调用
delete()释放Mat对象,防止浏览器内存持续增长。 - 推理逻辑集成:在
processFrame的注释区域替换为你的业务代码,比如人脸检测、物体识别等。
内容的提问来源于stack exchange,提问作者tim3in
相关产品推荐
相关产品推荐

