Visual Servoing Platform  version 3.6.1 under development (2024-04-22)
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(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  // vpERROR_TRACE("The format of the file does not correspond to a readable
158  // format.");
159  throw(vpException(vpException::fatalError, "The format of the file does "
160  "not correspond to a readable "
161  "format supported by ViSP."));
162  }
163 
164  findFirstFrameIndex();
165  m_isOpen = true;
166  findLastFrameIndex();
167 }
168 
177 {
178  getProperties();
179 
180  m_frameCount = m_firstFrame;
181  if (!getFrame(I, m_firstFrame)) {
182  throw(vpException(vpException::ioError, "Could not read the video first frame"));
183  }
184 
185  // Rewind to the first frame since open() should not increase the frame
186  // counter
187  m_frameCount = m_firstFrame;
188 
189  if (isVideoExtensionSupported()) {
190 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
191 
192 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
193  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
194 #else
195  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
196 #endif
197  m_frameCount--;
198 #endif
199  }
200 }
201 
210 {
211  getProperties();
212 
213  m_frameCount = m_firstFrame;
214  if (!getFrame(I, m_firstFrame)) {
215  throw(vpException(vpException::ioError, "Could not read the video first frame"));
216  }
217 
218  // Rewind to the first frame since open() should not increase the frame
219  // counter
220  m_frameCount = m_firstFrame;
221 
222  if (isVideoExtensionSupported()) {
223 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
224 
225 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
226  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
227 #else
228  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
229 #endif
230  m_frameCount--;
231 #endif
232  }
233 }
234 
246 {
247  if (!m_isOpen) {
248  open(I);
249  }
250  if (m_imSequence != nullptr) {
251  m_imSequence->setStep(m_frameStep);
252  bool skip_frame = false;
253  do {
254  try {
255  m_imSequence->acquire(I);
256  skip_frame = false;
257  }
258  catch (...) {
259  skip_frame = true;
260  }
261  } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
262  m_frameCount = m_imSequence->getImageNumber();
263  m_frameName = m_imSequence->getImageName();
264  if (m_frameCount + m_frameStep > m_lastFrame) {
265  m_imSequence->setImageNumber(m_frameCount);
266  }
267  else if (m_frameCount + m_frameStep < m_firstFrame) {
268  m_imSequence->setImageNumber(m_frameCount);
269  }
270  }
271 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
272  else {
273  m_capture >> m_frame;
274  if (m_frameStep == 1) {
275  m_frameCount++;
276  }
277  else {
278 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
279  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
280  if (m_frameStep > 0) {
281  if (m_frameCount + m_frameStep <= m_lastFrame) {
282  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
283  }
284  else {
285  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
286  }
287  }
288  else if (m_frameStep < 0) {
289  if (m_frameCount + m_frameStep >= m_firstFrame) {
290  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
291  }
292  else {
293  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
294  }
295  }
296 #else
297  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
298  if (m_frameStep > 0) {
299  if (m_frameCount + m_frameStep <= m_lastFrame) {
300  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
301  }
302  else {
303  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
304  }
305  }
306  else if (m_frameStep < 0) {
307  if (m_frameCount + m_frameStep >= m_firstFrame) {
308  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
309  }
310  else {
311  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
312  }
313  }
314 #endif
315  }
316 
317  if (m_frame.empty()) {
318  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
319  if (m_lastframe_unknown) {
320  // Set last frame to this image index
321  setLastFrameIndex(m_frameCount - m_frameStep);
322  }
323  }
324  else {
325  vpImageConvert::convert(m_frame, I);
326  }
327  }
328 #endif
329 }
330 
340 {
341  if (!m_isOpen) {
342  open(I);
343  }
344 
345  if (m_imSequence != nullptr) {
346  m_imSequence->setStep(m_frameStep);
347  bool skip_frame = false;
348  do {
349  try {
350  m_imSequence->acquire(I);
351  skip_frame = false;
352  }
353  catch (...) {
354  skip_frame = true;
355  }
356  } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
357  m_frameCount = m_imSequence->getImageNumber();
358  m_frameName = m_imSequence->getImageName();
359  if (m_frameCount + m_frameStep > m_lastFrame) {
360  m_imSequence->setImageNumber(m_frameCount);
361  }
362  else if (m_frameCount + m_frameStep < m_firstFrame) {
363  m_imSequence->setImageNumber(m_frameCount);
364  }
365  }
366 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
367  else {
368  m_capture >> m_frame;
369  if (m_frameStep == 1) {
370  m_frameCount++;
371  }
372  else {
373 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
374  m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
375  if (m_frameStep > 0) {
376  if (m_frameCount + m_frameStep <= m_lastFrame) {
377  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
378  }
379  else {
380  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
381  }
382  }
383  else if (m_frameStep < 0) {
384  if (m_frameCount + m_frameStep >= m_firstFrame) {
385  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
386  }
387  else {
388  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
389  }
390  }
391 #else
392  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
393  if (m_frameStep > 0) {
394  if (m_frameCount + m_frameStep <= m_lastFrame) {
395  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
396  }
397  else {
398  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
399  }
400  }
401  else if (m_frameStep < 0) {
402  if (m_frameCount + m_frameStep >= m_firstFrame) {
403  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
404  }
405  else {
406  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
407  }
408  }
409 #endif
410  }
411 
412  if (m_frame.empty()) {
413  std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
414  }
415  else {
416  vpImageConvert::convert(m_frame, I);
417  }
418  }
419 #endif
420 }
421 
435 bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
436 {
437  if (m_imSequence != nullptr) {
438  try {
439  m_imSequence->acquire(I, frame_index);
440  width = I.getWidth();
441  height = I.getHeight();
442  m_frameCount = m_imSequence->getImageNumber();
443  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
444  if (m_frameCount + m_frameStep > m_lastFrame) {
445  m_imSequence->setImageNumber(m_frameCount);
446  }
447  else if (m_frameCount + m_frameStep < m_firstFrame) {
448  m_imSequence->setImageNumber(m_frameCount);
449  }
450  }
451  catch (...) {
452  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
453  return false;
454  }
455  }
456  else {
457 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
458 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
459  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
460  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
461  return false;
462  }
463 
464  m_capture >> m_frame;
465  m_frameCount = frame_index + m_frameStep; // next index
466  m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
467  if (m_frame.empty()) {
468  // New trial that makes things working with opencv 3.0.0
469  m_capture >> m_frame;
470  if (m_frame.empty()) {
471  setLastFrameIndex(m_frameCount - m_frameStep);
472  return false;
473  }
474  else {
475  vpImageConvert::convert(m_frame, I);
476  }
477  }
478  else
479  vpImageConvert::convert(m_frame, I);
480 #else
481  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
482  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
483  return false;
484  }
485 
486  m_capture >> m_frame;
487  m_frameCount = frame_index + m_frameStep; // next index
488  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
489  if (m_frame.empty())
490  setLastFrameIndex(m_frameCount - m_frameStep);
491  else
492  vpImageConvert::convert(m_frame, I);
493 #endif
494 #endif
495  }
496  return true;
497 }
498 
513 {
514  if (m_imSequence != nullptr) {
515  try {
516  m_imSequence->acquire(I, frame_index);
517  width = I.getWidth();
518  height = I.getHeight();
519  m_frameCount = m_imSequence->getImageNumber();
520  m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
521  if (m_frameCount + m_frameStep > m_lastFrame) {
522  m_imSequence->setImageNumber(m_frameCount);
523  }
524  else if (m_frameCount + m_frameStep < m_firstFrame) {
525  m_imSequence->setImageNumber(m_frameCount);
526  }
527  }
528  catch (...) {
529  vpERROR_TRACE("Couldn't find the %u th frame", frame_index);
530  return false;
531  }
532  }
533  else {
534 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
535 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
536  if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
537  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index);
538  return false;
539  }
540  m_capture >> m_frame;
541  if (m_frame.empty()) {
542  // New trial that makes things working with opencv 3.0.0
543  m_capture >> m_frame;
544  if (m_frame.empty()) {
545  setLastFrameIndex(m_frameCount - m_frameStep);
546  return false;
547  }
548  else {
549  vpImageConvert::convert(m_frame, I);
550  }
551  }
552  else {
553  vpImageConvert::convert(m_frame, I);
554  }
555 #else
556  if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
557  vpERROR_TRACE("Couldn't find the %ld th frame",
558  frame_index); // next index
559  return false;
560  }
561  m_capture >> m_frame;
562  m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
563  if (m_frameStep > 1) {
564  m_frameCount += m_frameStep - 1; // next index
565  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
566  }
567  else if (m_frameStep < -1) {
568  m_frameCount += m_frameStep - 1; // next index
569  m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
570  }
571  if (m_frame.empty())
572  setLastFrameIndex(m_frameCount - m_frameStep);
573  else
574  vpImageConvert::convert(m_frame, I);
575 #endif
576 #endif
577  }
578  return true;
579 }
580 
586 vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(const std::string &filename) const
587 {
588  std::string ext = vpVideoReader::getExtension(filename);
589 
590  if (ext.compare(".PGM") == 0)
591  return FORMAT_PGM;
592  else if (ext.compare(".pgm") == 0)
593  return FORMAT_PGM;
594  else if (ext.compare(".PPM") == 0)
595  return FORMAT_PPM;
596  else if (ext.compare(".ppm") == 0)
597  return FORMAT_PPM;
598  else if (ext.compare(".JPG") == 0)
599  return FORMAT_JPEG;
600  else if (ext.compare(".jpg") == 0)
601  return FORMAT_JPEG;
602  else if (ext.compare(".JPEG") == 0)
603  return FORMAT_JPEG;
604  else if (ext.compare(".jpeg") == 0)
605  return FORMAT_JPEG;
606  else if (ext.compare(".PNG") == 0)
607  return FORMAT_PNG;
608  else if (ext.compare(".png") == 0)
609  return FORMAT_PNG;
610  else if (ext.compare(".TIFF") == 0)
611  return FORMAT_TIFF;
612  else if (ext.compare(".tiff") == 0)
613  return FORMAT_TIFF;
614  else if (ext.compare(".BMP") == 0)
615  return FORMAT_BMP;
616  else if (ext.compare(".bmp") == 0)
617  return FORMAT_BMP;
618  else if (ext.compare(".DIB") == 0)
619  return FORMAT_DIB;
620  else if (ext.compare(".dib") == 0)
621  return FORMAT_DIB;
622  else if (ext.compare(".PBM") == 0)
623  return FORMAT_PBM;
624  else if (ext.compare(".pbm") == 0)
625  return FORMAT_PBM;
626  else if (ext.compare(".SR") == 0)
627  return FORMAT_PBM;
628  else if (ext.compare(".sr") == 0)
629  return FORMAT_PBM;
630  else if (ext.compare(".RAS") == 0)
631  return FORMAT_RASTER;
632  else if (ext.compare(".ras") == 0)
633  return FORMAT_RASTER;
634  else if (ext.compare(".JP2") == 0)
635  return FORMAT_JPEG2000;
636  else if (ext.compare(".jp2") == 0)
637  return FORMAT_JPEG2000;
638  else if (ext.compare(".AVI") == 0)
639  return FORMAT_AVI;
640  else if (ext.compare(".avi") == 0)
641  return FORMAT_AVI;
642  else if (ext.compare(".MPEG") == 0)
643  return FORMAT_MPEG;
644  else if (ext.compare(".mpeg") == 0)
645  return FORMAT_MPEG;
646  else if (ext.compare(".MPG") == 0)
647  return FORMAT_MPEG;
648  else if (ext.compare(".mpg") == 0)
649  return FORMAT_MPEG;
650  else if (ext.compare(".MPEG4") == 0)
651  return FORMAT_MPEG4;
652  else if (ext.compare(".mpeg4") == 0)
653  return FORMAT_MPEG4;
654  else if (ext.compare(".MP4") == 0)
655  return FORMAT_MPEG4;
656  else if (ext.compare(".mp4") == 0)
657  return FORMAT_MPEG4;
658  else if (ext.compare(".MOV") == 0)
659  return FORMAT_MOV;
660  else if (ext.compare(".mov") == 0)
661  return FORMAT_MOV;
662  else if (ext.compare(".OGV") == 0)
663  return FORMAT_OGV;
664  else if (ext.compare(".ogv") == 0)
665  return FORMAT_OGV;
666  else if (ext.compare(".WMV") == 0)
667  return FORMAT_WMV;
668  else if (ext.compare(".wmv") == 0)
669  return FORMAT_WMV;
670  else if (ext.compare(".FLV") == 0)
671  return FORMAT_FLV;
672  else if (ext.compare(".flv") == 0)
673  return FORMAT_FLV;
674  else if (ext.compare(".MKV") == 0)
675  return FORMAT_MKV;
676  else if (ext.compare(".mkv") == 0)
677  return FORMAT_MKV;
678  else if (ext.compare(".MTS") == 0)
679  return FORMAT_MTS;
680  else if (ext.compare(".mts") == 0)
681  return FORMAT_MTS;
682  else
683  return FORMAT_UNKNOWN;
684 }
685 
686 // return the extension of the file including the dot
687 std::string vpVideoReader::getExtension(const std::string &filename)
688 {
689  // extract the extension
690  size_t dot = filename.find_last_of(".");
691  std::string ext = filename.substr(dot, filename.size() - 1);
692  return ext;
693 }
694 
698 void vpVideoReader::findLastFrameIndex()
699 {
700  if (!m_isOpen) {
701  vpERROR_TRACE("Use the open method before");
702  throw(vpException(vpException::notInitialized, "file not yet opened"));
703  }
704 
705  if (m_imSequence != nullptr) {
706  if (!m_lastFrameIndexIsSet) {
707  std::string imageNameFormat = vpIoTools::getName(m_videoName);
708  std::string dirName = vpIoTools::getParent(m_videoName);
709  if (dirName == "") {
710  dirName = ".";
711  }
712  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
713  m_lastFrame = 0;
714  for (size_t i = 0; i < files.size(); ++i) {
715  // Checking that file name satisfies image format,
716  // specified by imageNameFormat, and extracting imageIndex
717  long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
718  if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
719  m_lastFrame = imageIndex;
720  }
721  }
722  }
723  }
724 
725 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
726 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
727  else if (!m_lastFrameIndexIsSet) {
728  m_lastFrame = (long)m_capture.get(cv::CAP_PROP_FRAME_COUNT);
729  if (m_lastFrame <= 2) {
730  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
731  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
732  // We set video last frame to an arbitrary value 100000 and set a flag
733  m_lastframe_unknown = true;
734  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
735  }
736  }
737 #else
738  else if (!m_lastFrameIndexIsSet) {
739  m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
740  if (m_lastFrame <= 2) {
741  // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
742  // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
743  // We set video last frame to an arbitrary value 100000 and set a flag
744  m_lastframe_unknown = true;
745  m_lastFrame = 100000; // Set lastFrame to an arbitrary value
746  }
747  }
748 #endif
749 #endif
750 }
751 
755 void vpVideoReader::findFirstFrameIndex()
756 {
757  if (m_imSequence != nullptr) {
758  if (!m_firstFrameIndexIsSet) {
759  std::string imageNameFormat = vpIoTools::getName(m_videoName);
760  std::string dirName = vpIoTools::getParent(m_videoName);
761  if (dirName == "") {
762  dirName = ".";
763  }
764  std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
765  m_firstFrame = -1;
766  for (size_t i = 0; i < files.size(); ++i) {
767  // Checking that file name satisfies image format, specified by
768  // imageNameFormat, and extracting imageIndex
769  long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
770 
771  if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
772  m_firstFrame = imageIndex;
773  }
774  }
775  m_imSequence->setImageNumber(m_firstFrame);
776  }
777  }
778 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
779 
780  else if (!m_firstFrameIndexIsSet) {
781  m_firstFrame = 1L;
782  }
783 #endif
784 }
785 
789 bool vpVideoReader::isImageExtensionSupported() const
790 {
791  return (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
792  m_formatType == FORMAT_PNG || m_formatType == FORMAT_TIFF || m_formatType == FORMAT_BMP ||
793  m_formatType == FORMAT_DIB || m_formatType == FORMAT_PBM || m_formatType == FORMAT_RASTER ||
794  m_formatType == FORMAT_JPEG2000);
795 }
796 
800 bool vpVideoReader::isVideoExtensionSupported() const
801 {
802  return (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
803  m_formatType == FORMAT_MOV || m_formatType == FORMAT_OGV || m_formatType == FORMAT_WMV ||
804  m_formatType == FORMAT_FLV || m_formatType == FORMAT_MKV || m_formatType == FORMAT_MTS);
805 }
806 
831 {
832  this->acquire(I);
833  return *this;
834 }
835 
860 {
861  this->acquire(I);
862  return *this;
863 }
864 
869 bool vpVideoReader::checkImageNameFormat(const std::string &format) const
870 {
871  size_t indexBegin = format.find_last_of('%');
872  size_t indexEnd = format.find_first_of('d', indexBegin);
873  if (indexBegin == std::string::npos || indexEnd == std::string::npos) {
874  return false;
875  }
876  for (size_t i = indexBegin + 1; i < indexEnd; ++i) {
877  if (!std::isdigit(format[i])) {
878  return false;
879  }
880  }
881  return true;
882 }
883 
892 {
893  // Video format
894  switch (m_formatType) {
895  case FORMAT_AVI:
896  case FORMAT_MPEG:
897  case FORMAT_MPEG4:
898  case FORMAT_MTS:
899  case FORMAT_MOV:
900  case FORMAT_OGV:
901  case FORMAT_WMV:
902  case FORMAT_FLV:
903  case FORMAT_MKV:
904  return true;
905  default:
906  return false;
907  }
908 }
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:245
unsigned int getHeight() const
Definition: vpImage.h:184
static long getIndex(const std::string &filename, const std::string &format)
Definition: vpIoTools.cpp:2044
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:2456
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:2086
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1981
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:382