zoukankan      html  css  js  c++  java
  • OpenCV-Utils学习日志:VideoWriter使用样例

    1.VideoWriter可将数据流保存为指定格式的视频或图像序列:

             (1)录制为视频数据,需要指定视频的完整路径,如/root/data/vtest.avi;同时需要指定fourcc、帧率、图像尺寸及是否保存为彩色,fourcc值参见OpenCV官网指定的链接。

             (2)保存为图像序列,需要指定图像序列的完整路径,其中路径中的文件名的格式同C言语中prinf的格式,可参见《CV学习日志:C语言中文件IO使用要点》。如/root/data/ima%d.png;如/root/data/ima%03d.png,这里%03d表示图像名序列号是整数、占宽三位、不足三位的高位是零填充。同时,需要设置fourcc或帧率为0。

    2.VideoWriter常用的函数是构造和write

             (1)构造函数:用于创建数据流。

             (2)write函数:写一帧数据流。

    3.AboutVideoIOVideoCaptureVideoWriter的综合使用样例,其功能如下:

             (1)打开数据流功能:可打开相机、视频或图像序列,相机指定设备号、视频和图像序列指定完整路径。

             (2)保存数据流功能:按空格保存图像到给定的目录或默认的workDir/data,图像名是时间戳,单位纳秒。

             (3)帧显示时间设置功能:默认每帧显示30毫秒,可指定为期望显示的时间,其中设为零表示一直显示直到按下任意键。

             (4)帧高度宽度设置功能:对于相机数据流,可指定相机支持的尺寸,否则为相机默认的输出尺寸。

             (5)录制数据流功能:按1开始或继续录制图像到给定的目录或默认的workDir/data,按2暂停录制。

             (6)录制时帧率设置功能:当帧率设置为0时,录制为图像序列videoio*.png,否则录制为视频videoio.avi。

             (7)录制时编码设置功能:即VideoWriter::fourcc码,当帧率设置为0时,此设置无效,内部自动置为0。

             (8)录制时色彩设置功能:当设置为0时录制为灰度流,否则录制为彩色流,默认录制为彩色流。

             (9)自动生成配置文件功能:首次运行或配置文件不存在将自动生成workDir/videoio.yml,然后修改配置项为期望值后重启。

             可在https://github.com/opencv/opencv/tree/master/samples/data下载vtest.avi和left*.jpg测试视频流和图像序列。

             也可参见关于VedioCapture的使用样例《OpenCV-Utils学习日志:VideoCapture使用样例

             以下是详细代码,依赖于C++14、OpenCV4.x和Spdlog。

      1 #include <opencv2/opencv.hpp>
      2 #include <opencv2/core/utils/filesystem.hpp>
      3 #include <spdlog/spdlog.h>
      4 using namespace std;
      5 using namespace cv;
      6 
      7 #ifndef StrPairKey
      8 #define StrPairKey(key) make_pair(#key, key)
      9 #define StrPairVal(val) make_pair(val, #val)
     10 #endif
     11 
     12 class AboutVideoIO
     13 {
     14 public:
     15     map<int, pair<int, string>> capProps =
     16     {
     17         make_pair(0, StrPairVal(CAP_PROP_POS_MSEC)),
     18         make_pair(1, StrPairVal(CAP_PROP_POS_FRAMES)),
     19         make_pair(2, StrPairVal(CAP_PROP_FRAME_COUNT)),
     20         make_pair(3, StrPairVal(CAP_PROP_POS_AVI_RATIO)),
     21 
     22         make_pair(4, StrPairVal(CAP_PROP_FRAME_WIDTH)),
     23         make_pair(5, StrPairVal(CAP_PROP_FRAME_HEIGHT)),
     24         make_pair(6, StrPairVal(CAP_PROP_FPS)),
     25         make_pair(7, StrPairVal(CAP_PROP_FOURCC)),
     26         make_pair(8, StrPairVal(CAP_PROP_FORMAT)),
     27         make_pair(9, StrPairVal(CAP_PROP_MODE)),
     28 
     29         make_pair(10, StrPairVal(CAP_PROP_BRIGHTNESS)),
     30         make_pair(11, StrPairVal(CAP_PROP_HUE)),
     31         make_pair(12, StrPairVal(CAP_PROP_SATURATION)),
     32         make_pair(13, StrPairVal(CAP_PROP_CONTRAST)),
     33         make_pair(14, StrPairVal(CAP_PROP_GAIN)),
     34         make_pair(15, StrPairVal(CAP_PROP_EXPOSURE))
     35     };
     36 
     37 public:
     38     struct VideoIO
     39     {
     40         char imaFrom[512] = "0";
     41         char saveDir[512] = "./data";
     42         int waitTime = 30;
     43         int deviceRows = 0;
     44         int deviceCols = 0;
     45         int writeFPS = 24;
     46         char writeFourcc[8] = "DX50";
     47         bool writeColor = true;
     48         void write(FileStorage& fs)
     49         {
     50             fs << "imaFrom" << imaFrom; fs.writeComment("deviceId like"0" or videoPath like"/root/data/vtest.avi" or imaListPath like"/root/data/left%03d.jpg)"", true);
     51             fs << "saveDir" << saveDir; fs.writeComment("auto created if not existing", true);
     52             fs << "waitTime" << waitTime; fs.writeComment("0-wait for pressing any key", true);
     53             fs << "deviceRows" << deviceRows; fs.writeComment("0-auto size", true);
     54             fs << "deviceCols" << deviceCols; fs.writeComment("0-auto size", true);
     55             fs << "writeFPS" << writeFPS; fs.writeComment("0-save as videoio*.png or else videoio.avi", true);
     56             fs << "writeFourcc" << writeFourcc;
     57             fs << "writeColor" << writeColor;
     58         }
     59         void read(FileStorage& fs)
     60         {
     61             strcpy(imaFrom, fs["imaFrom"].string().c_str());
     62             strcpy(saveDir, fs["saveDir"].string().c_str());
     63             fs["waitTime"] >> waitTime;
     64             fs["deviceRows"] >> deviceRows;
     65             fs["deviceCols"] >> deviceCols;
     66             fs["writeFPS"] >> writeFPS;
     67             strcpy(writeFourcc, fs["writeFourcc"].string().c_str());
     68             fs["writeColor"] >> writeColor;
     69         }
     70         string print(string savePath = "")
     71         {
     72             string str;
     73             str += fmt::format("imaFrom: {}
    ", imaFrom);
     74             str += fmt::format("saveDir: {}
    ", saveDir);
     75             str += fmt::format("waitTime: {}
    ", waitTime);
     76             str += fmt::format("deviceRows: {}
    ", deviceRows);
     77             str += fmt::format("deviceCols: {}
    ", deviceCols);
     78             str += fmt::format("writeFPS: {}
    ", writeFPS);
     79             str += fmt::format("writeFourcc: {}
    ", writeFourcc);
     80             str += fmt::format("writeColor: {}
    ", writeColor);
     81             if (savePath.empty() == false) { FILE* out = fopen(savePath.c_str(), "w"); fprintf(out, str.c_str()); fclose(out); }
     82             return str;
     83         }
     84         static VideoIO GetOne(string fsPath, bool doPrint = true)
     85         {
     86             VideoIO videoIO;
     87             if (cv::utils::fs::exists(fsPath) == false)
     88             {
     89                 cv::utils::fs::createDirectories(getFilePathInfo(fsPath));
     90                 FileStorage fs(fsPath, FileStorage::WRITE);
     91                 videoIO.write(fs);
     92                 fs.release();
     93                 //memset(&videoIO, 0, sizeof(videoIO));
     94                 spdlog::critical("No exist: {}", fsPath);
     95                 spdlog::info("Created file: {}", fsPath);
     96                 spdlog::info("Modify default values and relaunch");
     97             }
     98             else
     99             {
    100                 FileStorage fs(fsPath, FileStorage::READ);
    101                 videoIO.read(fs);
    102                 fs.release();
    103             }
    104             if (doPrint) spdlog::info(videoIO.print());
    105             return videoIO;
    106         }
    107         static string getFilePathInfo(string path, int mode = 0/*0=dir 1=basename 2=extname 3=dirbasename 4=filename*/)
    108         {
    109             int ind1 = (int)path.find_last_of('/');
    110             int ind2 = (int)path.find_last_of('.');
    111             if (mode == 0) return path.substr(0, ind1);
    112             else if (mode == 1) return path.substr(ind1 + 1, ind2 - ind1 - 1);
    113             else if (mode == 2) return path.substr(ind2 + 1);
    114             else if (mode == 3) return path.substr(0, ind2);
    115             else return path.substr(ind1 + 1);
    116         }
    117     };
    118 
    119 public:
    120     void TestMe(int argc = 0, char** argv = 0)
    121     {
    122         //0.GetParams
    123         string videoioCfgPath = "./videoio.yml";
    124         VideoIO videoIO = VideoIO::GetOne(videoioCfgPath);
    125 
    126         //1.CreatDirectory
    127         utils::fs::createDirectories(videoIO.saveDir);
    128         spdlog::set_pattern("%v"); spdlog::info(videoIO.print());
    129 
    130         //2.OpenStream
    131         VideoCapture cap;
    132         if (std::strlen(videoIO.imaFrom) == 1)
    133             if (cap.open(atoi(videoIO.imaFrom)) == false) { spdlog::critical("Failed to open device: {}", videoIO.imaFrom); return; }
    134         if (std::strlen(videoIO.imaFrom) > 1)
    135             if (cap.open(videoIO.imaFrom) == false) { spdlog::critical("Failed to open file: {}", videoIO.imaFrom); return; }
    136 
    137         //3.SetDevice
    138         if (videoIO.deviceRows != 0) cap.set(CAP_PROP_FRAME_HEIGHT, videoIO.deviceRows);
    139         if (videoIO.deviceCols != 0) cap.set(CAP_PROP_FRAME_WIDTH, videoIO.deviceCols);
    140 
    141         //4.GetDevice
    142         spdlog::info("cap.isOpened(): {}", cap.isOpened());
    143         spdlog::info("cap.getBackendName(): ", cap.getBackendName());
    144         for (map<int, pair<int, string>>::iterator it = capProps.begin(); it != capProps.end(); ++it)
    145             spdlog::info("cap.get({}): {}", it->second.second, cap.get(it->second.first));
    146 
    147         //5.CreatStream
    148         string path = fmt::format("{}/{}", videoIO.saveDir, videoIO.writeFPS == 0 ? "videoid%04d.png" : "videoio.avi");
    149         int fourcc = videoIO.writeFPS == 0 ? 0 : VideoWriter::fourcc(videoIO.writeFourcc[0], videoIO.writeFourcc[1], videoIO.writeFourcc[2], videoIO.writeFourcc[3]);
    150         VideoWriter wrt(path, fourcc, videoIO.writeFPS, Size((int)cap.get(CAP_PROP_FRAME_WIDTH), (int)cap.get(CAP_PROP_FRAME_HEIGHT)), videoIO.writeColor);
    151         spdlog::info("wrt.isOpened(): {}", wrt.isOpened());
    152         spdlog::info("wrt.getBackendName(): ", wrt.getBackendName());
    153         spdlog::info("wrt.get(VIDEOWRITER_PROP_QUALITY): {}", wrt.get(VIDEOWRITER_PROP_QUALITY));
    154         spdlog::info("wrt.get(VIDEOWRITER_PROP_FRAMEBYTES): {}", wrt.get(VIDEOWRITER_PROP_FRAMEBYTES));
    155         spdlog::info("wrt.get(VIDEOWRITER_PROP_NSTRIPES): {}", wrt.get(VIDEOWRITER_PROP_NSTRIPES));
    156         spdlog::info("wrt.get(VIDEOWRITER_PROP_IS_COLOR ): {}", wrt.get(VIDEOWRITER_PROP_IS_COLOR));
    157 
    158         //6.ReadWriteStream
    159         cv::namedWindow(__FUNCTION__, WINDOW_NORMAL);
    160         spdlog::info("Press space to save one and q/Q to exit");
    161         spdlog::info("press 1 to start/continue and 2 to stop recording");
    162         Mat frame; int flag = 0;
    163         while (cap.read(frame))
    164         {
    165             //6.1 ShowImage
    166             cv::imshow(__FUNCTION__, frame);
    167             int c = cv::waitKey(videoIO.waitTime);
    168             if (c == 'q' || c == 'Q') break;
    169 
    170             //6.2 SaveImage
    171             if (c == ' ')
    172             {
    173                 string savePath = videoIO.saveDir + fmt::format("/{}.png", chrono::time_point_cast<chrono::nanoseconds>(chrono::system_clock::now()).time_since_epoch().count());
    174                 cv::imwrite(savePath, frame);
    175                 spdlog::info("Saved to: " + savePath);
    176             }
    177 
    178             //6.3 RecordImage
    179             if (c == '1' || c == '2') flag = c;
    180             if (flag == '1') { wrt.write(frame); spdlog::info("Record timestamp: {}", chrono::time_point_cast<chrono::nanoseconds>(chrono::system_clock::now()).time_since_epoch().count()); }
    181         }
    182         cv::destroyWindow(__FUNCTION__);
    183     }
    184 };
    185 
    186 int main(int argc, char** argv) { AboutVideoIO me; me.TestMe(argc, argv); return 0; }
    View Code
  • 相关阅读:
    echo e 在SHELL脚本和命令行中表现不同一例问题排查
    Linux 中修改网卡名称【ubuntu + Centos7】
    ESXI上实施ORACLE 10G RAC+LINUX+ASM
    Linux crontab下关于使用date命令的坑
    SkiaSharp跨平台绘图研究1WPF桌面应用
    编译原理 实验一 词法分析
    计算机组成原理(上)_第一章测试题
    计算机组成原理(上)_第三章测试题
    SQL Server 2017 下载及安装详细教程
    计算机组成原理(上)_第四章测试题(上)
  • 原文地址:https://www.cnblogs.com/dzyBK/p/13855389.html
Copyright © 2011-2022 走看看