[求助] openCV-aardio库调用不了VideoWriter()

By mr_mao at 25 天前 • 0人收藏 • 111人看过

最近有个用电脑摄像头录像的需求,搜了下GitHub,发现了openCV-aardio库,试了下,能控制摄像头,但是录制视频的时候出错,本人不太懂,请大家帮忙看看怎么回事,是不是该库封装的OpenCvSharpExtern.dll有问题?怎么解决这个问题?

image.png

import win.ui;
/*DSG{{*/
var winform = win.form(text="OpenCV-aardio 摄像头控制";right=823;bottom=543;border="dialog frame")
winform.add(
btnClose={cls="button";text="关闭摄像头";left=648;top=72;right=788;bottom=112;disabled=1;z=3};
btnOpen={cls="button";text="打开摄像头";left=648;top=24;right=788;bottom=64;z=2};
btnRecord={cls="button";text="开始录像";left=648;top=256;right=788;bottom=296;disabled=1;z=7};
btnSnap={cls="button";text="截 图";left=648;top=208;right=788;bottom=248;disabled=1;z=6};
chkGray={cls="checkbox";text="灰度 (Gray)";left=656;top=168;right=784;bottom=188;z=5};
chkMirror={cls="checkbox";text="镜像 (Mirror)";left=656;top=136;right=784;bottom=156;z=4};
txtInfo={cls="static";text="准备就绪";left=24;top=512;right=764;bottom=542;transparent=1;z=8};
videoPlus={cls="plus";left=16;top=24;right=616;bottom=504;bgcolor=0xFF000000;db=1;repeat="scale";z=1}
)
/*}}*/

import fsys.dlg;
import cv2; // 引用 OpenCV-aardio 扩展库

// 全局变量
var cap = null;      // 摄像头对象
var writer = null;   // 录像对象
var isRecording = false;

// 核心处理函数:读取并处理每一帧
var processFrame = function(){
    if(!cap) return;
    
    // 1. 读取帧
    var ok, frame = cap.read();
    if(!ok || !frame) return;
    
    // 2. 处理镜像 (左右翻转)
    if(winform.chkMirror.checked){
        frame = cv2.flip(frame, 1);
    }

    // 3. 处理灰度
    if(winform.chkGray.checked){
        frame = cv2.cvtColor(frame, 6/*_CV2_COLOR_BGR2GRAY*/);
    }
    
    // 4. 处理录像
    if(isRecording && writer){
        writer.write(frame);
    }
    
    // 5. 显示在 Plus 控件
    var buf = cv2.imencode(".jpg", frame);
    if(buf) {
        winform.videoPlus.background = buf;
    }
}

var tmrId;  // 定时器 ID

// --- 打开摄像头 ---
winform.btnOpen.oncommand = function(id,event){
    winform.txtInfo.text = "正在打开摄像头...";
    
    // 打开默认摄像头
    cap = cv2.VideoCapture(0);
    
    // 检查是否成功
    if( !cap || !cap.isOpened() ){
        winform.txtInfo.text = "摄像头打开失败";
        win.msgboxErr("无法连接到摄像头,请检查设备。");
        return;
    }
    
    // 设置分辨率 ( opencv-aardio库没有封装cap.set()函数 )
    //cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640);
    //cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480);
    
    winform.txtInfo.text = "摄像头运行中";
    
    // 启用/禁用按钮
    winform.btnOpen.disabled = true;
    winform.btnClose.disabled = false;
    winform.btnSnap.disabled = false;
    winform.btnRecord.disabled = false;
    
    // 启动定时器刷新画面 ( 30帧/秒 )
    tmrId = winform.setInterval(processFrame, 30);
}

// --- 关闭摄像头 ---
winform.btnClose.oncommand = function(id,event){
    // 如果正在录像,强制停止
    if(isRecording) winform.btnRecord.oncommand();

    // 停止定时器
    if(tmrId) winform.clearInterval(tmrId);
    
    // 释放摄像头
    if(cap){
        cap.release();
        cap = null;
    }
    
    winform.videoPlus.background = null; // 清除画面
    winform.videoPlus.backgroundColor = 0xFF000000;
    winform.videoPlus.redrawTransparent()
    winform.txtInfo.text = "摄像头已关闭";
    
    // 恢复按钮状态
    winform.btnOpen.disabled = false;
    winform.btnClose.disabled = true;
    winform.btnSnap.disabled = true;
    winform.btnRecord.disabled = true;
}

// --- 截图 ---
winform.btnSnap.oncommand = function(id,event){
    if(!cap) return;
    
    var path = fsys.dlg.save("*.jpg|*.jpg","保存截图");
    if(path){
        var ok, frame = cap.read();
        
        if( !frame.empty() ){
             if(winform.chkMirror.checked) frame = cv2.flip(frame, 1);
             if(winform.chkGray.checked) frame = cv2.cvtColor(frame, 6/*_CV2_COLOR_BGR2GRAY*/);
             
             // 保存
             cv2.imwrite(path, frame);
             winform.txtInfo.text = "截图保存成功:" + path;
        }
    }
}

// --- 录像 (** 报错:好像是cv2库的问题 **)---
winform.btnRecord.oncommand = function(id,event){
    if(!cap) return;
    
    if(!isRecording){
        // 开始录像
        var path = fsys.dlg.save("*.avi|*.avi","保存录像视频",,winform);
        if(!path) return;
        
        var width  = cap.get(3/*_CV2_CAP_PROP_FRAME_WIDTH*/);
        var height = cap.get(4/*_CV2_CAP_PROP_FRAME_HEIGHT*/);
        var fps    = cap.get(5/*_CV2_CAP_PROP_FPS*/):30;
        
        // 初始化录像对象
        var fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G');  // MJPG 编码兼容性较好
        writer = cv2.VideoWriter(path, fourcc, fps, ::SIZE(width, height), true);
        
        if(writer.isOpened()){
            isRecording = true;
            winform.btnRecord.text = "停止录像";
            winform.txtInfo.text = "正在录像..."; 
        } else {
            win.msgboxErr("无法初始化录像,请检查路径或编码器。");
        }
        
    } else {
        // 停止录像
        isRecording = false;
        if(writer){
            writer.release();
            writer = null;
        }
        winform.btnRecord.text = "开始录像";
        winform.txtInfo.text = "录像已结束";
    }
}

// 窗口关闭事件:确保资源释放
winform.onClose = function(hwnd,message,wParam,lParam){
    if(tmrId) winform.clearInterval(tmrId);
    if(isRecording && writer) writer.release();
    if(cap) cap.release();
}

winform.show();
win.loopMessage();


1 个回复 | 最后更新于 20 天前
20 天前   #1

没研究过

登录后方可回帖

登 录
信息栏
本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...