代码有意思的地方在g_run这个变量,默认为1,第一次执行完后减为0,如果是继续则为-1,g_run的值会一直变小(有可能会溢出?)当再一次转换为单步时g_run又被设为1,当进入循环后g_run被设为0,则条件 不满足所以不会进入循环程序会停止
如果采用布尔变量
onTrackbarSlide控制的变量g_dontset 有什么用呢?没看懂。
To avoid confusion, when the user clicks on the trackbar to jump to a new location in
the video, we’ll leave the video paused there in the single-step state by setting g_run =
1. This, however, brings up a subtle problem: as the video advances, we’d like the
slider trackbar’s position in the display window to advance according to our location
in the video. We do this by having the main program call the trackbar callback func‐
tion to update the slider’s position each time we get a new video frame. However, we
don’t want these programmatic calls to the trackbar callback to put us into single-step
mode. To avoid this, we introduce a final global variable, g_dontset, to allow us to
update the trackbar’s position without triggering single-step mode.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace std;
int g_slider_position = 0;
int g_run = 1, g_dontset = 0; //start out in single step mode
cv::VideoCapture g_cap;
void onTrackbarSlide(int pos, void *) {
g_cap.set(CV_CAP_PROP_POS_FRAMES, pos); //opencv 2410
//g_cap.set(CV::CAP_PROP_POS_FRAMES, pos);
if (!g_dontset)
g_run = 1;
g_dontset = 0;
}
int main(int argc, char** argv) {
cv::namedWindow("Example2_4", CV_WINDOW_AUTOSIZE);
g_cap.open(string(argv[1]));
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; if (frame.empty()) break;
int current_pos = (int)g_cap.get(CV_CAP_PROP_POS_FRAMES);
g_dontset = 1;
cv::setTrackbarPos("Position", "Example2_4", current_pos);
cv::imshow("Example2_4", frame);
g_run -= 1;
}
char c = (char)cv::waitKey(10);
if (c == 's') // single step
{
g_run = 1; cout << "Single step, run = " << g_run << endl;
}
if (c == 'r') // run mode
{
g_run = -1; cout << "Run mode, run = " << g_run << endl;
}
if (c == 27)
break;
}
return(0);
}
//
//just read a video from our disk
//int main(int argc, char** argv) {
//
// cv::namedWindow("Example3", cv::WINDOW_AUTOSIZE);
// cv::VideoCapture cap;
// cap.open(argv[1]);
//
// cv::Mat frame;
// for (;;) {
// cap >> frame;
// if (frame.empty()) break; // Ran out of film
// cv::imshow("Example3", frame);
// if (cv::waitKey(33) >= 0) break;
// }
// return 0;
//}