Visual Servoing Platform  version 3.6.0 under development (2023-09-27)
vpVideoReader.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Read videos and image sequences.
32  */
33 
39 #include <visp3/core/vpDebug.h>
40 #include <visp3/core/vpIoTools.h>
41 #include <visp3/io/vpVideoReader.h>
42 
43 #include <cctype>
44 #include <fstream>
45 #include <iostream>
46 #include <limits> // numeric_limits
47 
52  : vpFrameGrabber(), m_imSequence(NULL),
53 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
54  m_capture(), m_frame(), m_lastframe_unknown(false),
55 #endif
56  m_formatType(FORMAT_UNKNOWN), m_videoName(), m_frameName(), m_initFileName(false), m_isOpen(false), m_frameCount(0),
57  m_firstFrame(0), m_lastFrame(0), m_firstFrameIndexIsSet(false), m_lastFrameIndexIsSet(false), m_frameStep(1),
58  m_frameRate(0.)
59 {
60 }
61 
66 {
67  if (m_imSequence != NULL) {
68  delete m_imSequence;
69  }
70 }
71 
87 void vpVideoReader::setFileName(const std::string &filename)
88 {
89  if (filename.empty()) {
90  throw(vpImageException(vpImageException::noFileNameError, "filename empty "));
91  }
92 
93  m_videoName = filename;
94  m_frameName = filename;
95 
96  m_formatType = getFormat(filename);
97 
98  if (m_formatType == FORMAT_UNKNOWN) {
99  throw(vpException(vpException::badValue, "Filename extension not supported"));
100  }
101 
102  // checking image name format
103  if (isImageExtensionSupported()) {
104  std::string format = vpIoTools::getName(m_videoName);
105  if (!checkImageNameFormat(format)) {
106  throw(vpException(vpException::badValue, "Format of image name wasn't recognized: %s", format.c_str()));
107  }
108  }
109 
110  m_initFileName = true;
111 }
112 
116 void vpVideoReader::getProperties()
117 {
118  if (m_isOpen) {
119  return;
120  }
121 
122  if (!m_initFileName) {
123  throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set"));
124  }
125 
126  if (isImageExtensionSupported()) {
127  m_imSequence = new vpDiskGrabber;
128  m_imSequence->setGenericName(m_videoName.c_str());
129  m_imSequence->setStep(m_frameStep);
130  if (m_firstFrameIndexIsSet) {
131  m_imSequence->setImageNumber(m_firstFrame);
132  }
133  m_frameRate = -1.;
134  } else if (isVideoExtensionSupported()) {
135 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
136  m_capture.open(m_videoName.c_str());
137 
138  if (!m_capture.isOpened()) {
139  throw(vpException(vpException::ioError, "Could not open the video %s with OpenCV", m_videoName.c_str()));
140  }
141 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
142  width = (unsigned int)m_capture.get(cv::CAP_PROP_FRAME_WIDTH);
143  height = (unsigned int)m_capture.get(cv::CAP_PROP_FRAME_HEIGHT);
144  m_frameRate = (double)m_capture.get(cv::CAP_PROP_FPS);
145 #else
146  width = (unsigned int)m_capture.get(CV_CAP_PROP_FRAME_WIDTH);
147  height = (unsigned int)m_capture.get(CV_CAP_PROP_FRAME_HEIGHT);
148  m_frameRate = m_capture.get(CV_CAP_PROP_FPS);
149 #endif
150 
151 #else
152  throw(vpException(vpException::fatalError, "To read video files ViSP should be build with opencv "
153  "3rd >= 2.1.0 party libraries."));
154 #endif
155  } else if (m_formatType == FORMAT_UNKNOWN) {
156  // vpERROR_TRACE("The format of the file does not correspond to a readable
157  // format.");
158  throw(vpException(vpException::fatalError, "The format of the file does "
159  "not correspond to a readable "
160  "format supported by ViSP."));
161  }
162 
163  findFirstFrameIndex();
164  m_isOpen = true;
165  findLastFrameIndex();
166 }
167 
176 {
177  getProperties();
178 
179  m_frameCount = m_firstFrame;
180  if (!getFrame(I, m_firstFrame)) {
181  throw(vpException(vpException::ioError, "Could not read the video first frame"));
182  }
183 
184  // Rewind to the first frame since open() should not increase the frame
185  // counter
186  m_frameCount = m_firstFrame;
187 
188  if (isVideoExtensionSupported()) {
189 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
190 
191 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
192  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
193 #else
194  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
195 #endif
196  m_frameCount--;
197 #endif
198  }
199 }
200 
209 {
210  getProperties();
211 
212  m_frameCount = m_firstFrame;
213  if (!getFrame(I, m_firstFrame)) {
214  throw(vpException(vpException::ioError, "Could not read the video first frame"));
215  }
216 
217  // Rewind to the first frame since open() should not increase the frame
218  // counter
219  m_frameCount = m_firstFrame;
220 
221  if (isVideoExtensionSupported()) {
222 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
223 
224 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
225  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
226 #else
227  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
228 #endif
229  m_frameCount--;
230 #endif
231  }
232 }
233 
245 {
246  if (!m_isOpen) {
247  open(I);
248  }
249  if (m_imSequence != NULL) {
250  m_imSequence->setStep(m_frameStep);
251  bool skip_frame = false;
252  do {
253  try {
254  m_imSequence->acquire(I);
255  skip_frame = false;
256  } catch (...) {
257  skip_frame = true;
258  }
259  } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
260  m_frameCount = m_imSequence->getImageNumber();
261  m_frameName = m_imSequence->getImageName();
262  if (m_frameCount + m_frameStep > m_lastFrame) {
263  m_imSequence->setImageNumber(m_frameCount);
264  } else if (m_frameCount + m_frameStep < m_firstFrame) {
265  m_imSequence->setImageNumber(m_frameCount);
266  }
267  }
268 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
269  else {
270  m_capture >> m_frame;
271  if (m_frameStep == 1) {
272  m_frameCount++;
273  } else {
274 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
275  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
276  if (m_frameStep > 0) {
277  if (m_frameCount + m_frameStep <= m_lastFrame) {
278  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
279  } else {
280  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
281  }
282  } else if (m_frameStep < 0) {
283  if (m_frameCount + m_frameStep >= m_firstFrame) {
284  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
285  } else {
286  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
287  }
288  }
289 #else
290  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
291  if (m_frameStep > 0) {
292  if (m_frameCount + m_frameStep <= m_lastFrame) {
293  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
294  } else {
295  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
296  }
297  } else if (m_frameStep < 0) {
298  if (m_frameCount + m_frameStep >= m_firstFrame) {
299  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
300  } else {
301  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
302  }
303  }
304 #endif
305  }
306 
307  if (m_frame.empty()) {
308  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
309  if (m_lastframe_unknown) {
310  // Set last frame to this image index
311  setLastFrameIndex(m_frameCount - m_frameStep);
312  }
313  } else {
314  vpImageConvert::convert(m_frame, I);
315  }
316  }
317 #endif
318 }
319 
329 {
330  if (!m_isOpen) {
331  open(I);
332  }
333 
334  if (m_imSequence != NULL) {
335  m_imSequence->setStep(m_frameStep);
336  bool skip_frame = false;
337  do {
338  try {
339  m_imSequence->acquire(I);
340  skip_frame = false;
341  } catch (...) {
342  skip_frame = true;
343  }
344  } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
345  m_frameCount = m_imSequence->getImageNumber();
346  m_frameName = m_imSequence->getImageName();
347  if (m_frameCount + m_frameStep > m_lastFrame) {
348  m_imSequence->setImageNumber(m_frameCount);
349  } else if (m_frameCount + m_frameStep < m_firstFrame) {
350  m_imSequence->setImageNumber(m_frameCount);
351  }
352  }
353 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
354  else {
355  m_capture >> m_frame;
356  if (m_frameStep == 1) {
357  m_frameCount++;
358  } else {
359 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
360  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
361  if (m_frameStep > 0) {
362  if (m_frameCount + m_frameStep <= m_lastFrame) {
363  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
364  } else {
365  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
366  }
367  } else if (m_frameStep < 0) {
368  if (m_frameCount + m_frameStep >= m_firstFrame) {
369  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
370  } else {
371  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
372  }
373  }
374 #else
375  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
376  if (m_frameStep > 0) {
377  if (m_frameCount + m_frameStep <= m_lastFrame) {
378  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
379  } else {
380  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
381  }
382  } else if (m_frameStep < 0) {
383  if (m_frameCount + m_frameStep >= m_firstFrame) {
384  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
385  } else {
386  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
387  }
388  }
389 #endif
390  }
391 
392  if (m_frame.empty()) {
393  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
394  } else {
395  vpImageConvert::convert(m_frame, I);
396  }
397  }
398 #endif
399 }
400 
414 bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
415 {
416  if (m_imSequence != NULL) {
417  try {
418  m_imSequence->acquire(I, frame_index);
419  width = I.getWidth();
420  height = I.getHeight();
421  m_frameCount = m_imSequence->getImageNumber();
422  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
423  if (m_frameCount + m_frameStep > m_lastFrame) {
424  m_imSequence->setImageNumber(m_frameCount);
425  } else if (m_frameCount + m_frameStep < m_firstFrame) {
426  m_imSequence->setImageNumber(m_frameCount);
427  }
428  } catch (...) {
429  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
430  return false;
431  }
432  } else {
433 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
434 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
435  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
436  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
437  return false;
438  }
439 
440  m_capture >> m_frame;
441  m_frameCount = frame_index + m_frameStep; // next index
442  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
443  if (m_frame.empty()) {
444  // New trial that makes things working with opencv 3.0.0
445  m_capture >> m_frame;
446  if (m_frame.empty()) {
447  setLastFrameIndex(m_frameCount - m_frameStep);
448  return false;
449  } else {
450  vpImageConvert::convert(m_frame, I);
451  }
452  } else
453  vpImageConvert::convert(m_frame, I);
454 #else
455  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
456  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
457  return false;
458  }
459 
460  m_capture >> m_frame;
461  m_frameCount = frame_index + m_frameStep; // next index
462  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
463  if (m_frame.empty())
464  setLastFrameIndex(m_frameCount - m_frameStep);
465  else
466  vpImageConvert::convert(m_frame, I);
467 #endif
468 #endif
469  }
470  return true;
471 }
472 
487 {
488  if (m_imSequence != NULL) {
489  try {
490  m_imSequence->acquire(I, frame_index);
491  width = I.getWidth();
492  height = I.getHeight();
493  m_frameCount = m_imSequence->getImageNumber();
494  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
495  if (m_frameCount + m_frameStep > m_lastFrame) {
496  m_imSequence->setImageNumber(m_frameCount);
497  } else if (m_frameCount + m_frameStep < m_firstFrame) {
498  m_imSequence->setImageNumber(m_frameCount);
499  }
500  } catch (...) {
501  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
502  return false;
503  }
504  } else {
505 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
506 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
507  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
508  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
509  return false;
510  }
511  m_capture >> m_frame;
512  if (m_frame.empty()) {
513  // New trial that makes things working with opencv 3.0.0
514  m_capture >> m_frame;
515  if (m_frame.empty()) {
516  setLastFrameIndex(m_frameCount - m_frameStep);
517  return false;
518  } else {
519  vpImageConvert::convert(m_frame, I);
520  }
521  } else {
522  vpImageConvert::convert(m_frame, I);
523  }
524 #else
525  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
526  vpERROR_TRACE("Couldn't find the %ld th frame",
527  frame_index); // next index
528  return false;
529  }
530  m_capture >> m_frame;
531  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
532  if (m_frameStep > 1) {
533  m_frameCount += m_frameStep - 1; // next index
534  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
535  } else if (m_frameStep < -1) {
536  m_frameCount += m_frameStep - 1; // next index
537  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
538  }
539  if (m_frame.empty())
540  setLastFrameIndex(m_frameCount - m_frameStep);
541  else
542  vpImageConvert::convert(m_frame, I);
543 #endif
544 #endif
545  }
546  return true;
547 }
548 
554 vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(const std::string &filename) const
555 {
556  std::string ext = vpVideoReader::getExtension(filename);
557 
558  if (ext.compare(".PGM") == 0)
559  return FORMAT_PGM;
560  else if (ext.compare(".pgm") == 0)
561  return FORMAT_PGM;
562  else if (ext.compare(".PPM") == 0)
563  return FORMAT_PPM;
564  else if (ext.compare(".ppm") == 0)
565  return FORMAT_PPM;
566  else if (ext.compare(".JPG") == 0)
567  return FORMAT_JPEG;
568  else if (ext.compare(".jpg") == 0)
569  return FORMAT_JPEG;
570  else if (ext.compare(".JPEG") == 0)
571  return FORMAT_JPEG;
572  else if (ext.compare(".jpeg") == 0)
573  return FORMAT_JPEG;
574  else if (ext.compare(".PNG") == 0)
575  return FORMAT_PNG;
576  else if (ext.compare(".png") == 0)
577  return FORMAT_PNG;
578  else if (ext.compare(".TIFF") == 0)
579  return FORMAT_TIFF;
580  else if (ext.compare(".tiff") == 0)
581  return FORMAT_TIFF;
582  else if (ext.compare(".BMP") == 0)
583  return FORMAT_BMP;
584  else if (ext.compare(".bmp") == 0)
585  return FORMAT_BMP;
586  else if (ext.compare(".DIB") == 0)
587  return FORMAT_DIB;
588  else if (ext.compare(".dib") == 0)
589  return FORMAT_DIB;
590  else if (ext.compare(".PBM") == 0)
591  return FORMAT_PBM;
592  else if (ext.compare(".pbm") == 0)
593  return FORMAT_PBM;
594  else if (ext.compare(".SR") == 0)
595  return FORMAT_PBM;
596  else if (ext.compare(".sr") == 0)
597  return FORMAT_PBM;
598  else if (ext.compare(".RAS") == 0)
599  return FORMAT_RASTER;
600  else if (ext.compare(".ras") == 0)
601  return FORMAT_RASTER;
602  else if (ext.compare(".JP2") == 0)
603  return FORMAT_JPEG2000;
604  else if (ext.compare(".jp2") == 0)
605  return FORMAT_JPEG2000;
606  else if (ext.compare(".AVI") == 0)
607  return FORMAT_AVI;
608  else if (ext.compare(".avi") == 0)
609  return FORMAT_AVI;
610  else if (ext.compare(".MPEG") == 0)
611  return FORMAT_MPEG;
612  else if (ext.compare(".mpeg") == 0)
613  return FORMAT_MPEG;
614  else if (ext.compare(".MPG") == 0)
615  return FORMAT_MPEG;
616  else if (ext.compare(".mpg") == 0)
617  return FORMAT_MPEG;
618  else if (ext.compare(".MPEG4") == 0)
619  return FORMAT_MPEG4;
620  else if (ext.compare(".mpeg4") == 0)
621  return FORMAT_MPEG4;
622  else if (ext.compare(".MP4") == 0)
623  return FORMAT_MPEG4;
624  else if (ext.compare(".mp4") == 0)
625  return FORMAT_MPEG4;
626  else if (ext.compare(".MOV") == 0)
627  return FORMAT_MOV;
628  else if (ext.compare(".mov") == 0)
629  return FORMAT_MOV;
630  else if (ext.compare(".OGV") == 0)
631  return FORMAT_OGV;
632  else if (ext.compare(".ogv") == 0)
633  return FORMAT_OGV;
634  else if (ext.compare(".WMV") == 0)
635  return FORMAT_WMV;
636  else if (ext.compare(".wmv") == 0)
637  return FORMAT_WMV;
638  else if (ext.compare(".FLV") == 0)
639  return FORMAT_FLV;
640  else if (ext.compare(".flv") == 0)
641  return FORMAT_FLV;
642  else if (ext.compare(".MKV") == 0)
643  return FORMAT_MKV;
644  else if (ext.compare(".mkv") == 0)
645  return FORMAT_MKV;
646  else if (ext.compare(".MTS") == 0)
647  return FORMAT_MTS;
648  else if (ext.compare(".mts") == 0)
649  return FORMAT_MTS;
650  else
651  return FORMAT_UNKNOWN;
652 }
653 
654 // return the extension of the file including the dot
655 std::string vpVideoReader::getExtension(const std::string &filename)
656 {
657  // extract the extension
658  size_t dot = filename.find_last_of(".");
659  std::string ext = filename.substr(dot, filename.size() - 1);
660  return ext;
661 }
662 
666 void vpVideoReader::findLastFrameIndex()
667 {
668  if (!m_isOpen) {
669  vpERROR_TRACE("Use the open method before");
670  throw(vpException(vpException::notInitialized, "file not yet opened"));
671  }
672 
673  if (m_imSequence != NULL) {
674  if (!m_lastFrameIndexIsSet) {
675  std::string imageNameFormat = vpIoTools::getName(m_videoName);
676  std::string dirName = vpIoTools::getParent(m_videoName);
677  if (dirName == "") {
678  dirName = ".";
679  }
680  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
681  m_lastFrame = 0;
682  for (size_t i = 0; i < files.size(); i++) {
683  // Checking that file name satisfies image format,
684  // specified by imageNameFormat, and extracting imageIndex
685  long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
686  if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
687  m_lastFrame = imageIndex;
688  }
689  }
690  }
691  }
692 
693 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
694 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
695  else if (!m_lastFrameIndexIsSet) {
696  m_lastFrame = (long)m_capture.get(cv::CAP_PROP_FRAME_COUNT);
697  if (m_lastFrame <= 2) {
698  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
699  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
700  // We set video last frame to an arbitrary value 100000 and set a flag
701  m_lastframe_unknown = true;
702  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
703  }
704  }
705 #else
706  else if (!m_lastFrameIndexIsSet) {
707  m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
708  if (m_lastFrame <= 2) {
709  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
710  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
711  // We set video last frame to an arbitrary value 100000 and set a flag
712  m_lastframe_unknown = true;
713  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
714  }
715  }
716 #endif
717 #endif
718 }
719 
723 void vpVideoReader::findFirstFrameIndex()
724 {
725  if (m_imSequence != NULL) {
726  if (!m_firstFrameIndexIsSet) {
727  std::string imageNameFormat = vpIoTools::getName(m_videoName);
728  std::string dirName = vpIoTools::getParent(m_videoName);
729  if (dirName == "") {
730  dirName = ".";
731  }
732  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
733  m_firstFrame = -1;
734  for (size_t i = 0; i < files.size(); i++) {
735  // Checking that file name satisfies image format, specified by
736  // imageNameFormat, and extracting imageIndex
737  long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
738 
739  if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
740  m_firstFrame = imageIndex;
741  }
742  }
743  m_imSequence->setImageNumber(m_firstFrame);
744  }
745  }
746 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
747 
748  else if (!m_firstFrameIndexIsSet) {
749  m_firstFrame = 1L;
750  }
751 #endif
752 }
753 
757 bool vpVideoReader::isImageExtensionSupported() const
758 {
759  return (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
760  m_formatType == FORMAT_PNG || m_formatType == FORMAT_TIFF || m_formatType == FORMAT_BMP ||
761  m_formatType == FORMAT_DIB || m_formatType == FORMAT_PBM || m_formatType == FORMAT_RASTER ||
762  m_formatType == FORMAT_JPEG2000);
763 }
764 
768 bool vpVideoReader::isVideoExtensionSupported() const
769 {
770  return (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
771  m_formatType == FORMAT_MOV || m_formatType == FORMAT_OGV || m_formatType == FORMAT_WMV ||
772  m_formatType == FORMAT_FLV || m_formatType == FORMAT_MKV || m_formatType == FORMAT_MTS);
773 }
774 
799 {
800  this->acquire(I);
801  return *this;
802 }
803 
828 {
829  this->acquire(I);
830  return *this;
831 }
832 
837 bool vpVideoReader::checkImageNameFormat(const std::string &format) const
838 {
839  size_t indexBegin = format.find_last_of('%');
840  size_t indexEnd = format.find_first_of('d', indexBegin);
841  if (indexBegin == std::string::npos || indexEnd == std::string::npos) {
842  return false;
843  }
844  for (size_t i = indexBegin + 1; i < indexEnd; i++) {
845  if (!std::isdigit(format[i])) {
846  return false;
847  }
848  }
849  return true;
850 }
851 
860 {
861  // Video format
862  switch (m_formatType) {
863  case FORMAT_AVI:
864  case FORMAT_MPEG:
865  case FORMAT_MPEG4:
866  case FORMAT_MTS:
867  case FORMAT_MOV:
868  case FORMAT_OGV:
869  case FORMAT_WMV:
870  case FORMAT_FLV:
871  case FORMAT_MKV:
872  return true;
873  default:
874  return false;
875  }
876 }
Class to grab (ie. read) images from the disk.
void setStep(long step)
void setGenericName(const std::string &genericName)
std::string getImageName() const
void setImageNumber(long number)
long getImageNumber() const
void acquire(vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ ioError
I/O error.
Definition: vpException.h:79
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:85
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition: vpException.h:86
@ fatalError
Fatal error.
Definition: vpException.h:84
Base class for all video devices. It is designed to provide a front end to video sources.
unsigned int height
Number of rows in the image.
unsigned int width
Number of columns in the image.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Error that can be emitted by the vpImage class and its derivatives.
@ noFileNameError
Image file name error.
unsigned int getWidth() const
Definition: vpImage.h:242
unsigned int getHeight() const
Definition: vpImage.h:184
static long getIndex(const std::string &filename, const std::string &format)
Definition: vpIoTools.cpp:1627
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:2041
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1669
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1564
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
bool isVideoFormat() const
void acquire(vpImage< vpRGBa > &I)
void setLastFrameIndex(const long last_frame)
void open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
bool getFrame(vpImage< vpRGBa > &I, long frame)
virtual ~vpVideoReader()
vpVideoReader & operator>>(vpImage< unsigned char > &I)
#define vpERROR_TRACE
Definition: vpDebug.h:388