[求助] openCV-aardio库调用不了VideoWriter()
By
mr_mao
at 25 天前 • 0人收藏 • 111人看过
最近有个用电脑摄像头录像的需求,搜了下GitHub,发现了openCV-aardio库,试了下,能控制摄像头,但是录制视频的时候出错,本人不太懂,请大家帮忙看看怎么回事,是不是该库封装的OpenCvSharpExtern.dll有问题?怎么解决这个问题?

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 天前
登录后方可回帖
没研究过