OpenCV.js 视频入门

从相机捕获视频

OpenCV.js 通过 video 标签对视频进行读取,使用 canvas 对其进行显示,首先应该创建 HTML 标签

  1. 一个video标签直接显示视频
  2. 一个canvas标签用于显示 OpenCV.js 获取的视频
  3. 创建一个捕获错误信息的标签,我使用的 p 标签

HTML 标签内容如下:

 <h2>Video capture example</h2>
    <button id="startAndStop" disabled>Start</button>
    //用于处理错误信息的显示
    <p id="errorMessage"></p>

    <table>
        <tr>
            <td><div><video width="400px" height="300px" id="videoInput"></video></div></td>
            <td><div><canvas width="400px" height="300px" id="canvasOutput"></canvas></div></td>
        </tr>
        <tr>
            <td><div>videoInput</div></td>
            <td><div>canvasOutput</div></td>
        </tr>
    </table>

先创建一个用于捕获 信息的 utils 对象

  // 创建处理错误信息  传入显示错误信息的 标签id
    let utils=new Utils('errorMessage')

OpenCV.js 使用utils 处理视频

  • 开始视频:utils.startCamera()
  • 结束视频:utils.stopCamera()
cv.Mat()

OpenCV.js cv.Mat()对象用于创建目标对象矩阵,类似opencv python中的numpy.array() 创建矩阵

第一个参数也类似于矩阵中的行,但是传递的是目标对象的高(其实就是行)
第二个参数类似矩阵中的列,传递目标对象的宽
第三个参数为类型,在OpenCV.js 的类型格式如下

cv.CV_8UC1、cv.CV_8UC2、cv.CV_8UC3、cv.CV_8UC4…cv.CV_8UCn
分别代表8位1通道、2通道、3通道对象

在网页获取视频是 获取得到的是 RGBA 4通道的内容,即cv.CV_8UC4,如下为创建源目标矩阵对象和,目标矩阵对象,在本例中在canvas中显示灰度图,故类型为cv.CV_8UC1

  // dst 为灰度图 1通道
    let src=new cv.Mat(video.height,video.width,cv.CV_8UC4)
    let dst=new cv.Mat(canvasOutput.height,canvasOutput.width,cv.CV_8UC1)
video example

// 加载完成后处理
function opencvReady(){

     // 定义点击状态
    let clicked=false

    let startAndStop=document.getElementById('startAndStop')
    let video=document.getElementById('videoInput')
    let canvasOutput=document.getElementById('canvasOutput')
    let canvasContext=canvasOutput.getContext('2d')

    // 创建VideoCapture对象
    let camera=new cv.VideoCapture(video)


    // 创建处理错误信息  传入显示错误信息的 标签id
    let utils=new Utils('errorMessage')

     // 移除disabled
 startAndStop.removeAttribute('disabled')
 const fps=30


    function videoProcess(){
    // 每次进入过程需重新创建
   // 创建4通道矩阵 src 为RGBA 4通道  
    // 由于canvas仅支持具有连续存储的8位RGBA图像,因此cv.Mat类型为cv.CV_8UC4
    // dst 为灰度图 1通道
    let src=new cv.Mat(video.height,video.width,cv.CV_8UC4)
    let dst=new cv.Mat(canvasOutput.height,canvasOutput.width,cv.CV_8UC1)
        
    function startProcess(){

        try{
                if(!clicked){
                     src.delete()
                     dst.delete() 
                     return
                }
                        let startTime=Date.now()
                        camera.read(src)
                        // 网页获取的 图像为RGB 格式的
                        cv.cvtColor(src,dst,cv.COLOR_RGBA2GRAY)
                        // cv.Canny(dst,dst,50,120)
                        cv.imshow('canvasOutput',dst)
                        // 1000/fps   为 ms/帧 减去处理时间 为延迟
                        // 如果视频是30fps,延迟毫秒应为(1000/30 - processing_time)。
                        let delay = 1000 / fps - (Date.now() - startTime);
                        setTimeout(startProcess, delay);
                
        }
        catch(err){
            utils.printError(err)
        }

    }
    // 处理第一次
 setTimeout(startProcess,0)
    }
    


    function onVideoStop(){
        startAndStop.innerText='Start'
        clicked=false
        // 清除画布
        canvasContext.clearRect(0,0,canvasOutput.width,canvasOutput.height)
    
    }
    function onVideoStart(){
        
        startAndStop.innerText='Stop'
        clicked=true
        videoProcess()
    }

    // 点击事件
    startAndStop.addEventListener('click',()=>{
        if(!clicked){
            utils.clearError()
            utils.startCamera('qvga',onVideoStart,'videoInput')
        
        }
        else{
                utils.stopCamera()
                onVideoStop()
        }
    })



}
总结

OpenCV.js 总体上还是和 opencv-python 很类似的,尝试了下Canny 边缘检测发现也是可以的,另外一方面就是OpenCV.js 的面向对象感觉比 opencv-python 更强烈。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值