Visual Servoing Platform  version 3.6.1 under development (2024-05-07)
tutorial-video-manipulation.cpp
1 #include <visp3/core/vpImageConvert.h>
3 #include <visp3/core/vpTime.h>
4 #include <visp3/gui/vpDisplayD3D.h>
5 #include <visp3/gui/vpDisplayGDI.h>
6 #include <visp3/gui/vpDisplayGTK.h>
7 #include <visp3/gui/vpDisplayOpenCV.h>
8 #include <visp3/gui/vpDisplayX.h>
9 #include <visp3/io/vpVideoReader.h>
10 #include <visp3/io/vpVideoWriter.h>
11 
12 void usage(const char *argv[], int error)
13 {
14  std::cout << "Synopsis" << std::endl
15  << " " << argv[0] << " [--in <video name>]"
16  << " [--display-fps <framerate>]"
17  << " [--out <video name>]"
18  << " [--out-first-frame <index>]"
19  << " [--out-gray]"
20  << " [--out-stride <value>]"
21  << " [--verbose] [-v]"
22  << " [--help] [-h]" << std::endl
23  << std::endl;
24  std::cout << "Description" << std::endl
25  << " --in <video name> " << std::endl
26  << " Input video to manipulate. " << std::endl
27  << " Supported image formats: pgm,ppm,jpg,jpeg,png,tiff,bmp,ras,jp2" << std::endl
28  << " Example: " << std::endl
29  << " - I%03d.jpg : to read a sequence of images (I008.jpg, I009.jpg, I010.jpg) " << std::endl
30  << std::endl
31  << " --display-fps <framerate>" << std::endl
32  << " Framerate used to display the video. When set to -1 display video as fast as possible." << std::endl
33  << " Default: 30 (fps)" << std::endl
34  << std::endl
35  << " --out <video name>" << std::endl
36  << " Renamed video." << std::endl
37  << std::endl
38  << " --out-first-frame <index>" << std::endl
39  << " Renamed video first image index." << std::endl
40  << " When set to -1, use same image numbering as input video." << std::endl
41  << " Default: -1" << std::endl
42  << std::endl
43  << " --out-gray" << std::endl
44  << " Associated to --out option, convert input images to Y8 gray level image." << std::endl
45  << std::endl
46  << " --out-stride <value>" << std::endl
47  << " Associated to --out option, allows to subsample the resulting output video" << std::endl
48  << " keeping one over <value> images. For example, when set to 2, the ouput video" << std::endl
49  << " has two times less images than the input video." << std::endl
50  << " Default: 1." << std::endl
51  << std::endl
52  << " --select, -s" << std::endl
53  << " Associated to --out option, allows the user to select by mouse" << std::endl
54  << " click which images will be saved in the output video." << std::endl
55  << std::endl
56  << " --verbose, -v" << std::endl
57  << " Display extra messages." << std::endl
58  << std::endl
59  << " --help, -h" << std::endl
60  << " Print this helper message." << std::endl
61  << std::endl;
62  if (error) {
63  std::cout << "Error" << std::endl
64  << " "
65  << "Unsupported parameter " << argv[error] << std::endl;
66  }
67 }
68 
69 int main(int argc, const char *argv[])
70 {
71  if (argc == 1) {
72  usage(argv, 0);
73  return EXIT_SUCCESS;
74  }
75 
76  std::string opt_video_in = "";
77  double opt_display_fps = 30;
78  std::string opt_video_out = "";
79  int opt_video_out_first_frame = -1;
80  bool opt_video_out_gray = false;
81  int opt_video_out_stride = 1;
82 
83  bool opt_verbose = false;
84  bool opt_select_frame = false;
85 
86  for (int i = 1; i < argc; i++) {
87  if (std::string(argv[i]) == "--in" && i + 1 < argc) {
88  opt_video_in = std::string(argv[i + 1]);
89  i++;
90  } else if (std::string(argv[i]) == "--display-fps" && i + 1 < argc) {
91  opt_display_fps = std::atof(argv[i + 1]);
92  i++;
93  } else if (std::string(argv[i]) == "--out" && i + 1 < argc) {
94  opt_video_out = std::string(argv[i + 1]);
95  i++;
96  } else if (std::string(argv[i]) == "--out-first-frame" && i + 1 < argc) {
97  opt_video_out_first_frame = std::atoi(argv[i + 1]);
98  i++;
99  } else if (std::string(argv[i]) == "--out-gray") {
100  opt_video_out_gray = true;
101  } else if (std::string(argv[i]) == "--out-stride" && i + 1 < argc) {
102  opt_video_out_stride = std::atoi(argv[i + 1]);
103  i++;
104  } else if (std::string(argv[i]) == "--verbose" || std::string(argv[i]) == "-v") {
105  opt_verbose = true;
106  } else if (std::string(argv[i]) == "--select" || std::string(argv[i]) == "-s") {
107  opt_select_frame = true;
108  } else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
109  usage(argv, 0);
110  return EXIT_SUCCESS;
111  } else {
112  usage(argv, i);
113  return EXIT_FAILURE;
114  }
115  }
116 
117  // Option ckeck
118  if (opt_video_in.empty()) {
119  usage(argv, 0);
120  std::cout << "Error: " << std::endl << " No input video set using --in <video name> option." << std::endl;
121  return EXIT_FAILURE;
122  }
123  if (opt_select_frame && opt_video_out.empty()) {
124  usage(argv, 0);
125  std::cout << "Error: " << std::endl
126  << " --select option is enabled but no output video name is specified using --out <video> option."
127  << std::endl;
128  return EXIT_FAILURE;
129  }
130  if (opt_video_out_gray && opt_video_out.empty()) {
131  usage(argv, 0);
132  std::cout << "Error: " << std::endl
133  << " --out-gray option is enabled but no output video name is specified using --out <video> option."
134  << std::endl;
135  return EXIT_FAILURE;
136  }
137  if ((opt_video_out_stride > 1) && opt_video_out.empty()) {
138  usage(argv, 0);
139  std::cout << "Error: " << std::endl
140  << " --out-stride option is enabled but no output video name is specified using --out <video> option."
141  << std::endl;
142  return EXIT_FAILURE;
143  }
144  if ((opt_video_out_stride > 1) && opt_select_frame && !opt_video_out.empty()) {
145  usage(argv, 0);
146  std::cout << "Error: " << std::endl
147  << " --out-stride option is enabled but this option doesn't make sense with --select option."
148  << std::endl;
149  return EXIT_FAILURE;
150  }
151 
152  vpImage<vpRGBa> I;
154  vpVideoReader g;
155  g.setFileName(opt_video_in);
156  g.open(I);
157  std::cout << "Input video" << std::endl;
158  std::cout << " Video name : " << opt_video_in << std::endl;
159  std::cout << " Video dimension: " << I.getWidth() << " " << I.getHeight() << std::endl;
160  std::cout << " First image : " << g.getFirstFrameIndex() << std::endl;
161  std::cout << " Last image : " << g.getLastFrameIndex() << std::endl;
162  std::cout << " Framerate (fps): " << opt_display_fps << std::endl;
163 
164  vpVideoWriter writer;
165  if (!opt_video_out.empty()) {
166  writer.setFileName(opt_video_out);
167  int first_frame =
168  (opt_video_out_first_frame < 0 ? static_cast<int>(g.getFirstFrameIndex()) : opt_video_out_first_frame);
169  writer.setFirstFrameIndex(first_frame);
170  if (opt_video_out_gray) {
171  vpImageConvert::convert(I, Igray);
172  writer.open(Igray);
173  } else {
174  writer.open(I);
175  }
176  std::cout << "Output video" << std::endl;
177  std::cout << " Video name : " << opt_video_out << std::endl;
178  std::cout << " First image : " << first_frame << std::endl;
179  std::cout << " Stride : " << opt_video_out_stride << std::endl;
180  std::cout << " Y8 gray images : " << (opt_video_out_gray ? "yes" : "no (same as input)") << std::endl;
181  }
182 
183  std::cout << "Other settings" << std::endl;
184  std::cout << " Verbose : " << (opt_verbose ? "enabled" : "disabled") << std::endl;
185  std::cout << " Select frames : " << (opt_select_frame ? "enabled" : "disabled") << std::endl;
186 
187  try {
189 #if defined(VISP_HAVE_X11)
191 #elif defined(VISP_HAVE_GDI)
193 #elif defined(HAVE_OPENCV_HIGHGUI)
195 #elif defined(VISP_HAVE_GTK)
197 #elif defined(VISP_HAVE_D3D9)
199 #else
200  std::cout << "No image viewer is available..." << std::endl;
201 #endif
202  int scale = vpDisplay::getDownScalingFactor(I);
203  int cpt_stride = 1;
204 
205  while (!g.end()) {
206  double t = vpTime::measureTimeMs();
207  g.acquire(I);
208 
209  std::stringstream ss;
210  ss << "Image " << g.getFrameIndex();
211  vpDisplay::setTitle(I, ss.str());
213  vpDisplay::displayText(I, 15 * scale, 15 * scale, "Right click to quit", vpColor::red);
214  if (opt_select_frame) {
215  vpDisplay::displayText(I, 30 * scale, 15 * scale, "Left click to select frame", vpColor::red);
216  }
217  vpDisplay::flush(I);
218 
219  bool selected_frame = (opt_select_frame ? false : true);
221  if (vpDisplay::getClick(I, button, false)) {
222  if (button == vpMouseButton::button1 && opt_select_frame) {
223  selected_frame = true;
224  } else if (button == vpMouseButton::button3) {
225  break;
226  }
227  }
228 
229  if (!opt_video_out.empty() && selected_frame) {
230  if (cpt_stride == opt_video_out_stride) {
231  cpt_stride = 1;
232  if (opt_video_out_gray) {
233  vpImageConvert::convert(I, Igray);
234  writer.saveFrame(Igray);
235  } else {
236  writer.saveFrame(I);
237  }
238  if (opt_verbose) {
239  std::cout << "Save " << writer.getFrameName() << std::endl;
240  }
241  } else {
242  cpt_stride++;
243  }
244  }
245 
246  if (opt_display_fps > 0) {
247  vpTime::wait(t, 1000. / opt_display_fps);
248  }
249  }
250  } catch (const vpException &e) {
251  std::cout << "Catch an exception: " << e << std::endl;
252  }
253 }
static const vpColor red
Definition: vpColor.h:211
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:101
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:128
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:128
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
@ SCALE_AUTO
Definition: vpDisplay.h:179
unsigned int getDownScalingFactor()
Definition: vpDisplay.h:231
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
Definition: vpException.h:59
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
unsigned int getWidth() const
Definition: vpImage.h:245
unsigned int getHeight() const
Definition: vpImage.h:184
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void acquire(vpImage< vpRGBa > &I)
long getLastFrameIndex()
void open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
long getFirstFrameIndex()
long getFrameIndex() const
Class that enables to write easily a video file or a sequence of images.
void saveFrame(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
void open(vpImage< vpRGBa > &I)
void setFirstFrameIndex(int first_frame)
std::string getFrameName() const
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMs()