Visual Servoing Platform  version 3.4.1 under development (2021-10-17)
vpVideoReader.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Read videos and image sequences.
33  *
34  * Authors:
35  * Nicolas Melchior
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
45 #include <visp3/core/vpDebug.h>
46 #include <visp3/core/vpIoTools.h>
47 #include <visp3/io/vpVideoReader.h>
48 
49 #include <cctype>
50 #include <fstream>
51 #include <iostream>
52 #include <limits> // numeric_limits
53 
58  : vpFrameGrabber(), m_imSequence(NULL),
59 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
60  m_capture(), m_frame(), m_lastframe_unknown(false),
61 #endif
62  m_formatType(FORMAT_UNKNOWN), m_fileName(), m_initFileName(false), m_isOpen(false), m_frameCount(0), m_firstFrame(0), m_lastFrame(0),
63  m_firstFrameIndexIsSet(false), m_lastFrameIndexIsSet(false), m_frameStep(1), m_frameRate(0.)
64 {
65 }
66 
71 {
72  if (m_imSequence != NULL) {
73  delete m_imSequence;
74  }
75 }
76 
92 void vpVideoReader::setFileName(const std::string &filename)
93 {
94  if (filename.empty()) {
95  throw(vpImageException(vpImageException::noFileNameError, "filename empty "));
96  }
97 
98  m_fileName = filename;
99 
100  m_formatType = getFormat(m_fileName);
101 
102  if (m_formatType == FORMAT_UNKNOWN) {
103  throw(vpException(vpException::badValue, "Filename extension not supported"));
104  }
105 
106  // checking image name format
107  if (isImageExtensionSupported()) {
108  std::string format = vpIoTools::getName(m_fileName);
109  if (!checkImageNameFormat(format)) {
110  throw(vpException(vpException::badValue, "Format of image name wasn't recognized: %s", format.c_str()));
111  }
112  }
113 
114  m_initFileName = true;
115 }
116 
120 void vpVideoReader::getProperties()
121 {
122  if (m_isOpen) {
123  return;
124  }
125 
126  if (!m_initFileName) {
127  throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set"));
128  }
129 
130  if (isImageExtensionSupported()) {
131  m_imSequence = new vpDiskGrabber;
132  m_imSequence->setGenericName(m_fileName.c_str());
133  m_imSequence->setStep(m_frameStep);
134  if (m_firstFrameIndexIsSet) {
135  m_imSequence->setImageNumber(m_firstFrame);
136  }
137  m_frameRate = -1.;
138  } else if (isVideoExtensionSupported()) {
139 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
140  m_capture.open(m_fileName.c_str());
141 
142  if (!m_capture.isOpened()) {
143  throw(vpException(vpException::ioError, "Could not open the video %s with OpenCV", m_fileName.c_str()));
144  }
145 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
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 = (double)m_capture.get(cv::CAP_PROP_FPS);
149 #else
150  width = (unsigned int)m_capture.get(CV_CAP_PROP_FRAME_WIDTH);
151  height = (unsigned int)m_capture.get(CV_CAP_PROP_FRAME_HEIGHT);
152  m_frameRate = m_capture.get(CV_CAP_PROP_FPS);
153 #endif
154 
155 #else
156  throw(vpException(vpException::fatalError, "To read video files ViSP should be build with opencv "
157  "3rd >= 2.1.0 party libraries."));
158 #endif
159  } else if (m_formatType == FORMAT_UNKNOWN) {
160  // vpERROR_TRACE("The format of the file does not correspond to a readable
161  // format.");
162  throw(vpException(vpException::fatalError, "The format of the file does "
163  "not correspond to a readable "
164  "format supported by ViSP."));
165  }
166 
167  findFirstFrameIndex();
168  m_isOpen = true;
169  findLastFrameIndex();
170 }
171 
180 {
181  getProperties();
182 
183  m_frameCount = m_firstFrame;
184  if (!getFrame(I, m_firstFrame)) {
185  throw(vpException(vpException::ioError, "Could not read the video first frame"));
186  }
187 
188  // Rewind to the first frame since open() should not increase the frame
189  // counter
190  m_frameCount = m_firstFrame;
191 
192  if (isVideoExtensionSupported()) {
193 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
194 
195 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
196  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
197 #else
198  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
199 #endif
200  m_frameCount--;
201 #endif
202  }
203 }
204 
213 {
214  getProperties();
215 
216  m_frameCount = m_firstFrame;
217  if (!getFrame(I, m_firstFrame)) {
218  throw(vpException(vpException::ioError, "Could not read the video first frame"));
219  }
220 
221  // Rewind to the first frame since open() should not increase the frame
222  // counter
223  m_frameCount = m_firstFrame;
224 
225  if (isVideoExtensionSupported()) {
226 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
227 
228 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
229  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
230 #else
231  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
232 #endif
233  m_frameCount--;
234 #endif
235  }
236 }
237 
249 {
250  if (!m_isOpen) {
251  open(I);
252  }
253  // getFrame(I,m_frameCount);
254  if (m_imSequence != NULL) {
255  m_imSequence->setStep(m_frameStep);
256  m_imSequence->acquire(I);
257  m_frameCount = m_imSequence->getImageNumber();
258  if (m_frameCount + m_frameStep > m_lastFrame) {
259  m_imSequence->setImageNumber(m_frameCount);
260  } else if (m_frameCount + m_frameStep < m_firstFrame) {
261  m_imSequence->setImageNumber(m_frameCount);
262  }
263  }
264 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
265  else {
266  m_capture >> m_frame;
267  if (m_frameStep == 1) {
268  m_frameCount++;
269  } else {
270 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
271  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
272  if (m_frameStep > 0) {
273  if (m_frameCount + m_frameStep <= m_lastFrame) {
274  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
275  } else {
276  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
277  }
278  } else if (m_frameStep < 0) {
279  if (m_frameCount + m_frameStep >= m_firstFrame) {
280  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
281  } else {
282  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
283  }
284  }
285 #else
286  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
287  if (m_frameStep > 0) {
288  if (m_frameCount + m_frameStep <= m_lastFrame) {
289  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
290  } else {
291  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
292  }
293  } else if (m_frameStep < 0) {
294  if (m_frameCount + m_frameStep >= m_firstFrame) {
295  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
296  } else {
297  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
298  }
299  }
300 #endif
301  }
302 
303  if (m_frame.empty()) {
304  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
305  if (m_lastframe_unknown) {
306  // Set last frame to this image index
307  setLastFrameIndex(m_frameCount - m_frameStep);
308  }
309  }
310  else {
311  vpImageConvert::convert(m_frame, I);
312  }
313  }
314 #endif
315 }
316 
326 {
327  if (!m_isOpen) {
328  open(I);
329  }
330 
331  if (m_imSequence != NULL) {
332  m_imSequence->setStep(m_frameStep);
333  m_imSequence->acquire(I);
334  m_frameCount = m_imSequence->getImageNumber();
335  if (m_frameCount + m_frameStep > m_lastFrame) {
336  m_imSequence->setImageNumber(m_frameCount);
337  } else if (m_frameCount + m_frameStep < m_firstFrame) {
338  m_imSequence->setImageNumber(m_frameCount);
339  }
340  }
341 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
342  else {
343  m_capture >> m_frame;
344  if (m_frameStep == 1) {
345  m_frameCount++;
346  } else {
347 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
348  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
349  if (m_frameStep > 0) {
350  if (m_frameCount + m_frameStep <= m_lastFrame) {
351  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
352  } else {
353  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
354  }
355  } else if (m_frameStep < 0) {
356  if (m_frameCount + m_frameStep >= m_firstFrame) {
357  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
358  } else {
359  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
360  }
361  }
362 #else
363  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
364  if (m_frameStep > 0) {
365  if (m_frameCount + m_frameStep <= m_lastFrame) {
366  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
367  } else {
368  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
369  }
370  } else if (m_frameStep < 0) {
371  if (m_frameCount + m_frameStep >= m_firstFrame) {
372  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
373  } else {
374  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
375  }
376  }
377 #endif
378  }
379 
380  if (m_frame.empty()) {
381  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
382  }
383  else {
384  vpImageConvert::convert(m_frame, I);
385  }
386  }
387 #endif
388 }
389 
403 bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
404 {
405  if (m_imSequence != NULL) {
406  try {
407  m_imSequence->acquire(I, frame_index);
408  width = I.getWidth();
409  height = I.getHeight();
410  m_frameCount = m_imSequence->getImageNumber();
411  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
412  if (m_frameCount + m_frameStep > m_lastFrame) {
413  m_imSequence->setImageNumber(m_frameCount);
414  } else if (m_frameCount + m_frameStep < m_firstFrame) {
415  m_imSequence->setImageNumber(m_frameCount);
416  }
417  } catch (...) {
418  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
419  return false;
420  }
421  } else {
422 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000)
423  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
424  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
425  return false;
426  }
427 
428  m_capture >> m_frame;
429  m_frameCount = frame_index + m_frameStep; // next index
430  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
431  if (m_frame.empty()) {
432  // New trial that makes things working with opencv 3.0.0
433  m_capture >> m_frame;
434  if (m_frame.empty()) {
435  setLastFrameIndex(m_frameCount - m_frameStep);
436  return false;
437  } else {
438  vpImageConvert::convert(m_frame, I);
439  }
440  } else
441  vpImageConvert::convert(m_frame, I);
442 #elif defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)
443  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
444  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
445  return false;
446  }
447 
448  m_capture >> m_frame;
449  m_frameCount = frame_index + m_frameStep; // next index
450  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
451  if (m_frame.empty())
452  setLastFrameIndex(m_frameCount - m_frameStep);
453  else
454  vpImageConvert::convert(m_frame, I);
455 #endif
456  }
457  return true;
458 }
459 
474 {
475  if (m_imSequence != NULL) {
476  try {
477  m_imSequence->acquire(I, frame_index);
478  width = I.getWidth();
479  height = I.getHeight();
480  m_frameCount = m_imSequence->getImageNumber();
481  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
482  if (m_frameCount + m_frameStep > m_lastFrame) {
483  m_imSequence->setImageNumber(m_frameCount);
484  } else if (m_frameCount + m_frameStep < m_firstFrame) {
485  m_imSequence->setImageNumber(m_frameCount);
486  }
487  } catch (...) {
488  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
489  return false;
490  }
491  } else {
492 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
493  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
494  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
495  return false;
496  }
497  m_capture >> m_frame;
498  if (m_frame.empty()) {
499  // New trial that makes things working with opencv 3.0.0
500  m_capture >> m_frame;
501  if (m_frame.empty()) {
502  setLastFrameIndex(m_frameCount - m_frameStep);
503  return false;
504  } else {
505  vpImageConvert::convert(m_frame, I);
506  }
507  } else {
508  vpImageConvert::convert(m_frame, I);
509  }
510 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
511  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
512  vpERROR_TRACE("Couldn't find the %ld th frame",
513  frame_index); // next index
514  return false;
515  }
516  m_capture >> m_frame;
517  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
518  if (m_frameStep > 1) {
519  m_frameCount += m_frameStep - 1; // next index
520  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
521  } else if (m_frameStep < -1) {
522  m_frameCount += m_frameStep - 1; // next index
523  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
524  }
525  if (m_frame.empty())
526  setLastFrameIndex(m_frameCount - m_frameStep);
527  else
528  vpImageConvert::convert(m_frame, I);
529 #endif
530  }
531  return true;
532 }
533 
539 vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(const std::string &filename) const
540 {
541  std::string ext = vpVideoReader::getExtension(filename);
542 
543  if (ext.compare(".PGM") == 0)
544  return FORMAT_PGM;
545  else if (ext.compare(".pgm") == 0)
546  return FORMAT_PGM;
547  else if (ext.compare(".PPM") == 0)
548  return FORMAT_PPM;
549  else if (ext.compare(".ppm") == 0)
550  return FORMAT_PPM;
551  else if (ext.compare(".JPG") == 0)
552  return FORMAT_JPEG;
553  else if (ext.compare(".jpg") == 0)
554  return FORMAT_JPEG;
555  else if (ext.compare(".JPEG") == 0)
556  return FORMAT_JPEG;
557  else if (ext.compare(".jpeg") == 0)
558  return FORMAT_JPEG;
559  else if (ext.compare(".PNG") == 0)
560  return FORMAT_PNG;
561  else if (ext.compare(".png") == 0)
562  return FORMAT_PNG;
563  else if (ext.compare(".TIFF") == 0)
564  return FORMAT_TIFF;
565  else if (ext.compare(".tiff") == 0)
566  return FORMAT_TIFF;
567  else if (ext.compare(".BMP") == 0)
568  return FORMAT_BMP;
569  else if (ext.compare(".bmp") == 0)
570  return FORMAT_BMP;
571  else if (ext.compare(".DIB") == 0)
572  return FORMAT_DIB;
573  else if (ext.compare(".dib") == 0)
574  return FORMAT_DIB;
575  else if (ext.compare(".PBM") == 0)
576  return FORMAT_PBM;
577  else if (ext.compare(".pbm") == 0)
578  return FORMAT_PBM;
579  else if (ext.compare(".SR") == 0)
580  return FORMAT_PBM;
581  else if (ext.compare(".sr") == 0)
582  return FORMAT_PBM;
583  else if (ext.compare(".RAS") == 0)
584  return FORMAT_RASTER;
585  else if (ext.compare(".ras") == 0)
586  return FORMAT_RASTER;
587  else if (ext.compare(".JP2") == 0)
588  return FORMAT_JPEG2000;
589  else if (ext.compare(".jp2") == 0)
590  return FORMAT_JPEG2000;
591  else if (ext.compare(".AVI") == 0)
592  return FORMAT_AVI;
593  else if (ext.compare(".avi") == 0)
594  return FORMAT_AVI;
595  else if (ext.compare(".MPEG") == 0)
596  return FORMAT_MPEG;
597  else if (ext.compare(".mpeg") == 0)
598  return FORMAT_MPEG;
599  else if (ext.compare(".MPG") == 0)
600  return FORMAT_MPEG;
601  else if (ext.compare(".mpg") == 0)
602  return FORMAT_MPEG;
603  else if (ext.compare(".MPEG4") == 0)
604  return FORMAT_MPEG4;
605  else if (ext.compare(".mpeg4") == 0)
606  return FORMAT_MPEG4;
607  else if (ext.compare(".MP4") == 0)
608  return FORMAT_MPEG4;
609  else if (ext.compare(".mp4") == 0)
610  return FORMAT_MPEG4;
611  else if (ext.compare(".MOV") == 0)
612  return FORMAT_MOV;
613  else if (ext.compare(".mov") == 0)
614  return FORMAT_MOV;
615  else if (ext.compare(".OGV") == 0)
616  return FORMAT_OGV;
617  else if (ext.compare(".ogv") == 0)
618  return FORMAT_OGV;
619  else if (ext.compare(".WMV") == 0)
620  return FORMAT_WMV;
621  else if (ext.compare(".wmv") == 0)
622  return FORMAT_WMV;
623  else if (ext.compare(".FLV") == 0)
624  return FORMAT_FLV;
625  else if (ext.compare(".flv") == 0)
626  return FORMAT_FLV;
627  else if (ext.compare(".MKV") == 0)
628  return FORMAT_MKV;
629  else if (ext.compare(".mkv") == 0)
630  return FORMAT_MKV;
631  else if (ext.compare(".MTS") == 0)
632  return FORMAT_MTS;
633  else if (ext.compare(".mts") == 0)
634  return FORMAT_MTS;
635  else
636  return FORMAT_UNKNOWN;
637 }
638 
639 // return the extension of the file including the dot
640 std::string vpVideoReader::getExtension(const std::string &filename)
641 {
642  // extract the extension
643  size_t dot = filename.find_last_of(".");
644  std::string ext = filename.substr(dot, filename.size() - 1);
645  return ext;
646 }
647 
651 void vpVideoReader::findLastFrameIndex()
652 {
653  if (!m_isOpen) {
654  vpERROR_TRACE("Use the open method before");
655  throw(vpException(vpException::notInitialized, "file not yet opened"));
656  }
657 
658  if (m_imSequence != NULL) {
659  if (!m_lastFrameIndexIsSet) {
660  std::string imageNameFormat = vpIoTools::getName(m_fileName);
661  std::string dirName = vpIoTools::getParent(m_fileName);
662  if (dirName == "") {
663  dirName = ".";
664  }
665  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
666  m_lastFrame = 0;
667  for (size_t i = 0; i < files.size(); i++) {
668  // Checking that file name satisfies image format,
669  // specified by imageNameFormat, and extracting imageIndex
670  long imageIndex = extractImageIndex(files[i], imageNameFormat);
671  if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
672  m_lastFrame = imageIndex;
673  }
674  }
675  }
676  }
677 
678 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
679  else if (!m_lastFrameIndexIsSet) {
680  m_lastFrame = (long)m_capture.get(cv::CAP_PROP_FRAME_COUNT);
681  if (m_lastFrame <= 2) {
682  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
683  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
684  // We set video last frame to an arbitrary value 100000 and set a flag
685  m_lastframe_unknown = true;
686  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
687  }
688  }
689 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
690  else if (!m_lastFrameIndexIsSet) {
691  m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
692  if (m_lastFrame <= 2) {
693  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
694  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
695  // We set video last frame to an arbitrary value 100000 and set a flag
696  m_lastframe_unknown = true;
697  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
698  }
699  }
700 #endif
701 }
702 
706 void vpVideoReader::findFirstFrameIndex()
707 {
708  if (m_imSequence != NULL) {
709  if (!m_firstFrameIndexIsSet) {
710  std::string imageNameFormat = vpIoTools::getName(m_fileName);
711  std::string dirName = vpIoTools::getParent(m_fileName);
712  if (dirName == "") {
713  dirName = ".";
714  }
715  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
716  m_firstFrame = -1;
717  for (size_t i = 0; i < files.size(); i++) {
718  // Checking that file name satisfies image format, specified by
719  // imageNameFormat, and extracting imageIndex
720  long imageIndex = extractImageIndex(files[i], imageNameFormat);
721  if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
722  m_firstFrame = imageIndex;
723  }
724  }
725  m_imSequence->setImageNumber(m_firstFrame);
726  }
727  }
728 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
729  else if (!m_firstFrameIndexIsSet) {
730  m_firstFrame = 1L;
731  }
732 #endif
733 }
734 
738 bool vpVideoReader::isImageExtensionSupported() const
739 {
740  return (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
741  m_formatType == FORMAT_PNG || m_formatType == FORMAT_TIFF || m_formatType == FORMAT_BMP ||
742  m_formatType == FORMAT_DIB || m_formatType == FORMAT_PBM || m_formatType == FORMAT_RASTER ||
743  m_formatType == FORMAT_JPEG2000);
744 }
745 
749 bool vpVideoReader::isVideoExtensionSupported() const
750 {
751  return (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
752  m_formatType == FORMAT_MOV || m_formatType == FORMAT_OGV || m_formatType == FORMAT_WMV ||
753  m_formatType == FORMAT_FLV || m_formatType == FORMAT_MKV || m_formatType == FORMAT_MTS);
754 }
755 
781 {
782  this->acquire(I);
783  return *this;
784 }
785 
811 {
812  this->acquire(I);
813  return *this;
814 }
815 
827 long vpVideoReader::extractImageIndex(const std::string &imageName, const std::string &format) const
828 {
829  size_t indexBegin = format.find_last_of('%');
830  size_t indexEnd = format.find_first_of('d', indexBegin);
831  size_t suffixLength = format.length() - indexEnd - 1;
832 
833  // Extracting index
834  if (imageName.length() <= suffixLength + indexBegin) {
835  return -1;
836  }
837  size_t indexLength = imageName.length() - suffixLength - indexBegin;
838  std::string indexSubstr = imageName.substr(indexBegin, indexLength);
839  std::istringstream ss(indexSubstr);
840  long index = 0;
841  ss >> index;
842  if (ss.fail() || index < 0 || !ss.eof()) {
843  return -1;
844  }
845 
846  // Checking that format with inserted index equals imageName
847  char nameByFormat[FILENAME_MAX];
848  sprintf(nameByFormat, format.c_str(), index);
849  if (std::string(nameByFormat) != imageName) {
850  return -1;
851  }
852  return index;
853 }
854 
859 bool vpVideoReader::checkImageNameFormat(const std::string &format) const
860 {
861  size_t indexBegin = format.find_last_of('%');
862  size_t indexEnd = format.find_first_of('d', indexBegin);
863  if (indexBegin == std::string::npos || indexEnd == std::string::npos) {
864  return false;
865  }
866  for (size_t i = indexBegin + 1; i < indexEnd; i++) {
867  if (!std::isdigit(format[i])) {
868  return false;
869  }
870  }
871  return true;
872 }
873 
882 {
883  // Video format
884  switch (m_formatType) {
885  case FORMAT_AVI:
886  case FORMAT_MPEG:
887  case FORMAT_MPEG4:
888  case FORMAT_MTS:
889  case FORMAT_MOV:
890  case FORMAT_OGV:
891  case FORMAT_WMV:
892  case FORMAT_FLV:
893  case FORMAT_MKV:
894  return true;
895  default:
896  return false;
897  }
898 }
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
void setGenericName(const std::string &genericName)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
#define vpERROR_TRACE
Definition: vpDebug.h:393
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void setStep(long step)
error that can be emited by ViSP classes.
Definition: vpException.h:71
Error that can be emited by the vpImage class and its derivates.
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:1705
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1382
void open(vpImage< vpRGBa > &I)
bool getFrame(vpImage< vpRGBa > &I, long frame)
bool isVideoFormat() const
unsigned int height
Number of rows in the image.
void acquire(vpImage< vpRGBa > &I)
void setImageNumber(long number)
vpVideoReader & operator>>(vpImage< unsigned char > &I)
Class to grab (ie. read) images from the disk.
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1347
Base class for all video devices. It is designed to provide a front end to video sources.
virtual ~vpVideoReader()
long getImageNumber()
void setLastFrameIndex(const long last_frame)
unsigned int getHeight() const
Definition: vpImage.h:188
Used to indicate that a parameter is not initialized.
Definition: vpException.h:98
void setFileName(const std::string &filename)
void acquire(vpImage< unsigned char > &I)
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int width
Number of columns in the image.