【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 按原样传递给回调的用户数据。它可用于在不使用全局变量的情况下处理跟踪栏事件