Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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
38
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(VISP_HAVE_OPENCV) && \
54 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
55 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
56 m_capture(), m_frame(), m_lastframe_unknown(false),
57#endif
58 m_formatType(FORMAT_UNKNOWN), m_videoName(), m_frameName(), m_initFileName(false), m_isOpen(false), m_frameCount(0),
59 m_firstFrame(0), m_lastFrame(0), m_firstFrameIndexIsSet(false), m_lastFrameIndexIsSet(false), m_frameStep(1),
60 m_frameRate(0.)
61{ }
62
67{
68 *this = reader;
69}
70
75{
76 if (m_imSequence != nullptr) {
77 delete m_imSequence;
78 }
79}
80
85{
86 m_imSequence = reader.m_imSequence;
87#if defined(VISP_HAVE_OPENCV) && \
88 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
89 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
90 m_capture = reader.m_capture;
91 m_frame = reader.m_frame;
92 m_lastframe_unknown = reader.m_lastframe_unknown;
93#endif
94 m_formatType = reader.m_formatType;
95 m_videoName = reader.m_videoName;
96 m_frameName = reader.m_frameName;
97 m_initFileName = reader.m_initFileName;
98 m_isOpen = reader.m_isOpen;
99 m_frameCount = reader.m_frameCount;
100 m_firstFrame = reader.m_firstFrame;
101 m_lastFrame = reader.m_lastFrame;
102 m_firstFrameIndexIsSet = reader.m_firstFrameIndexIsSet;
103 m_lastFrameIndexIsSet = reader.m_lastFrameIndexIsSet;
104 m_frameStep = reader.m_frameStep;
105 m_frameRate = reader.m_frameRate;
106 return *this;
107}
108
123void vpVideoReader::setFileName(const std::string &filename)
124{
125 if (filename.empty()) {
126 throw(vpImageException(vpImageException::noFileNameError, "filename empty "));
127 }
128
129 m_videoName = filename;
130 m_frameName = filename;
131
132 m_formatType = getFormat(filename);
133
134 if (m_formatType == FORMAT_UNKNOWN) {
135 throw(vpException(vpException::badValue, "Filename extension not supported"));
136 }
137
138 // checking image name format
139 if (isImageExtensionSupported()) {
140 std::string format = vpIoTools::getName(m_videoName);
141 if (!checkImageNameFormat(format)) {
142 throw(vpException(vpException::badValue, "Format of image name wasn't recognized: %s", format.c_str()));
143 }
144 }
145
146 m_initFileName = true;
147}
148
152void vpVideoReader::getProperties()
153{
154 if (m_isOpen) {
155 return;
156 }
157
158 if (!m_initFileName) {
159 throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set"));
160 }
161
162 if (isImageExtensionSupported()) {
163 m_imSequence = new vpDiskGrabber;
164 m_imSequence->setGenericName(m_videoName.c_str());
165 m_imSequence->setStep(m_frameStep);
166 if (m_firstFrameIndexIsSet) {
167 m_imSequence->setImageNumber(m_firstFrame);
168 }
169 m_frameRate = -1.;
170 }
171 else if (isVideoExtensionSupported()) {
172#if defined(VISP_HAVE_OPENCV) && \
173 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
174 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
175 m_capture.open(m_videoName.c_str());
176
177 if (!m_capture.isOpened()) {
178 throw(vpException(vpException::ioError, "Could not open the video %s with OpenCV", m_videoName.c_str()));
179 }
180#if VISP_HAVE_OPENCV_VERSION >= 0x030000
181 width = static_cast<unsigned int>(m_capture.get(cv::CAP_PROP_FRAME_WIDTH));
182 height = static_cast<unsigned int>(m_capture.get(cv::CAP_PROP_FRAME_HEIGHT));
183 m_frameRate = static_cast<double>(m_capture.get(cv::CAP_PROP_FPS));
184#else
185 width = static_cast<unsigned int>(m_capture.get(CV_CAP_PROP_FRAME_WIDTH));
186 height = static_cast<unsigned int>(m_capture.get(CV_CAP_PROP_FRAME_HEIGHT));
187 m_frameRate = m_capture.get(CV_CAP_PROP_FPS);
188#endif
189
190#else
191 throw(vpException(vpException::fatalError, "To read video files ViSP should be build with opencv "
192 "3rd >= 2.1.0 party libraries."));
193#endif
194 }
195 else if (m_formatType == FORMAT_UNKNOWN) {
196 throw(vpException(vpException::fatalError, "The format of the file does "
197 "not correspond to a readable "
198 "format supported by ViSP."));
199 }
200
201 findFirstFrameIndex();
202 m_isOpen = true;
203 findLastFrameIndex();
204}
205
214{
215 getProperties();
216
217 m_frameCount = m_firstFrame;
218 if (!getFrame(I, m_firstFrame)) {
219 throw(vpException(vpException::ioError, "Could not read the video first frame"));
220 }
221
222 // Rewind to the first frame since open() should not increase the frame
223 // counter
224 m_frameCount = m_firstFrame;
225
226 if (isVideoExtensionSupported()) {
227#if defined(VISP_HAVE_OPENCV) && \
228 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
229 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
230
231#if VISP_HAVE_OPENCV_VERSION >= 0x030000
232 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
233#else
234 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
235#endif
236 m_frameCount--;
237#endif
238 }
239}
240
249{
250 getProperties();
251
252 m_frameCount = m_firstFrame;
253 if (!getFrame(I, m_firstFrame)) {
254 throw(vpException(vpException::ioError, "Could not read the video first frame"));
255 }
256
257 // Rewind to the first frame since open() should not increase the frame
258 // counter
259 m_frameCount = m_firstFrame;
260
261 if (isVideoExtensionSupported()) {
262#if defined(VISP_HAVE_OPENCV) && \
263 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
264 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
265
266#if VISP_HAVE_OPENCV_VERSION >= 0x030000
267 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
268#else
269 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
270#endif
271 m_frameCount--;
272#endif
273 }
274}
275
287{
288 if (!m_isOpen) {
289 open(I);
290 }
291 if (m_imSequence != nullptr) {
292 m_imSequence->setStep(m_frameStep);
293 bool skip_frame = false;
294 do {
295 try {
296 m_imSequence->acquire(I);
297 skip_frame = false;
298 }
299 catch (...) {
300 skip_frame = true;
301 }
302 } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
303 m_frameCount = m_imSequence->getImageNumber();
304 m_frameName = m_imSequence->getImageName();
305 if (m_frameCount + m_frameStep > m_lastFrame) {
306 m_imSequence->setImageNumber(m_frameCount);
307 }
308 else if (m_frameCount + m_frameStep < m_firstFrame) {
309 m_imSequence->setImageNumber(m_frameCount);
310 }
311 }
312#if defined(VISP_HAVE_OPENCV) && \
313 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
314 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
315 else {
316 m_capture >> m_frame;
317 if (m_frameStep == 1) {
318 ++m_frameCount;
319 }
320 else {
321#if VISP_HAVE_OPENCV_VERSION >= 0x030000
322 m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
323 if (m_frameStep > 0) {
324 if (m_frameCount + m_frameStep <= m_lastFrame) {
325 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
326 }
327 else {
328 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
329 }
330 }
331 else if (m_frameStep < 0) {
332 if (m_frameCount + m_frameStep >= m_firstFrame) {
333 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
334 }
335 else {
336 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
337 }
338 }
339#else
340 m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
341 if (m_frameStep > 0) {
342 if (m_frameCount + m_frameStep <= m_lastFrame) {
343 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
344 }
345 else {
346 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
347 }
348 }
349 else if (m_frameStep < 0) {
350 if (m_frameCount + m_frameStep >= m_firstFrame) {
351 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
352 }
353 else {
354 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
355 }
356 }
357#endif
358 }
359
360 if (m_frame.empty()) {
361 std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
362 if (m_lastframe_unknown) {
363 // Set last frame to this image index
364 setLastFrameIndex(m_frameCount - m_frameStep);
365 }
366 }
367 else {
368 vpImageConvert::convert(m_frame, I);
369 }
370 }
371#endif
372}
373
383{
384 if (!m_isOpen) {
385 open(I);
386 }
387
388 if (m_imSequence != nullptr) {
389 m_imSequence->setStep(m_frameStep);
390 bool skip_frame = false;
391 do {
392 try {
393 m_imSequence->acquire(I);
394 skip_frame = false;
395 }
396 catch (...) {
397 skip_frame = true;
398 }
399 } while (skip_frame && m_imSequence->getImageNumber() < m_lastFrame);
400 m_frameCount = m_imSequence->getImageNumber();
401 m_frameName = m_imSequence->getImageName();
402 if (m_frameCount + m_frameStep > m_lastFrame) {
403 m_imSequence->setImageNumber(m_frameCount);
404 }
405 else if (m_frameCount + m_frameStep < m_firstFrame) {
406 m_imSequence->setImageNumber(m_frameCount);
407 }
408 }
409#if defined(VISP_HAVE_OPENCV) && \
410 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
411 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
412 else {
413 m_capture >> m_frame;
414 if (m_frameStep == 1) {
415 ++m_frameCount;
416 }
417 else {
418#if VISP_HAVE_OPENCV_VERSION >= 0x030000
419 m_frameCount = (long)m_capture.get(cv::CAP_PROP_POS_FRAMES);
420 if (m_frameStep > 0) {
421 if (m_frameCount + m_frameStep <= m_lastFrame) {
422 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
423 }
424 else {
425 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
426 }
427 }
428 else if (m_frameStep < 0) {
429 if (m_frameCount + m_frameStep >= m_firstFrame) {
430 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
431 }
432 else {
433 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
434 }
435 }
436#else
437 m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
438 if (m_frameStep > 0) {
439 if (m_frameCount + m_frameStep <= m_lastFrame) {
440 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
441 }
442 else {
443 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
444 }
445 }
446 else if (m_frameStep < 0) {
447 if (m_frameCount + m_frameStep >= m_firstFrame) {
448 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount + m_frameStep - 1);
449 }
450 else {
451 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
452 }
453 }
454#endif
455 }
456
457 if (m_frame.empty()) {
458 std::cout << "Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
459 }
460 else {
461 vpImageConvert::convert(m_frame, I);
462 }
463 }
464#endif
465}
466
480bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
481{
482 if (m_imSequence != nullptr) {
483 try {
484 m_imSequence->acquire(I, frame_index);
485 width = I.getWidth();
486 height = I.getHeight();
487 m_frameCount = m_imSequence->getImageNumber();
488 m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
489 if (m_frameCount + m_frameStep > m_lastFrame) {
490 m_imSequence->setImageNumber(m_frameCount);
491 }
492 else if (m_frameCount + m_frameStep < m_firstFrame) {
493 m_imSequence->setImageNumber(m_frameCount);
494 }
495 }
496 catch (...) {
497 // Couldn't find the %u th frame", frame_index
498 return false;
499 }
500 }
501 else {
502#if defined(VISP_HAVE_OPENCV) && \
503 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
504 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
505#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
506 if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
507 // Couldn't find the %ld th frame", frame_index
508 return false;
509 }
510
511 m_capture >> m_frame;
512 m_frameCount = frame_index + m_frameStep; // next index
513 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
514 if (m_frame.empty()) {
515 // New trial that makes things working with opencv 3.0.0
516 m_capture >> m_frame;
517 if (m_frame.empty()) {
518 setLastFrameIndex(m_frameCount - m_frameStep);
519 return false;
520 }
521 else {
522 vpImageConvert::convert(m_frame, I);
523 }
524 }
525 else
526 vpImageConvert::convert(m_frame, I);
527#else
528 if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
529 // Couldn't find the %ld th frame", frame_index
530 return false;
531 }
532
533 m_capture >> m_frame;
534 m_frameCount = frame_index + m_frameStep; // next index
535 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
536 if (m_frame.empty())
537 setLastFrameIndex(m_frameCount - m_frameStep);
538 else
539 vpImageConvert::convert(m_frame, I);
540#endif
541#endif
542 }
543 return true;
544}
545
560{
561 if (m_imSequence != nullptr) {
562 try {
563 m_imSequence->acquire(I, frame_index);
564 width = I.getWidth();
565 height = I.getHeight();
566 m_frameCount = m_imSequence->getImageNumber();
567 m_imSequence->setImageNumber(m_frameCount); // to not increment vpDiskGrabber next image
568 if (m_frameCount + m_frameStep > m_lastFrame) {
569 m_imSequence->setImageNumber(m_frameCount);
570 }
571 else if (m_frameCount + m_frameStep < m_firstFrame) {
572 m_imSequence->setImageNumber(m_frameCount);
573 }
574 }
575 catch (...) {
576 // Couldn't find the %u th frame", frame_index
577 return false;
578 }
579 }
580 else {
581#if defined(VISP_HAVE_OPENCV) && \
582 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
583 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
584#if VISP_HAVE_OPENCV_VERSION >= 0x030000
585 if (!m_capture.set(cv::CAP_PROP_POS_FRAMES, frame_index)) {
586 // Couldn't find the %ld th frame", frame_index
587 return false;
588 }
589 m_capture >> m_frame;
590 if (m_frame.empty()) {
591 // New trial that makes things working with opencv 3.0.0
592 m_capture >> m_frame;
593 if (m_frame.empty()) {
594 setLastFrameIndex(m_frameCount - m_frameStep);
595 return false;
596 }
597 else {
598 vpImageConvert::convert(m_frame, I);
599 }
600 }
601 else {
602 vpImageConvert::convert(m_frame, I);
603 }
604#else
605 if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
606 // Couldn't find the %ld th frame", frame_index
607 return false;
608 }
609 m_capture >> m_frame;
610 m_frameCount = (long)m_capture.get(CV_CAP_PROP_POS_FRAMES);
611 if (m_frameStep > 1) {
612 m_frameCount += m_frameStep - 1; // next index
613 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
614 }
615 else if (m_frameStep < -1) {
616 m_frameCount += m_frameStep - 1; // next index
617 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
618 }
619 if (m_frame.empty())
620 setLastFrameIndex(m_frameCount - m_frameStep);
621 else
622 vpImageConvert::convert(m_frame, I);
623#endif
624#endif
625 }
626 return true;
627}
628
634vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(const std::string &filename) const
635{
636 std::string ext = vpVideoReader::getExtension(filename);
637
638 if (ext.compare(".PGM") == 0)
639 return FORMAT_PGM;
640 else if (ext.compare(".pgm") == 0)
641 return FORMAT_PGM;
642 else if (ext.compare(".PPM") == 0)
643 return FORMAT_PPM;
644 else if (ext.compare(".ppm") == 0)
645 return FORMAT_PPM;
646 else if (ext.compare(".JPG") == 0)
647 return FORMAT_JPEG;
648 else if (ext.compare(".jpg") == 0)
649 return FORMAT_JPEG;
650 else if (ext.compare(".JPEG") == 0)
651 return FORMAT_JPEG;
652 else if (ext.compare(".jpeg") == 0)
653 return FORMAT_JPEG;
654 else if (ext.compare(".PNG") == 0)
655 return FORMAT_PNG;
656 else if (ext.compare(".png") == 0)
657 return FORMAT_PNG;
658 else if (ext.compare(".TIFF") == 0)
659 return FORMAT_TIFF;
660 else if (ext.compare(".tiff") == 0)
661 return FORMAT_TIFF;
662 else if (ext.compare(".BMP") == 0)
663 return FORMAT_BMP;
664 else if (ext.compare(".bmp") == 0)
665 return FORMAT_BMP;
666 else if (ext.compare(".DIB") == 0)
667 return FORMAT_DIB;
668 else if (ext.compare(".dib") == 0)
669 return FORMAT_DIB;
670 else if (ext.compare(".PBM") == 0)
671 return FORMAT_PBM;
672 else if (ext.compare(".pbm") == 0)
673 return FORMAT_PBM;
674 else if (ext.compare(".SR") == 0)
675 return FORMAT_PBM;
676 else if (ext.compare(".sr") == 0)
677 return FORMAT_PBM;
678 else if (ext.compare(".RAS") == 0)
679 return FORMAT_RASTER;
680 else if (ext.compare(".ras") == 0)
681 return FORMAT_RASTER;
682 else if (ext.compare(".JP2") == 0)
683 return FORMAT_JPEG2000;
684 else if (ext.compare(".jp2") == 0)
685 return FORMAT_JPEG2000;
686 else if (ext.compare(".AVI") == 0)
687 return FORMAT_AVI;
688 else if (ext.compare(".avi") == 0)
689 return FORMAT_AVI;
690 else if (ext.compare(".MPEG") == 0)
691 return FORMAT_MPEG;
692 else if (ext.compare(".mpeg") == 0)
693 return FORMAT_MPEG;
694 else if (ext.compare(".MPG") == 0)
695 return FORMAT_MPEG;
696 else if (ext.compare(".mpg") == 0)
697 return FORMAT_MPEG;
698 else if (ext.compare(".MPEG4") == 0)
699 return FORMAT_MPEG4;
700 else if (ext.compare(".mpeg4") == 0)
701 return FORMAT_MPEG4;
702 else if (ext.compare(".MP4") == 0)
703 return FORMAT_MPEG4;
704 else if (ext.compare(".mp4") == 0)
705 return FORMAT_MPEG4;
706 else if (ext.compare(".MOV") == 0)
707 return FORMAT_MOV;
708 else if (ext.compare(".mov") == 0)
709 return FORMAT_MOV;
710 else if (ext.compare(".OGV") == 0)
711 return FORMAT_OGV;
712 else if (ext.compare(".ogv") == 0)
713 return FORMAT_OGV;
714 else if (ext.compare(".WMV") == 0)
715 return FORMAT_WMV;
716 else if (ext.compare(".wmv") == 0)
717 return FORMAT_WMV;
718 else if (ext.compare(".FLV") == 0)
719 return FORMAT_FLV;
720 else if (ext.compare(".flv") == 0)
721 return FORMAT_FLV;
722 else if (ext.compare(".MKV") == 0)
723 return FORMAT_MKV;
724 else if (ext.compare(".mkv") == 0)
725 return FORMAT_MKV;
726 else if (ext.compare(".MTS") == 0)
727 return FORMAT_MTS;
728 else if (ext.compare(".mts") == 0)
729 return FORMAT_MTS;
730 else
731 return FORMAT_UNKNOWN;
732}
733
734// return the extension of the file including the dot
735std::string vpVideoReader::getExtension(const std::string &filename)
736{
737 // extract the extension
738 size_t dot = filename.find_last_of(".");
739 std::string ext = filename.substr(dot, filename.size() - 1);
740 return ext;
741}
742
746void vpVideoReader::findLastFrameIndex()
747{
748 if (!m_isOpen) {
749 throw(vpException(vpException::notInitialized, "File not yet opened. Use the open() method before"));
750 }
751
752 if (m_imSequence != nullptr) {
753 if (!m_lastFrameIndexIsSet) {
754 std::string imageNameFormat = vpIoTools::getName(m_videoName);
755 std::string dirName = vpIoTools::getParent(m_videoName);
756 if (dirName == "") {
757 dirName = ".";
758 }
759 std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
760 m_lastFrame = 0;
761 for (size_t i = 0; i < files.size(); ++i) {
762 // Checking that file name satisfies image format,
763 // specified by imageNameFormat, and extracting imageIndex
764 long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
765 if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
766 m_lastFrame = imageIndex;
767 }
768 }
769 }
770 }
771
772#if defined(VISP_HAVE_OPENCV) && \
773 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
774 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
775#if VISP_HAVE_OPENCV_VERSION >= 0x030000
776 else if (!m_lastFrameIndexIsSet) {
777 m_lastFrame = (long)m_capture.get(cv::CAP_PROP_FRAME_COUNT);
778 if (m_lastFrame <= 2) {
779 // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
780 // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
781 // We set video last frame to an arbitrary value 100000 and set a flag
782 m_lastframe_unknown = true;
783 m_lastFrame = 100000; // Set lastFrame to an arbitrary value
784 }
785 }
786#else
787 else if (!m_lastFrameIndexIsSet) {
788 m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
789 if (m_lastFrame <= 2) {
790 // With visp/tutorial/detection/matching/video-postcard.mpeg that is MPEG-2 it return 2 with OpenCV 3.0.0
791 // With visp-images/video/cube.mpeg that is MPEG-1 it return 1 with OpenCV 4.1.1
792 // We set video last frame to an arbitrary value 100000 and set a flag
793 m_lastframe_unknown = true;
794 m_lastFrame = 100000; // Set lastFrame to an arbitrary value
795 }
796 }
797#endif
798#endif
799}
800
804void vpVideoReader::findFirstFrameIndex()
805{
806 if (m_imSequence != nullptr) {
807 if (!m_firstFrameIndexIsSet) {
808 std::string imageNameFormat = vpIoTools::getName(m_videoName);
809 std::string dirName = vpIoTools::getParent(m_videoName);
810 if (dirName == "") {
811 dirName = ".";
812 }
813 std::vector<std::string> files = vpIoTools::getDirFiles(dirName);
814 m_firstFrame = -1;
815 for (size_t i = 0; i < files.size(); ++i) {
816 // Checking that file name satisfies image format, specified by
817 // imageNameFormat, and extracting imageIndex
818 long imageIndex = vpIoTools::getIndex(files[i], imageNameFormat);
819
820 if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
821 m_firstFrame = imageIndex;
822 }
823 }
824 m_imSequence->setImageNumber(m_firstFrame);
825 }
826 }
827#if defined(VISP_HAVE_OPENCV) && \
828 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
829 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
830
831 else if (!m_firstFrameIndexIsSet) {
832 m_firstFrame = 1L;
833 }
834#endif
835}
836
840bool vpVideoReader::isImageExtensionSupported() const
841{
842 return (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
843 m_formatType == FORMAT_PNG || m_formatType == FORMAT_TIFF || m_formatType == FORMAT_BMP ||
844 m_formatType == FORMAT_DIB || m_formatType == FORMAT_PBM || m_formatType == FORMAT_RASTER ||
845 m_formatType == FORMAT_JPEG2000);
846}
847
851bool vpVideoReader::isVideoExtensionSupported() const
852{
853 return (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
854 m_formatType == FORMAT_MOV || m_formatType == FORMAT_OGV || m_formatType == FORMAT_WMV ||
855 m_formatType == FORMAT_FLV || m_formatType == FORMAT_MKV || m_formatType == FORMAT_MTS);
856}
857
886{
887 this->acquire(I);
888 return *this;
889}
890
919{
920 this->acquire(I);
921 return *this;
922}
923
928bool vpVideoReader::checkImageNameFormat(const std::string &format) const
929{
930 size_t indexBegin = format.find_last_of('%');
931 size_t indexEnd = format.find_first_of('d', indexBegin);
932 if (indexBegin == std::string::npos || indexEnd == std::string::npos) {
933 return false;
934 }
935 for (size_t i = indexBegin + 1; i < indexEnd; ++i) {
936 if (!std::isdigit(format[i])) {
937 return false;
938 }
939 }
940 return true;
941}
942
951{
952 // Video format
953 switch (m_formatType) {
954 case FORMAT_AVI:
955 case FORMAT_MPEG:
956 case FORMAT_MPEG4:
957 case FORMAT_MTS:
958 case FORMAT_MOV:
959 case FORMAT_OGV:
960 case FORMAT_WMV:
961 case FORMAT_FLV:
962 case FORMAT_MKV:
963 return true;
964 default:
965 return false;
966 }
967}
968
969END_VISP_NAMESPACE
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
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.
Definition of the vpImage class member functions.
Definition vpImage.h:131
static long getIndex(const std::string &filename, const std::string &format)
static std::vector< std::string > getDirFiles(const std::string &dirname)
static std::string getParent(const std::string &pathname)
static std::string getName(const std::string &pathname)
bool isVideoFormat() const
void setLastFrameIndex(const long last_frame)
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
bool getFrame(vpImage< vpRGBa > &I, long frame)
vpVideoReader & operator=(const vpVideoReader &reader)
virtual ~vpVideoReader() VP_OVERRIDE
vpVideoReader & operator>>(vpImage< unsigned char > &I)
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE