简单的读入视频:
#include "opencv2/opencv.hpp"
int main(int argc, char** argv) {
namedWindow("Example3", WINDOW_FREERATIO);
VideoCapture cap;
cap.open("F:/test/white-lilies.mp4");
Mat frame;
for (;;) {
cap >> frame;
if (frame.empty()) break;
imshow("Example3", frame);
if (waitKey(33)>=0) break;
}
return 0;
}
此时的视频播放器不可以快速在视频中进行跳转,接下来添加一个滑动条使用户可以进行视频跳转。按S键执行单步模式,按R键来恢复连续视频播放模式。无论何时通过滑动条跳转到视频一个新的时间点,都会使用单步模式在那个点进行播放。
HighGUI工具提供了许多简单的工具用于处理视频和图像,要创建一个滑动条,可以调用cv::createTrackbar()并指明要在哪个窗口显示,还需要一个能够执行重新定位的回调函数。
#include "opencv2/opencv.hpp" #include#include using namespace cv; using namespace std; int g_slider_position = 0; //存储滑动条的位置 int g_run = 1, g_dontset = 0; //以单步模式开始。g_run将在新的跳转触发之后置0。 定义g_dontset避免在调整进度条位置的时候触发单步模式 VideoCapture g_cap; //帧读取结构定义为全局变量,以便回调函数的访问 //回调程序 void onTrackbarSlide(int pos, void *) { g_cap.set(CAP_PROP_POS_FRAMES, pos); //使进度条移到期望位置 if (!g_dontset) g_run = 1; g_dontset = 0; } int main(int argc, char** argv) { namedWindow("Example2_4", WINDOW_AUTOSIZE); g_cap.open("F:/test/white-lilies.mp4"); int frames = (int)g_cap.get(CAP_PROP_FRAME_COUNT); //确定视频的总帧数,下边分别是宽和高 int tmpw = (int)g_cap.get(CAP_PROP_FRAME_WIDTH); int tmph = (int)g_cap.get(CAP_PROP_FRAME_HEIGHT); cout << "Video has" << frames << "frames of dimensions (" << tmpw << "," << tmph << ")." << endl; createTrackbar("Position", "Example2_4", &g_slider_position, frames, onTrackbarSlide); //创建滑动条 Mat frame; for (;;) { if (g_run != 0) { g_cap >> frame; if (frame.empty()) break; int current_pos = (int)g_cap.get(CAP_PROP_POS_FRAMES); g_dontset = 1; //使下一个滑动条的回调函数不会让程序进入单步模式 setTrackbarPos("Position", "Example2_4", current_pos); //更新滑动块在滑动条上的位置以便显示给用户 imshow("Example2_4", frame); g_run = -1; } char c = (char)waitKey(10); if (c == 's') { g_run = 1; cout << "single step, run = " << g_run << endl; } if (c == 'r') { g_run = -1; cout << "Run mode, run = " << g_run << endl; } if (c == 27) //esc break; } destroyAllWindows(); return 0; }
本质上,代码中添加一个全局变量来表示滑动条的位置并且添加一个回调函数来更改这个变量来重新定位i视频读取的位置。
运行结果:



