【C++】【OpenCV-4.9.0】播放视频

相较于之前的Python下的opencv读取视频流并展示,C++下有一些不同需要配置

1、opencv\build文件夹的bin文件夹下的opencv_videoio_ffmpeg490_64.dll需要拷贝至工程文件中,或者将bin路径写入环境变量也可。(如果没有这个dll文件的话,可能会出现一直读取视频失败,即使用isOpened()返回false)。

 1 #include<iostream>
 2 #include<string>
 3 #include<opencv2/highgui/highgui.hpp>
 4 #include<opencv2/imgproc/imgproc.hpp>
 5 
 6 int main(int argc, char** argv) {
 7     cv::namedWindow("Video", cv::WINDOW_AUTOSIZE);
 8     cv::VideoCapture cap;
 9     cap.open(argv[1]);
10     cv::Mat frame;
11     if (!cap.isOpened()) std::cout << "Failed!" << std::endl;
12     for (;;) {
13         cap >> frame;
14         if (frame.empty()) break;
15         std::cout << "OK" << std::endl;
16         cv::imshow("Video", frame);
17         if (cv::waitKey(33) >= 0) break;
18     }
19     return 0;
20 }

 上述代码只是简单的播放视频,我们还可以通过添加跟踪条和监听按键来完成跳转和暂停功能:

1、cv::trackbar()来创建进度条

2、cv::VideoCapture::get()来获取实时帧率信息

3、cv::setTrackbarPos()实时更新进度条进度

4、cv::VideoCapture::set()调整视频进度

关于回调函数的调用,每次经过setTrackbarPos()时都会去调用一遍回调函数,并将第三个参数传给回调函数中的int形参(current_pos会传给pos

 1 #include <iostream>
 2 #include <fstream>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 using namespace std;
 6 
 7 // 标记进度条位置
 8 int g_slider_position = 0;
 9 // 设置播放状态
10 int g_run = 1, g_dotset = 0;
11 cv::VideoCapture g_cap;
12 
13 void onTrackbarSlide(int pos, void*) {
14     g_cap.set(cv::CAP_PROP_POS_FRAMES, pos);
15     // 当希望触发回调函数后自动播放时则设置为1,否则可直接注释该行或者置0
16     g_run = 0;
17 }
18 
19 int main(int argc, char** argv) {
20     cv::namedWindow("Video", cv::WINDOW_AUTOSIZE);
21     g_cap.open(argv[1]);
22     // 读取帧率
23     int frames = (int)g_cap.get(cv::CAP_PROP_FRAME_COUNT);
24     // 读取宽度
25     int tmpw = (int)g_cap.get(cv::CAP_PROP_FRAME_WIDTH);
26     // 读取高度
27     int tmph = (int)g_cap.get(cv::CAP_PROP_FRAME_HEIGHT);
28     cout << "Video has " << frames << "frames of dimensions("
29         << tmpw << ", " << tmph << ")." << endl;
30     // 创建进度条
31     cv::createTrackbar("Position", "Video", &g_slider_position, frames,
32         onTrackbarSlide);
33     cv::Mat frame;
34     for (;;) {
35         if (g_run != 0) {
36             g_cap >> frame;
37             if (frame.empty()) break;
38             int current_pos = (int)g_cap.get(cv::CAP_PROP_POS_FRAMES);
39             cout << "Back call" << endl;
40             cv::setTrackbarPos("Position", "Video", current_pos);
41             cv::imshow("Video", frame);
42 
43             g_run = -1;
44         }
45         char c = (char)cv::waitKey(10);
46         if (c == 's') {
47             g_run = 0;
48             cout << "Single step, run = " << g_run << endl;
49         }
50         if (c == 'r') {
51             g_run = -1;
52             cout << "Run mode, run = " << g_run << endl;
53         }
54         if (c == 27)
55             break;
56 
57     }
58 
59     return 0;
60 }

◆ createTrackbar()

int cv::createTrackbar(const String&  trackbarname,

          const String&  winname,

          int *       value,

          int       count,

          TrackbarCallback onChange = 0,

          void *       userdata = 0

          )

创建跟踪栏并将其附加到指定的窗口。

函数 createTrackbar 创建具有指定名称和范围的跟踪栏(滑块或范围控件),将变量值指定为与跟踪栏同步的位置,并指定要在跟踪栏位置更改时调用的回调函数 onChange。创建的跟踪栏显示在指定的窗口 winname 中。

Parameters

  trackbarname  创建的跟踪栏的名称

  winname    将用作所创建跟踪栏的父级的窗口的名称

  value       指向整数变量的可选指针,其值反映滑块的位置。创建时,滑块位置由此变量定义

  count       滑块的最大位置。最小位置始终为 0

  onChange     指向每次滑块更改位置时要调用的函数的指针。这个函数应该被原型化为 void Foo(int,void*);,其中第一个参数是跟踪栏位置,第二个参数是用户数据(请参阅下一个参数)。如果回调为 NULL 指针,则不调用回调,只更新值

  userdata     按原样传递给回调的用户数据。它可用于在不使用全局变量的情况下处理跟踪栏事件

posted @ 2024-02-29 20:50  VanGoghpeng  阅读(69)  评论(0编辑  收藏  举报