opencv-VideoCapture视频和摄像头读写
读取视频文件
#include<opencv2/opencv.hpp> #include<iostream> int main(int argc, char** argv) { cv::VideoCapture capture("D:/bb/tu/aa.avi"); // 从视频文件读取-方式一 //从文件(.MPG .AVI .mp4)中读取视频 cv::VideoCapture VideoCapture;//方式二--先创建对象 VideoCapture.open("D:/bb/tu/aa.mp4"); if (!VideoCapture.isOpened()) //如果视频打开失败;:成功打开时,isOpened返回ture { std::cout << "Read video Failed !" << std::endl; return 0; } cv::Mat frame; cv::namedWindow("视频"); VideoCapture.read(frame); //读取一帧视频到指定矩阵---方式一
// 读取成功返回 true //VideoCapture >> frame; //读取一帧视频到指定矩阵---方式二 cv::imshow("视频", frame); int frame_num = VideoCapture.get(cv::CAP_PROP_FRAME_COUNT);//返回指定的VideoCapture属性 /* 0- CAP_PROP_POS_MSEC:视频文件的当前位置(毫秒)或视频捕获时间戳 1- CAP_PROP_POS_FRAMES:下一个要解码/捕获的帧的索引,该索引基于0开始的。 2- CAP_PROP_POS_AVI_RATIO:视频文件的相对位置:0-影片开始,1-影片结束。 3- CAP_PROP_FRAME_WIDTH:视频流中帧的宽度。 4- CAP_PROP_FRAME_HEIGHT:视频流中帧的高度。 5- CAP_PROP_FPS:帧速率。 6- CAP_PROP_FOURCC:编解码的4字-字符代码 7- CAP_PROP_FRAME_COUNT:视频文件中的帧数。 8- CAP_PROP_FORMAT:返回对象的格式 9- 返回后端特定的值,该值指示当前捕获模式 10- 图像的亮度(仅适用于照相机) 11 图像的对比度(仅适用于照相机) 12 图像的饱和度(仅适用于照相机) 13 色调图像(仅适用于照相机) 14 图像增益(仅适用于照相机)(Gain在摄影中表示白平衡提升) 15 曝光(仅适用于照相机) 16 指示是否应将图像转换为RGB布尔标志 17 × 暂时不支持 18 立体摄像机的矫正标注(目前只有DC1394 v.2.x后端支持这个功能) */ std::cout << "total frame number is: " << frame_num << std::endl; for (int i = 0; i < frame_num - 1; ++i) { VideoCapture >> frame; cv::imshow("视频",frame); if (cv::waitKey(30) == 'q') { break; } } cv::destroyWindow("视频"); //销毁窗口 VideoCapture.release(); //释放视频对象 cv::waitKey(0); return 0; }
#include<opencv2/opencv.hpp> #include<iostream> int main(int argc, char** argv) { cv::VideoCapture VideoCapture; VideoCapture.open("D:/bb/tu/aa.mp4"); cv::namedWindow("视频", 0); if (!VideoCapture.isOpened()) { std::cout << "读取失败" << std::endl; return 0; } double rate = VideoCapture.get(cv::CAP_PROP_FPS);//获取当前视频帧率 int delay = 1000 / rate; //每一帧之间的延时 bool stop = false; cv::Mat frame; while (!stop) { if (!VideoCapture.read(frame)) { std::cout << "视频结束了" << std::endl; break; } int frame_num = VideoCapture.get(cv::CAP_PROP_POS_FRAMES);//下一个要解码/捕获的帧的索引,该索引基于0开始的 std::cout << "即将播放帧 : " << frame_num << std::endl; if (frame_num == 20) { VideoCapture.set(cv::CAP_PROP_POS_FRAMES, 10);//设置开始帧--移动帧指针到指定位置 //参数1:cv::CAP_PROP_POS_FRAMES 帧为单位 //参数2:cv::CAP_PROP_POS_MSEC ms为单位 } cv::imshow("视频", frame); //引入延时 //也可通过按键停止 if (cv::waitKey(delay) > 0)stop = true; } cv::destroyWindow("视频"); VideoCapture.release(); return 0; }
读取摄像头
//IDE:VS2019 #include<opencv2/opencv.hpp> #include<iostream> #include <vector> int main(int argc, char** argv) { //cv::VideoCapture video(0); //打开摄像头 /* 对于摄像机而言,这个标志符就是一个标志数字——如果只有1个摄像机,那么就是0,如果系统中有多个摄像机,那么只 要将其向上增加即可。标识符另外一部分是摄像机域(camera domain),用于表示摄像机的类型,这个域值可以是下面任一预定义常量 cv::CAP_ANY=0 cv::CAP_MIL=100 cv::CAP_VFW=200 cv::CAP_V4L=200 cv::CAP_V4L2=200 cv::CAP_FIREWIRE=300 cv::CAP_IEEE1394=300 cv::CAP_DC1394=300 cv::CAP_CMU1394=300 cv::CAP_QT=500 cv::CAP_DSHOW=700 cv::CAP_PVAPI=800 cv::CAP_OPENNI=900 cv::CAP_ANDROID=1000 ...... */ cv::VideoCapture video; video.open(0);
//读取视频时可以传入视频路径,而读取摄像头传入的是index索引号
//如果默认笔记本/台式机只有一个USB摄像头,Index=0; 如果有2个,一般Index为0和1,根据具体情况区分,摄像头接入和断开会改变Index值 if (!video.isOpened()) //检测是否正常打开:成功打开时,isOpened返回ture { std::cerr << "打开失败" << std::endl; return -1; } cv::Size videoSize = cv::Size((int)video.get(cv::CAP_PROP_FRAME_WIDTH), (int)video.get(cv::CAP_PROP_FRAME_HEIGHT));//检测视频的大小 std::cerr << videoSize << std::endl; cv::Mat frame; while (1) { video >> frame; imshow("video", frame); if (cv::waitKey(20) > 0) //按下任意键退出摄像头 因电脑环境而异,有的电脑可能会出现一闪而过的情况 break; } cv::waitKey(0); return 0; }
储存视频
#include<opencv2/opencv.hpp> #include<iostream> #include <vector> int main(int argc, char** argv) { cv::VideoCapture video; video.open(0); if (!video.isOpened()) { std::cerr << "打开失败" << std::endl; return -1; } cv::Size videoSize = cv::Size((int)video.get(cv::CAP_PROP_FRAME_WIDTH), (int)video.get(cv::CAP_PROP_FRAME_HEIGHT)); std::cerr << videoSize << std::endl; cv::VideoWriter writer;//创建存储对象 writer.open("D:/bb/tu/output.avi", cv::VideoWriter::fourcc('M', 'P', '4', '2'), 25.0, cv::Size((int)video.get(cv::CAP_PROP_FRAME_WIDTH), (int)video.get(cv::CAP_PROP_FRAME_HEIGHT)), // 视频大小 true); // 是否输出彩色视频 //第一个参数输出视频文件名 //第二个参数指的是视频存放的编码格式 // cv::VideoWriter::fourcc('P', 'I', 'M', '1') = MPEG-1 codec // cv::VideoWriter::fourcc('M', 'J', 'P', 'G') = motion - jpeg codec // cv::VideoWriter::fourcc('M', 'P', '4', '2') = MPEG - 4.2 codec // cv::VideoWriter::fourcc('D', 'I', 'V', '3') = MPEG - 4.3 codec // cv::VideoWriter::fourcc('D', 'I', 'V', 'X') = MPEG - 4 codec // cv::VideoWriter::fourcc('U', '2', '6', '3') = H263 codec // cv::VideoWriter::fourcc('I', '2', '6', '3') = H263I codec // cv::VideoWriter::fourcc('F', 'L', 'V', '1') = FLV1 codec // 在存储视频时采用motion-jpeg codec格式存储的视频最大,其他几种的格式存储的相差不大 //参数3:fps表示每秒的帧数 //参数4:图像的长宽大小 //说明:OpenCV只支持avi的格式,而且生成的视频文件不能大于2GB,而且不能添加音频 if (!writer.isOpened()) //writer打开失败 { std::cerr << "writer打开失败" << std::endl; return -1; } cv::Mat frame; while (1) { video >> frame;//读取一帧到矩阵 writer << frame;//等同于writer.write(frame);写一帧 imshow("video", frame); if (cv::waitKey(10) > 0) break;//给图像绘制留点时间 } video.release(); cv::destroyAllWindows(); cv::waitKey(0); return 0; }