1、createTrackbar(trackbarname,winname,*value,count,onTrackbarSlide)
参数名 trackbarname表示进度条名字 winname表示窗口名字 value表示进度条位置的索引 count表示该视频的最大帧数 onTrackbarSlide表示回调函数
2、TrackbarSlide(pos)
void onTrackbarSlide(int pos, void *) //pos参数由g_slider_position传递 { g_cap.set(cv::CAP_PROP_POS_FRAMES, pos); //从第pos帧开始 if (!g_dontset) g_run = 1; //进入单步模式 g_dontset = 0; }3、实现代码
#include<opencv2\opencv.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highgui/highgui.hpp> #include<iostream> #include<fstream> using namespace std; int g_slider_position = 0; int g_run = 1, g_dontset = 0; cv::VideoCapture g_cap; void onTrackbarSlide(int pos, void *) //pos参数由g_slider_position传递 { g_cap.set(cv::CAP_PROP_POS_FRAMES, pos); //从第pos帧开始 if (!g_dontset) g_run = 1; //进入单步模式 g_dontset = 0; } int main() { cv::namedWindow("Example2_4", cv::WINDOW_AUTOSIZE); g_cap.open("Video1.mp4"); assert(g_cap.isOpened()); int frames = (int)g_cap.get(cv::CAP_PROP_FRAME_COUNT); int tmpw = (int)g_cap.get(cv::CAP_PROP_FRAME_WIDTH); int tmph = (int)g_cap.get(cv::CAP_PROP_FRAME_HEIGHT); cout << "Video has " << frames << " frames of dimensions( " << tmpw << "," << tmph << ")." << endl; cv::createTrackbar("Position", "Example2_4", &g_slider_position, frames, onTrackbarSlide); //创建一个进度条 cv::Mat frame; //用于读取视频流 for (;;) { if (g_run != 0) { g_cap >> frame; //从g_cap读取一帧 if (frame.empty()) break; int current_pos = (int)g_cap.get(cv::CAP_PROP_POS_FRAMES); //获取下一帧的索引值 g_dontset = 1; //初始值为0,下一步调用回调函数会判断并且将g_run设置为1,就会导致进入单步模式 cv::setTrackbarPos("Position", "Example2_4", current_pos); //设置滚动条位置 cv::imshow("Example2_4", frame); //显示一帧图片 g_run -= 1; } char c = (char)cv::waitKey(30); //等待30ms继续执行程序 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的ascll码 break; } return 0; }总结:一开始会默认读取一帧然后停止,因为g_run初始值等于1,如果执行单步模式,即每次g_run=1都会读取一帧后停止,每次拖动进度条都会获取到g_slider_position的值。然后调用回调函数获取下一帧,默认进入单步模式。当输入r时,g_run=-1,此时循环会不断进行,直到读取到esc或者s。