Visual Servoing Platform  version 3.3.1 under development (2020-05-29)
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_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_fileName.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 VISP_HAVE_OPENCV_VERSION >= 0x020100
136  m_capture.open(m_fileName.c_str());
137 
138  if (!m_capture.isOpened()) {
139  throw(vpException(vpException::ioError, "Could not open the video %s with OpenCV", m_fileName.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 VISP_HAVE_OPENCV_VERSION >= 0x020100
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 VISP_HAVE_OPENCV_VERSION >= 0x020100
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  // getFrame(I,m_frameCount);
250  if (m_imSequence != NULL) {
251  m_imSequence->setStep(m_frameStep);
252  m_imSequence->acquire(I);
253  m_frameCount = m_imSequence->getImageNumber();
254  if (m_frameCount + m_frameStep > m_lastFrame) {
255  m_imSequence->setImageNumber(m_frameCount);
256  } else if (m_frameCount + m_frameStep < m_firstFrame) {
257  m_imSequence->setImageNumber(m_frameCount);
258  }
259  }
260 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
261  else {
262  m_capture >> m_frame;
263  if (m_frameStep == 1) {
264  m_frameCount++;
265  } else {
266 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
267  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
268  if (m_frameStep > 0) {
269  if (m_frameCount + m_frameStep <= m_lastFrame) {
270  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
271  } else {
272  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
273  }
274  } else if (m_frameStep < 0) {
275  if (m_frameCount + m_frameStep >= m_firstFrame) {
276  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
277  } else {
278  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
279  }
280  }
281 #else
282  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
283  if (m_frameStep > 0) {
284  if (m_frameCount + m_frameStep <= m_lastFrame) {
285  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
286  } else {
287  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
288  }
289  } else if (m_frameStep < 0) {
290  if (m_frameCount + m_frameStep >= m_firstFrame) {
291  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
292  } else {
293  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
294  }
295  }
296 #endif
297  }
298 
299  if (m_frame.empty()) {
300  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
301  if (m_lastframe_unknown) {
302  // Set last frame to this image index
303  setLastFrameIndex(m_frameCount - m_frameStep);
304  }
305  }
306  else {
307  vpImageConvert::convert(m_frame, I);
308  }
309  }
310 #endif
311 }
312 
322 {
323  if (!m_isOpen) {
324  open(I);
325  }
326 
327  if (m_imSequence != NULL) {
328  m_imSequence->setStep(m_frameStep);
329  m_imSequence->acquire(I);
330  m_frameCount = m_imSequence->getImageNumber();
331  if (m_frameCount + m_frameStep > m_lastFrame) {
332  m_imSequence->setImageNumber(m_frameCount);
333  } else if (m_frameCount + m_frameStep < m_firstFrame) {
334  m_imSequence->setImageNumber(m_frameCount);
335  }
336  }
337 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
338  else {
339  m_capture >> m_frame;
340  if (m_frameStep == 1) {
341  m_frameCount++;
342  } else {
343 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
344  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
345  if (m_frameStep > 0) {
346  if (m_frameCount + m_frameStep <= m_lastFrame) {
347  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
348  } else {
349  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
350  }
351  } else if (m_frameStep < 0) {
352  if (m_frameCount + m_frameStep >= m_firstFrame) {
353  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
354  } else {
355  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
356  }
357  }
358 #else
359  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
360  if (m_frameStep > 0) {
361  if (m_frameCount + m_frameStep <= m_lastFrame) {
362  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
363  } else {
364  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
365  }
366  } else if (m_frameStep < 0) {
367  if (m_frameCount + m_frameStep >= m_firstFrame) {
368  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
369  } else {
370  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
371  }
372  }
373 #endif
374  }
375 
376  if (m_frame.empty()) {
377  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
378  }
379  else {
380  vpImageConvert::convert(m_frame, I);
381  }
382  }
383 #endif
384 }
385 
399 bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
400 {
401  if (m_imSequence != NULL) {
402  try {
403  m_imSequence->acquire(I, frame_index);
404  width = I.getWidth();
405  height = I.getHeight();
406  m_frameCount = m_imSequence->getImageNumber();
407  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
408  if (m_frameCount + m_frameStep > m_lastFrame) {
409  m_imSequence->setImageNumber(m_frameCount);
410  } else if (m_frameCount + m_frameStep < m_firstFrame) {
411  m_imSequence->setImageNumber(m_frameCount);
412  }
413  } catch (...) {
414  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
415  return false;
416  }
417  } else {
418 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000)
419  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
420  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
421  return false;
422  }
423 
424  m_capture >> m_frame;
425  m_frameCount = frame_index + m_frameStep; // next index
426  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
427  if (m_frame.empty()) {
428  // New trial that makes things working with opencv 3.0.0
429  m_capture >> m_frame;
430  if (m_frame.empty()) {
431  setLastFrameIndex(m_frameCount - m_frameStep);
432  return false;
433  } else {
434  vpImageConvert::convert(m_frame, I);
435  }
436  } else
437  vpImageConvert::convert(m_frame, I);
438 #elif defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)
439  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
440  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
441  return false;
442  }
443 
444  m_capture >> m_frame;
445  m_frameCount = frame_index + m_frameStep; // next index
446  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
447  if (m_frame.empty())
448  setLastFrameIndex(m_frameCount - m_frameStep);
449  else
450  vpImageConvert::convert(m_frame, I);
451 #endif
452  }
453  return true;
454 }
455 
470 {
471  if (m_imSequence != NULL) {
472  try {
473  m_imSequence->acquire(I, frame_index);
474  width = I.getWidth();
475  height = I.getHeight();
476  m_frameCount = m_imSequence->getImageNumber();
477  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
478  if (m_frameCount + m_frameStep > m_lastFrame) {
479  m_imSequence->setImageNumber(m_frameCount);
480  } else if (m_frameCount + m_frameStep < m_firstFrame) {
481  m_imSequence->setImageNumber(m_frameCount);
482  }
483  } catch (...) {
484  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
485  return false;
486  }
487  } else {
488 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
489  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
490  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
491  return false;
492  }
493  m_capture >> m_frame;
494  if (m_frame.empty()) {
495  // New trial that makes things working with opencv 3.0.0
496  m_capture >> m_frame;
497  if (m_frame.empty()) {
498  setLastFrameIndex(m_frameCount - m_frameStep);
499  return false;
500  } else {
501  vpImageConvert::convert(m_frame, I);
502  }
503  } else {
504  vpImageConvert::convert(m_frame, I);
505  }
506 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
507  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
508  vpERROR_TRACE("Couldn't find the %ld th frame",
509  frame_index); // next index
510  return false;
511  }
512  m_capture >> m_frame;
513  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
514  if (m_frameStep > 1) {
515  m_frameCount += m_frameStep - 1; // next index
516  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
517  } else if (m_frameStep < -1) {
518  m_frameCount += m_frameStep - 1; // next index
519  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
520  }
521  if (m_frame.empty())
522  setLastFrameIndex(m_frameCount - m_frameStep);
523  else
524  vpImageConvert::convert(m_frame, I);
525 #endif
526  }
527  return true;
528 }
529 
535 vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(const std::string &filename) const
536 {
537  std::string ext = vpVideoReader::getExtension(filename);
538 
539  if (ext.compare(".PGM") == 0)
540  return FORMAT_PGM;
541  else if (ext.compare(".pgm") == 0)
542  return FORMAT_PGM;
543  else if (ext.compare(".PPM") == 0)
544  return FORMAT_PPM;
545  else if (ext.compare(".ppm") == 0)
546  return FORMAT_PPM;
547  else if (ext.compare(".JPG") == 0)
548  return FORMAT_JPEG;
549  else if (ext.compare(".jpg") == 0)
550  return FORMAT_JPEG;
551  else if (ext.compare(".JPEG") == 0)
552  return FORMAT_JPEG;
553  else if (ext.compare(".jpeg") == 0)
554  return FORMAT_JPEG;
555  else if (ext.compare(".PNG") == 0)
556  return FORMAT_PNG;
557  else if (ext.compare(".png") == 0)
558  return FORMAT_PNG;
559  else if (ext.compare(".TIFF") == 0)
560  return FORMAT_TIFF;
561  else if (ext.compare(".tiff") == 0)
562  return FORMAT_TIFF;
563  else if (ext.compare(".BMP") == 0)
564  return FORMAT_BMP;
565  else if (ext.compare(".bmp") == 0)
566  return FORMAT_BMP;
567  else if (ext.compare(".DIB") == 0)
568  return FORMAT_DIB;
569  else if (ext.compare(".dib") == 0)
570  return FORMAT_DIB;
571  else if (ext.compare(".PBM") == 0)
572  return FORMAT_PBM;
573  else if (ext.compare(".pbm") == 0)
574  return FORMAT_PBM;
575  else if (ext.compare(".SR") == 0)
576  return FORMAT_PBM;
577  else if (ext.compare(".sr") == 0)
578  return FORMAT_PBM;
579  else if (ext.compare(".RAS") == 0)
580  return FORMAT_RASTER;
581  else if (ext.compare(".ras") == 0)
582  return FORMAT_RASTER;
583  else if (ext.compare(".JP2") == 0)
584  return FORMAT_JPEG2000;
585  else if (ext.compare(".jp2") == 0)
586  return FORMAT_JPEG2000;
587  else if (ext.compare(".AVI") == 0)
588  return FORMAT_AVI;
589  else if (ext.compare(".avi") == 0)
590  return FORMAT_AVI;
591  else if (ext.compare(".MPEG") == 0)
592  return FORMAT_MPEG;
593  else if (ext.compare(".mpeg") == 0)
594  return FORMAT_MPEG;
595  else if (ext.compare(".MPG") == 0)
596  return FORMAT_MPEG;
597  else if (ext.compare(".mpg") == 0)
598  return FORMAT_MPEG;
599  else if (ext.compare(".MPEG4") == 0)
600  return FORMAT_MPEG4;
601  else if (ext.compare(".mpeg4") == 0)
602  return FORMAT_MPEG4;
603  else if (ext.compare(".MP4") == 0)
604  return FORMAT_MPEG4;
605  else if (ext.compare(".mp4") == 0)
606  return FORMAT_MPEG4;
607  else if (ext.compare(".MOV") == 0)
608  return FORMAT_MOV;
609  else if (ext.compare(".mov") == 0)
610  return FORMAT_MOV;
611  else if (ext.compare(".OGV") == 0)
612  return FORMAT_OGV;
613  else if (ext.compare(".ogv") == 0)
614  return FORMAT_OGV;
615  else if (ext.compare(".WMV") == 0)
616  return FORMAT_WMV;
617  else if (ext.compare(".wmv") == 0)
618  return FORMAT_WMV;
619  else if (ext.compare(".FLV") == 0)
620  return FORMAT_FLV;
621  else if (ext.compare(".flv") == 0)
622  return FORMAT_FLV;
623  else if (ext.compare(".MKV") == 0)
624  return FORMAT_MKV;
625  else if (ext.compare(".mkv") == 0)
626  return FORMAT_MKV;
627  else if (ext.compare(".MTS") == 0)
628  return FORMAT_MTS;
629  else if (ext.compare(".mts") == 0)
630  return FORMAT_MTS;
631  else
632  return FORMAT_UNKNOWN;
633 }
634 
635 // return the extension of the file including the dot
636 std::string vpVideoReader::getExtension(const std::string &filename)
637 {
638  // extract the extension
639  size_t dot = filename.find_last_of(".");
640  std::string ext = filename.substr(dot, filename.size() - 1);
641  return ext;
642 }
643 
647 void vpVideoReader::findLastFrameIndex()
648 {
649  if (!m_isOpen) {
650  vpERROR_TRACE("Use the open method before");
651  throw(vpException(vpException::notInitialized, "file not yet opened"));
652  }
653 
654  if (m_imSequence != NULL) {
655  if (!m_lastFrameIndexIsSet) {
656  std::string imageNameFormat = vpIoTools::getName(m_fileName);
657  std::string dirName = vpIoTools::getParent(m_fileName);
658  if (dirName == "") {
659  dirName = ".";
660  }
661  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
662  m_lastFrame = 0;
663  for (size_t i = 0; i < files.size(); i++) {
664  // Checking that file name satisfies image format,
665  // specified by imageNameFormat, and extracting imageIndex
666  long imageIndex = extractImageIndex(files[i], imageNameFormat);
667  if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
668  m_lastFrame = imageIndex;
669  }
670  }
671  }
672  }
673 
674 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
675  else if (!m_lastFrameIndexIsSet) {
676  m_lastFrame = (long)m_capture.get(cv::CAP_PROP_FRAME_COUNT);
677  if (m_lastFrame <= 2) {
678  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
679  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
680  // We set video last frame to an arbitrary value 100000 and set a flag
681  m_lastframe_unknown = true;
682  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
683  }
684  }
685 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
686  else if (!m_lastFrameIndexIsSet) {
687  m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
688  if (m_lastFrame <= 2) {
689  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
690  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
691  // We set video last frame to an arbitrary value 100000 and set a flag
692  m_lastframe_unknown = true;
693  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
694  }
695  }
696 #endif
697 }
698 
702 void vpVideoReader::findFirstFrameIndex()
703 {
704  if (m_imSequence != NULL) {
705  if (!m_firstFrameIndexIsSet) {
706  std::string imageNameFormat = vpIoTools::getName(m_fileName);
707  std::string dirName = vpIoTools::getParent(m_fileName);
708  if (dirName == "") {
709  dirName = ".";
710  }
711  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
712  m_firstFrame = -1;
713  for (size_t i = 0; i < files.size(); i++) {
714  // Checking that file name satisfies image format, specified by
715  // imageNameFormat, and extracting imageIndex
716  long imageIndex = extractImageIndex(files[i], imageNameFormat);
717  if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
718  m_firstFrame = imageIndex;
719  }
720  }
721  m_imSequence->setImageNumber(m_firstFrame);
722  }
723  }
724 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
725  else if (!m_firstFrameIndexIsSet) {
726  m_firstFrame = 1L;
727  }
728 #endif
729 }
730 
734 bool vpVideoReader::isImageExtensionSupported() const
735 {
736  return (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
737  m_formatType == FORMAT_PNG || m_formatType == FORMAT_TIFF || m_formatType == FORMAT_BMP ||
738  m_formatType == FORMAT_DIB || m_formatType == FORMAT_PBM || m_formatType == FORMAT_RASTER ||
739  m_formatType == FORMAT_JPEG2000);
740 }
741 
745 bool vpVideoReader::isVideoExtensionSupported() const
746 {
747  return (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
748  m_formatType == FORMAT_MOV || m_formatType == FORMAT_OGV || m_formatType == FORMAT_WMV ||
749  m_formatType == FORMAT_FLV || m_formatType == FORMAT_MKV || m_formatType == FORMAT_MTS);
750 }
751 
777 {
778  this->acquire(I);
779  return *this;
780 }
781 
807 {
808  this->acquire(I);
809  return *this;
810 }
811 
823 long vpVideoReader::extractImageIndex(const std::string &imageName, const std::string &format) const
824 {
825  size_t indexBegin = format.find_last_of('%');
826  size_t indexEnd = format.find_first_of('d', indexBegin);
827  size_t suffixLength = format.length() - indexEnd - 1;
828 
829  // Extracting index
830  if (imageName.length() <= suffixLength + indexBegin) {
831  return -1;
832  }
833  size_t indexLength = imageName.length() - suffixLength - indexBegin;
834  std::string indexSubstr = imageName.substr(indexBegin, indexLength);
835  std::istringstream ss(indexSubstr);
836  long index = 0;
837  ss >> index;
838  if (ss.fail() || index < 0 || !ss.eof()) {
839  return -1;
840  }
841 
842  // Checking that format with inserted index equals imageName
843  char nameByFormat[FILENAME_MAX];
844  sprintf(nameByFormat, format.c_str(), index);
845  if (std::string(nameByFormat) != imageName) {
846  return -1;
847  }
848  return index;
849 }
850 
855 bool vpVideoReader::checkImageNameFormat(const std::string &format) const
856 {
857  size_t indexBegin = format.find_last_of('%');
858  size_t indexEnd = format.find_first_of('d', indexBegin);
859  if (indexBegin == std::string::npos || indexEnd == std::string::npos) {
860  return false;
861  }
862  for (size_t i = indexBegin + 1; i < indexEnd; i++) {
863  if (!std::isdigit(format[i])) {
864  return false;
865  }
866  }
867  return true;
868 }
869 
878 {
879  // Video format
880  switch (m_formatType) {
881  case FORMAT_AVI:
882  case FORMAT_MPEG:
883  case FORMAT_MPEG4:
884  case FORMAT_MTS:
885  case FORMAT_MOV:
886  case FORMAT_OGV:
887  case FORMAT_WMV:
888  case FORMAT_FLV:
889  case FORMAT_MKV:
890  return true;
891  default:
892  return false;
893  }
894 }
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:1706
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1383
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:1348
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.