Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpVideoReader.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 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/vpIoTools.h>
40 #include <visp3/io/vpVideoReader.h>
41 
42 #include <cctype>
43 #include <fstream>
44 #include <iostream>
45 
47 
52  : vpFrameGrabber(), m_imSequence(nullptr),
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 
65 {
66  if (m_imSequence != nullptr) {
67  delete m_imSequence;
68  }
69 }
70 
86 void vpVideoReader::setFileName(const std::string &filename)
87 {
88  if (filename.empty()) {
89  throw(vpImageException(vpImageException::noFileNameError, "filename empty "));
90  }
91 
92  m_videoName = filename;
93  m_frameName = filename;
94 
95  m_formatType = getFormat(filename);
96 
97  if (m_formatType == FORMAT_UNKNOWN) {
98  throw(vpException(vpException::badValue, "Filename extension not supported"));
99  }
100 
101  // checking image name format
102  if (isImageExtensionSupported()) {
103  std::string format = vpIoTools::getName(m_videoName);
104  if (!checkImageNameFormat(format)) {
105  throw(vpException(vpException::badValue, "Format of image name wasn't recognized: %s", format.c_str()));
106  }
107  }
108 
109  m_initFileName = true;
110 }
111 
115 void vpVideoReader::getProperties()
116 {
117  if (m_isOpen) {
118  return;
119  }
120 
121  if (!m_initFileName) {
122  throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set"));
123  }
124 
125  if (isImageExtensionSupported()) {
126  m_imSequence = new vpDiskGrabber;
127  m_imSequence->setGenericName(m_videoName.c_str());
128  m_imSequence->setStep(m_frameStep);
129  if (m_firstFrameIndexIsSet) {
130  m_imSequence->setImageNumber(m_firstFrame);
131  }
132  m_frameRate = -1.;
133  }
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  }
156  else if (m_formatType == FORMAT_UNKNOWN) {
157  throw(vpException(vpException::fatalError, "The format of the file does "
158  "not correspond to a readable "
159  "format supported by ViSP."));
160  }
161 
162  findFirstFrameIndex();
163  m_isOpen = true;
164  findLastFrameIndex();
165 }
166 
175 {
176  getProperties();
177 
178  m_frameCount = m_firstFrame;
179  if (!getFrame(I, m_firstFrame)) {
180  throw(vpException(vpException::ioError, "Could not read the video first frame"));
181  }
182 
183  // Rewind to the first frame since open() should not increase the frame
184  // counter
185  m_frameCount = m_firstFrame;
186 
187  if (isVideoExtensionSupported()) {
188 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
189 
190 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
191  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
192 #else
193  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
194 #endif
195  m_frameCount--;
196 #endif
197  }
198 }
199 
208 {
209  getProperties();
210 
211  m_frameCount = m_firstFrame;
212  if (!getFrame(I, m_firstFrame)) {
213  throw(vpException(vpException::ioError, "Could not read the video first frame"));
214  }
215 
216  // Rewind to the first frame since open() should not increase the frame
217  // counter
218  m_frameCount = m_firstFrame;
219 
220  if (isVideoExtensionSupported()) {
221 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
222 
223 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
224  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
225 #else
226  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
227 #endif
228  m_frameCount--;
229 #endif
230  }
231 }
232 
244 {
245  if (!m_isOpen) {
246  open(I);
247  }
248  if (m_imSequence != nullptr) {
249  m_imSequence->setStep(m_frameStep);
250  bool skip_frame = false;
251  do {
252  try {
253  m_imSequence->acquire(I);
254  skip_frame = false;
255  }
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  }
265  else if (m_frameCount + m_frameStep < m_firstFrame) {
266  m_imSequence->setImageNumber(m_frameCount);
267  }
268  }
269 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
270  else {
271  m_capture >> m_frame;
272  if (m_frameStep == 1) {
273  ++m_frameCount;
274  }
275  else {
276 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
277  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
278  if (m_frameStep > 0) {
279  if (m_frameCount + m_frameStep <= m_lastFrame) {
280  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
281  }
282  else {
283  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
284  }
285  }
286  else if (m_frameStep < 0) {
287  if (m_frameCount + m_frameStep >= m_firstFrame) {
288  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
289  }
290  else {
291  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
292  }
293  }
294 #else
295  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
296  if (m_frameStep > 0) {
297  if (m_frameCount + m_frameStep <= m_lastFrame) {
298  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
299  }
300  else {
301  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
302  }
303  }
304  else if (m_frameStep < 0) {
305  if (m_frameCount + m_frameStep >= m_firstFrame) {
306  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
307  }
308  else {
309  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
310  }
311  }
312 #endif
313  }
314 
315  if (m_frame.empty()) {
316  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
317  if (m_lastframe_unknown) {
318  // Set last frame to this image index
319  setLastFrameIndex(m_frameCount - m_frameStep);
320  }
321  }
322  else {
323  vpImageConvert::convert(m_frame, I);
324  }
325  }
326 #endif
327 }
328 
338 {
339  if (!m_isOpen) {
340  open(I);
341  }
342 
343  if (m_imSequence != nullptr) {
344  m_imSequence->setStep(m_frameStep);
345  bool skip_frame = false;
346  do {
347  try {
348  m_imSequence->acquire(I);
349  skip_frame = false;
350  }
351  catch (...) {
352  skip_frame = true;
353  }
354  } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
355  m_frameCount = m_imSequence->getImageNumber();
356  m_frameName = m_imSequence->getImageName();
357  if (m_frameCount + m_frameStep > m_lastFrame) {
358  m_imSequence->setImageNumber(m_frameCount);
359  }
360  else if (m_frameCount + m_frameStep < m_firstFrame) {
361  m_imSequence->setImageNumber(m_frameCount);
362  }
363  }
364 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
365  else {
366  m_capture >> m_frame;
367  if (m_frameStep == 1) {
368  ++m_frameCount;
369  }
370  else {
371 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
372  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
373  if (m_frameStep > 0) {
374  if (m_frameCount + m_frameStep <= m_lastFrame) {
375  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
376  }
377  else {
378  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
379  }
380  }
381  else if (m_frameStep < 0) {
382  if (m_frameCount + m_frameStep >= m_firstFrame) {
383  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
384  }
385  else {
386  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
387  }
388  }
389 #else
390  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
391  if (m_frameStep > 0) {
392  if (m_frameCount + m_frameStep <= m_lastFrame) {
393  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
394  }
395  else {
396  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
397  }
398  }
399  else if (m_frameStep < 0) {
400  if (m_frameCount + m_frameStep >= m_firstFrame) {
401  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
402  }
403  else {
404  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
405  }
406  }
407 #endif
408  }
409 
410  if (m_frame.empty()) {
411  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
412  }
413  else {
414  vpImageConvert::convert(m_frame, I);
415  }
416  }
417 #endif
418 }
419 
433 bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
434 {
435  if (m_imSequence != nullptr) {
436  try {
437  m_imSequence->acquire(I, frame_index);
438  width = I.getWidth();
439  height = I.getHeight();
440  m_frameCount = m_imSequence->getImageNumber();
441  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
442  if (m_frameCount + m_frameStep > m_lastFrame) {
443  m_imSequence->setImageNumber(m_frameCount);
444  }
445  else if (m_frameCount + m_frameStep < m_firstFrame) {
446  m_imSequence->setImageNumber(m_frameCount);
447  }
448  }
449  catch (...) {
450  // Couldn't find the %u th frame", frame_index
451  return false;
452  }
453  }
454  else {
455 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
456 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
457  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
458  // Couldn't find the %ld th frame", frame_index
459  return false;
460  }
461 
462  m_capture >> m_frame;
463  m_frameCount = frame_index + m_frameStep; // next index
464  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
465  if (m_frame.empty()) {
466  // New trial that makes things working with opencv 3.0.0
467  m_capture >> m_frame;
468  if (m_frame.empty()) {
469  setLastFrameIndex(m_frameCount - m_frameStep);
470  return false;
471  }
472  else {
473  vpImageConvert::convert(m_frame, I);
474  }
475  }
476  else
477  vpImageConvert::convert(m_frame, I);
478 #else
479  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
480  // Couldn't find the %ld th frame", frame_index
481  return false;
482  }
483 
484  m_capture >> m_frame;
485  m_frameCount = frame_index + m_frameStep; // next index
486  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
487  if (m_frame.empty())
488  setLastFrameIndex(m_frameCount - m_frameStep);
489  else
490  vpImageConvert::convert(m_frame, I);
491 #endif
492 #endif
493  }
494  return true;
495 }
496 
511 {
512  if (m_imSequence != nullptr) {
513  try {
514  m_imSequence->acquire(I, frame_index);
515  width = I.getWidth();
516  height = I.getHeight();
517  m_frameCount = m_imSequence->getImageNumber();
518  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
519  if (m_frameCount + m_frameStep > m_lastFrame) {
520  m_imSequence->setImageNumber(m_frameCount);
521  }
522  else if (m_frameCount + m_frameStep < m_firstFrame) {
523  m_imSequence->setImageNumber(m_frameCount);
524  }
525  }
526  catch (...) {
527  // Couldn't find the %u th frame", frame_index
528  return false;
529  }
530  }
531  else {
532 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
533 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
534  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
535  // Couldn't find the %ld th frame", frame_index
536  return false;
537  }
538  m_capture >> m_frame;
539  if (m_frame.empty()) {
540  // New trial that makes things working with opencv 3.0.0
541  m_capture >> m_frame;
542  if (m_frame.empty()) {
543  setLastFrameIndex(m_frameCount - m_frameStep);
544  return false;
545  }
546  else {
547  vpImageConvert::convert(m_frame, I);
548  }
549  }
550  else {
551  vpImageConvert::convert(m_frame, I);
552  }
553 #else
554  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
555  // Couldn't find the %ld th frame", frame_index
556  return false;
557  }
558  m_capture >> m_frame;
559  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
560  if (m_frameStep > 1) {
561  m_frameCount += m_frameStep - 1; // next index
562  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
563  }
564  else if (m_frameStep < -1) {
565  m_frameCount += m_frameStep - 1; // next index
566  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
567  }
568  if (m_frame.empty())
569  setLastFrameIndex(m_frameCount - m_frameStep);
570  else
571  vpImageConvert::convert(m_frame, I);
572 #endif
573 #endif
574  }
575  return true;
576 }
577 
583 vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(const std::string &filename) const
584 {
585  std::string ext = vpVideoReader::getExtension(filename);
586 
587  if (ext.compare(".PGM") == 0)
588  return FORMAT_PGM;
589  else if (ext.compare(".pgm") == 0)
590  return FORMAT_PGM;
591  else if (ext.compare(".PPM") == 0)
592  return FORMAT_PPM;
593  else if (ext.compare(".ppm") == 0)
594  return FORMAT_PPM;
595  else if (ext.compare(".JPG") == 0)
596  return FORMAT_JPEG;
597  else if (ext.compare(".jpg") == 0)
598  return FORMAT_JPEG;
599  else if (ext.compare(".JPEG") == 0)
600  return FORMAT_JPEG;
601  else if (ext.compare(".jpeg") == 0)
602  return FORMAT_JPEG;
603  else if (ext.compare(".PNG") == 0)
604  return FORMAT_PNG;
605  else if (ext.compare(".png") == 0)
606  return FORMAT_PNG;
607  else if (ext.compare(".TIFF") == 0)
608  return FORMAT_TIFF;
609  else if (ext.compare(".tiff") == 0)
610  return FORMAT_TIFF;
611  else if (ext.compare(".BMP") == 0)
612  return FORMAT_BMP;
613  else if (ext.compare(".bmp") == 0)
614  return FORMAT_BMP;
615  else if (ext.compare(".DIB") == 0)
616  return FORMAT_DIB;
617  else if (ext.compare(".dib") == 0)
618  return FORMAT_DIB;
619  else if (ext.compare(".PBM") == 0)
620  return FORMAT_PBM;
621  else if (ext.compare(".pbm") == 0)
622  return FORMAT_PBM;
623  else if (ext.compare(".SR") == 0)
624  return FORMAT_PBM;
625  else if (ext.compare(".sr") == 0)
626  return FORMAT_PBM;
627  else if (ext.compare(".RAS") == 0)
628  return FORMAT_RASTER;
629  else if (ext.compare(".ras") == 0)
630  return FORMAT_RASTER;
631  else if (ext.compare(".JP2") == 0)
632  return FORMAT_JPEG2000;
633  else if (ext.compare(".jp2") == 0)
634  return FORMAT_JPEG2000;
635  else if (ext.compare(".AVI") == 0)
636  return FORMAT_AVI;
637  else if (ext.compare(".avi") == 0)
638  return FORMAT_AVI;
639  else if (ext.compare(".MPEG") == 0)
640  return FORMAT_MPEG;
641  else if (ext.compare(".mpeg") == 0)
642  return FORMAT_MPEG;
643  else if (ext.compare(".MPG") == 0)
644  return FORMAT_MPEG;
645  else if (ext.compare(".mpg") == 0)
646  return FORMAT_MPEG;
647  else if (ext.compare(".MPEG4") == 0)
648  return FORMAT_MPEG4;
649  else if (ext.compare(".mpeg4") == 0)
650  return FORMAT_MPEG4;
651  else if (ext.compare(".MP4") == 0)
652  return FORMAT_MPEG4;
653  else if (ext.compare(".mp4") == 0)
654  return FORMAT_MPEG4;
655  else if (ext.compare(".MOV") == 0)
656  return FORMAT_MOV;
657  else if (ext.compare(".mov") == 0)
658  return FORMAT_MOV;
659  else if (ext.compare(".OGV") == 0)
660  return FORMAT_OGV;
661  else if (ext.compare(".ogv") == 0)
662  return FORMAT_OGV;
663  else if (ext.compare(".WMV") == 0)
664  return FORMAT_WMV;
665  else if (ext.compare(".wmv") == 0)
666  return FORMAT_WMV;
667  else if (ext.compare(".FLV") == 0)
668  return FORMAT_FLV;
669  else if (ext.compare(".flv") == 0)
670  return FORMAT_FLV;
671  else if (ext.compare(".MKV") == 0)
672  return FORMAT_MKV;
673  else if (ext.compare(".mkv") == 0)
674  return FORMAT_MKV;
675  else if (ext.compare(".MTS") == 0)
676  return FORMAT_MTS;
677  else if (ext.compare(".mts") == 0)
678  return FORMAT_MTS;
679  else
680  return FORMAT_UNKNOWN;
681 }
682 
683 // return the extension of the file including the dot
684 std::string vpVideoReader::getExtension(const std::string &filename)
685 {
686  // extract the extension
687  size_t dot = filename.find_last_of(".");
688  std::string ext = filename.substr(dot, filename.size() - 1);
689  return ext;
690 }
691 
695 void vpVideoReader::findLastFrameIndex()
696 {
697  if (!m_isOpen) {
698  throw(vpException(vpException::notInitialized, "File not yet opened. Use the open() method before"));
699  }
700 
701  if (m_imSequence != nullptr) {
702  if (!m_lastFrameIndexIsSet) {
703  std::string imageNameFormat = vpIoTools::getName(m_videoName);
704  std::string dirName = vpIoTools::getParent(m_videoName);
705  if (dirName == "") {
706  dirName = ".";
707  }
708  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
709  m_lastFrame = 0;
710  for (size_t i = 0; i < files.size(); ++i) {
711  // Checking that file name satisfies image format,
712  // specified by imageNameFormat, and extracting imageIndex
713  long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
714  if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
715  m_lastFrame = imageIndex;
716  }
717  }
718  }
719  }
720 
721 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
722 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
723  else if (!m_lastFrameIndexIsSet) {
724  m_lastFrame = (long)m_capture.get(cv::CAP_PROP_FRAME_COUNT);
725  if (m_lastFrame <= 2) {
726  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
727  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
728  // We set video last frame to an arbitrary value 100000 and set a flag
729  m_lastframe_unknown = true;
730  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
731  }
732  }
733 #else
734  else if (!m_lastFrameIndexIsSet) {
735  m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
736  if (m_lastFrame <= 2) {
737  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
738  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
739  // We set video last frame to an arbitrary value 100000 and set a flag
740  m_lastframe_unknown = true;
741  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
742  }
743  }
744 #endif
745 #endif
746 }
747 
751 void vpVideoReader::findFirstFrameIndex()
752 {
753  if (m_imSequence != nullptr) {
754  if (!m_firstFrameIndexIsSet) {
755  std::string imageNameFormat = vpIoTools::getName(m_videoName);
756  std::string dirName = vpIoTools::getParent(m_videoName);
757  if (dirName == "") {
758  dirName = ".";
759  }
760  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
761  m_firstFrame = -1;
762  for (size_t i = 0; i < files.size(); ++i) {
763  // Checking that file name satisfies image format, specified by
764  // imageNameFormat, and extracting imageIndex
765  long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
766 
767  if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
768  m_firstFrame = imageIndex;
769  }
770  }
771  m_imSequence->setImageNumber(m_firstFrame);
772  }
773  }
774 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
775 
776  else if (!m_firstFrameIndexIsSet) {
777  m_firstFrame = 1L;
778  }
779 #endif
780 }
781 
785 bool vpVideoReader::isImageExtensionSupported() const
786 {
787  return (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
788  m_formatType == FORMAT_PNG || m_formatType == FORMAT_TIFF || m_formatType == FORMAT_BMP ||
789  m_formatType == FORMAT_DIB || m_formatType == FORMAT_PBM || m_formatType == FORMAT_RASTER ||
790  m_formatType == FORMAT_JPEG2000);
791 }
792 
796 bool vpVideoReader::isVideoExtensionSupported() const
797 {
798  return (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
799  m_formatType == FORMAT_MOV || m_formatType == FORMAT_OGV || m_formatType == FORMAT_WMV ||
800  m_formatType == FORMAT_FLV || m_formatType == FORMAT_MKV || m_formatType == FORMAT_MTS);
801 }
802 
831 {
832  this->acquire(I);
833  return *this;
834 }
835 
864 {
865  this->acquire(I);
866  return *this;
867 }
868 
873 bool vpVideoReader::checkImageNameFormat(const std::string &format) const
874 {
875  size_t indexBegin = format.find_last_of('%');
876  size_t indexEnd = format.find_first_of('d', indexBegin);
877  if (indexBegin == std::string::npos || indexEnd == std::string::npos) {
878  return false;
879  }
880  for (size_t i = indexBegin + 1; i < indexEnd; ++i) {
881  if (!std::isdigit(format[i])) {
882  return false;
883  }
884  }
885  return true;
886 }
887 
896 {
897  // Video format
898  switch (m_formatType) {
899  case FORMAT_AVI:
900  case FORMAT_MPEG:
901  case FORMAT_MPEG4:
902  case FORMAT_MTS:
903  case FORMAT_MOV:
904  case FORMAT_OGV:
905  case FORMAT_WMV:
906  case FORMAT_FLV:
907  case FORMAT_MKV:
908  return true;
909  default:
910  return false;
911  }
912 }
913 
914 END_VISP_NAMESPACE
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:60
@ ioError
I/O error.
Definition: vpException.h:67
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition: vpException.h:74
@ fatalError
Fatal error.
Definition: vpException.h:72
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:181
static long getIndex(const std::string &filename, const std::string &format)
Definition: vpIoTools.cpp:1272
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:1692
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1314
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1205
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)