• OpenCV-Utils学习日志:VideoCapture使用样例


    1.VideoCapture可以打开多种来源的数据流,但常见的是相机、视频及图像序列三类数据流:

             (1)打开相机数据流,需要指定相机在主机上的设备编号,若主机上只有一个相机则编号通常是0。

             (2)打开视频数据流,需要指定视频的完整路径,如/root/data/vtest.avi。

             (3)打开图像序列流,需要指定图像序列的完整路径,其中路径中的文件名的格式同C言语中prinf的格式,可参见《CV学习日志:C语言中文件IO使用要点》。如/root/data下有ima1.png、ima2.png、…、ima123.png,则给定的文件名为/root/data/ima%d.png;如/root/data下有ima001.png、ima002.png、…、ima123.png,则给定的名为/root/data/ima%03d.png,这里%03d表示图像名序列号是整数、占宽三位、不足三位的高位是零填充。

    2.VideoCapture常用的函数是构造、readsetget

             (1)构造函数:打开数据流。

             (2)read函数:读一帧数据流。

             (3)set函数:设置VideoCapture属性值,常用属性是CAP_PROP_FRAME_HEIGHT和CAP_PROP_FRAME_WIDTH。

             (4)get函数:获取VideoCapture属性值,常用属性是CAP_PROP_FRAME_HEIGHT和CAP_PROP_FRAME_WIDTH。

    3.AboutVideoCAPVideoCapture的使用样例,其功能如下:

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

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

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

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

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

             也可参见关于VedioCapture和VideoWriter的综合使用样例《OpenCV-Utils学习日志:VideoWriter使用要点》。

             以下是详细代码,依赖于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 AboutVideoCAP
    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     void TestMe(int argc = 0, char** argv = 0)
    38     {
    39         //0.GetParams
    40         if (argc < 3) { spdlog::critical("Usage: appName streamFrom saveDir waitTime(Optional) deviceRows(Optional) deviceCols(Optional)"); return; }
    41         string imaFrom = argv[1];
    42         string saveDir = argv[2];
    43         int waitTime = 30; if (argc > 3) waitTime = atoi(argv[3]);
    44         int deviceRows = 0; if (argc > 4) deviceRows = atoi(argv[4]);
    45         int deviceCols = 0; if (argc > 5) deviceCols = atoi(argv[5]);
    46 
    47         //1.CreatDirectory
    48         utils::fs::createDirectories(saveDir);
    49         spdlog::set_pattern("%v"); spdlog::info("imaFrom: {}
    saveDir: {}
    waitTime: {}
    deviceRows: {}
    deviceCols: {}", imaFrom, saveDir, waitTime, deviceRows, deviceCols);
    50 
    51         //2.OpenStream
    52         VideoCapture cap;
    53         if (imaFrom.size() == 1)
    54             if (cap.open(atoi(imaFrom.c_str())) == false) { spdlog::critical("Failed to open device: {}", imaFrom); return; }
    55         if (imaFrom.size() > 1)
    56             if (cap.open(imaFrom) == false) { spdlog::critical("Failed to open file: {}", imaFrom); return; }
    57 
    58         //3.SetDevice
    59         if (imaFrom.size() == 1 && argc > 4) cap.set(CAP_PROP_FRAME_HEIGHT, deviceRows);
    60         if (imaFrom.size() == 1 && argc > 5) cap.set(CAP_PROP_FRAME_WIDTH, deviceCols);
    61 
    62         //4.GetDevice
    63         spdlog::info("cap.isOpened(): {}", cap.isOpened());
    64         spdlog::info("cap.getBackendName(): ", cap.getBackendName());
    65         for (map<int, pair<int, string>>::iterator it = capProps.begin(); it != capProps.end(); ++it)
    66             spdlog::info("cap.get({}): {}", it->second.second, cap.get(it->second.first));
    67 
    68         //5.ReadStream
    69         cv::namedWindow(__FUNCTION__, WINDOW_NORMAL);
    70         spdlog::info("Press space to save one and q/Q to exit");
    71         Mat frame;
    72         while (cap.read(frame))
    73         {
    74             //5.1 ShowImage
    75             cv::imshow(__FUNCTION__, frame);
    76             int c = cv::waitKey(waitTime);
    77             if (c == 'q' || c == 'Q') break;
    78 
    79             //5.2 SaveImage
    80             if (c == ' ')
    81             {
    82                 string savePath = saveDir + fmt::format("/{}.png", chrono::time_point_cast<chrono::nanoseconds>(chrono::system_clock::now()).time_since_epoch().count());
    83                 cv::imwrite(savePath, frame);
    84                 spdlog::info("Saved to: " + savePath);
    85             }
    86         }
    87         cv::destroyWindow(__FUNCTION__);
    88     }
    89 };
    90 
    91 int main(int argc, char** argv) { AboutVideoCAP me; me.TestMe(argc, argv); return 0; }
    View Code
  • 相关阅读:
    js 数组去重求和 (转载)
    表格插件汇总(转载)
    SQL Server 用一张表的数据更新另一张表的数据(转载)
    C#创建DataTable(转载)
    C# DataTable 和List之间相互转换的方法(转载)
    维度表,实体表,事实表之间的关系
    Scala中foldLeft的总结
    Scala集合Map
    从合并两个Map说开去
    UDAF(用户自定义聚合函数)求众数
  • 原文地址:https://www.cnblogs.com/dzyBK/p/13849616.html
Copyright © 2020-2023  润新知