OpenCV C++从摄像头流录制多段视频 解决输出文件为空问题
代码错误原因与修正方案
错误原因
- 按下
s启动录制的分支中,你定义了局部同名的VideoWriter对象,遮蔽了外层的全局video变量。该局部对象在代码块执行结束后会被自动销毁,后续循环写入帧时调用的是外层已经被释放的空video对象,因此生成的视频文件为空。 - 其他优化点:原代码中提前创建并释放dummy.avi的操作无意义,可直接省略;用字符字面量替代ASCII码可读性更高,增加VideoWriter初始化校验可以快速定位权限、编码不兼容等问题。
修正后完整代码
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; using namespace cv; int main(){ // 初始化摄像头采集对象 VideoCapture cap(0); if(!cap.isOpened()){ cout << "Error opening video stream" << endl; return -1; } // 获取摄像头帧分辨率 int frame_width = cap.get(cv::CAP_PROP_FRAME_WIDTH); int frame_height = cap.get(cv::CAP_PROP_FRAME_HEIGHT); bool recording = false; int videono = 1; // 仅声明VideoWriter对象,后续复用 VideoWriter video; while(1) { Mat frame; cap >> frame; if (frame.empty()) break; imshow( "Frame", frame ); char c = (char)waitKey(1); // ESC键退出程序 if( c == 27 ) break; // s键启动录制 if( c == 's' && !recording) { char path[100]; sprintf(path, "%d.avi", videono); std::cout << "recording started for " << path << "\n"; videono += 1; // 直接给外层video对象初始化,不定义局部同名变量 video.open(path, cv::VideoWriter::fourcc('M','J','P','G'), 10, Size(frame_width,frame_height)); if(!video.isOpened()){ cout << "Failed to create video file: " << path << endl; continue; } recording = true; } if( recording && video.isOpened() ) video.write(frame); // x键结束当前录制 if( c == 'x' && recording) { std::cout << "recording finished.\n"; recording = false; video.release(); } } // 退出前如果仍在录制则主动释放资源 if(recording){ video.release(); } cap.release(); destroyAllWindows(); return 0; }
内容的提问来源于stack exchange,提问作者fisakhan
相关产品推荐
相关产品推荐

