39#include <visp3/core/vpIoTools.h>
40#include <visp3/io/vpVideoReader.h>
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),
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),
76 if (m_imSequence !=
nullptr) {
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;
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;
125 if (filename.empty()) {
129 m_videoName = filename;
130 m_frameName = filename;
132 m_formatType = getFormat(filename);
134 if (m_formatType == FORMAT_UNKNOWN) {
139 if (isImageExtensionSupported()) {
141 if (!checkImageNameFormat(format)) {
146 m_initFileName =
true;
152void vpVideoReader::getProperties()
158 if (!m_initFileName) {
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);
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());
177 if (!m_capture.isOpened()) {
178 throw(vpException(
vpException::ioError,
"Could not open the video %s with OpenCV", m_videoName.c_str()));
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));
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);
192 "3rd >= 2.1.0 party libraries."));
195 else if (m_formatType == FORMAT_UNKNOWN) {
197 "not correspond to a readable "
198 "format supported by ViSP."));
201 findFirstFrameIndex();
203 findLastFrameIndex();
217 m_frameCount = m_firstFrame;
224 m_frameCount = m_firstFrame;
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)))
231#if VISP_HAVE_OPENCV_VERSION >= 0x030000
232 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
234 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
252 m_frameCount = m_firstFrame;
259 m_frameCount = m_firstFrame;
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)))
266#if VISP_HAVE_OPENCV_VERSION >= 0x030000
267 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
269 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
291 if (m_imSequence !=
nullptr) {
292 m_imSequence->setStep(m_frameStep);
293 bool skip_frame =
false;
296 m_imSequence->acquire(I);
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);
308 else if (m_frameCount + m_frameStep < m_firstFrame) {
309 m_imSequence->setImageNumber(m_frameCount);
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)))
316 m_capture >> m_frame;
317 if (m_frameStep == 1) {
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);
328 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
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);
336 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
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);
346 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
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);
354 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
360 if (m_frame.empty()) {
361 std::cout <<
"Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
362 if (m_lastframe_unknown) {
388 if (m_imSequence !=
nullptr) {
389 m_imSequence->setStep(m_frameStep);
390 bool skip_frame =
false;
393 m_imSequence->acquire(I);
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);
405 else if (m_frameCount + m_frameStep < m_firstFrame) {
406 m_imSequence->setImageNumber(m_frameCount);
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)))
413 m_capture >> m_frame;
414 if (m_frameStep == 1) {
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);
425 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount - 1);
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);
433 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_firstFrame - 1);
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);
443 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount - 1);
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);
451 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_firstFrame - 1);
457 if (m_frame.empty()) {
458 std::cout <<
"Warning: Unable to decode image " << m_frameCount - m_frameStep << std::endl;
482 if (m_imSequence !=
nullptr) {
484 m_imSequence->acquire(I, frame_index);
485 width = I.getWidth();
487 m_frameCount = m_imSequence->getImageNumber();
488 m_imSequence->setImageNumber(m_frameCount);
489 if (m_frameCount + m_frameStep > m_lastFrame) {
490 m_imSequence->setImageNumber(m_frameCount);
492 else if (m_frameCount + m_frameStep < m_firstFrame) {
493 m_imSequence->setImageNumber(m_frameCount);
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)) {
511 m_capture >> m_frame;
512 m_frameCount = frame_index + m_frameStep;
513 m_capture.set(cv::CAP_PROP_POS_FRAMES, m_frameCount);
514 if (m_frame.empty()) {
516 m_capture >> m_frame;
517 if (m_frame.empty()) {
528 if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
533 m_capture >> m_frame;
534 m_frameCount = frame_index + m_frameStep;
535 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
561 if (m_imSequence !=
nullptr) {
563 m_imSequence->acquire(I, frame_index);
564 width = I.getWidth();
566 m_frameCount = m_imSequence->getImageNumber();
567 m_imSequence->setImageNumber(m_frameCount);
568 if (m_frameCount + m_frameStep > m_lastFrame) {
569 m_imSequence->setImageNumber(m_frameCount);
571 else if (m_frameCount + m_frameStep < m_firstFrame) {
572 m_imSequence->setImageNumber(m_frameCount);
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)) {
589 m_capture >> m_frame;
590 if (m_frame.empty()) {
592 m_capture >> m_frame;
593 if (m_frame.empty()) {
605 if (!m_capture.set(CV_CAP_PROP_POS_FRAMES, frame_index)) {
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;
613 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
615 else if (m_frameStep < -1) {
616 m_frameCount += m_frameStep - 1;
617 m_capture.set(CV_CAP_PROP_POS_FRAMES, m_frameCount);
634vpVideoReader::vpVideoFormatType vpVideoReader::getFormat(
const std::string &filename)
const
636 std::string ext = vpVideoReader::getExtension(filename);
638 if (ext.compare(
".PGM") == 0)
640 else if (ext.compare(
".pgm") == 0)
642 else if (ext.compare(
".PPM") == 0)
644 else if (ext.compare(
".ppm") == 0)
646 else if (ext.compare(
".JPG") == 0)
648 else if (ext.compare(
".jpg") == 0)
650 else if (ext.compare(
".JPEG") == 0)
652 else if (ext.compare(
".jpeg") == 0)
654 else if (ext.compare(
".PNG") == 0)
656 else if (ext.compare(
".png") == 0)
658 else if (ext.compare(
".TIFF") == 0)
660 else if (ext.compare(
".tiff") == 0)
662 else if (ext.compare(
".BMP") == 0)
664 else if (ext.compare(
".bmp") == 0)
666 else if (ext.compare(
".DIB") == 0)
668 else if (ext.compare(
".dib") == 0)
670 else if (ext.compare(
".PBM") == 0)
672 else if (ext.compare(
".pbm") == 0)
674 else if (ext.compare(
".SR") == 0)
676 else if (ext.compare(
".sr") == 0)
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)
688 else if (ext.compare(
".avi") == 0)
690 else if (ext.compare(
".MPEG") == 0)
692 else if (ext.compare(
".mpeg") == 0)
694 else if (ext.compare(
".MPG") == 0)
696 else if (ext.compare(
".mpg") == 0)
698 else if (ext.compare(
".MPEG4") == 0)
700 else if (ext.compare(
".mpeg4") == 0)
702 else if (ext.compare(
".MP4") == 0)
704 else if (ext.compare(
".mp4") == 0)
706 else if (ext.compare(
".MOV") == 0)
708 else if (ext.compare(
".mov") == 0)
710 else if (ext.compare(
".OGV") == 0)
712 else if (ext.compare(
".ogv") == 0)
714 else if (ext.compare(
".WMV") == 0)
716 else if (ext.compare(
".wmv") == 0)
718 else if (ext.compare(
".FLV") == 0)
720 else if (ext.compare(
".flv") == 0)
722 else if (ext.compare(
".MKV") == 0)
724 else if (ext.compare(
".mkv") == 0)
726 else if (ext.compare(
".MTS") == 0)
728 else if (ext.compare(
".mts") == 0)
731 return FORMAT_UNKNOWN;
735std::string vpVideoReader::getExtension(
const std::string &filename)
738 size_t dot =
filename.find_last_of(
".");
746void vpVideoReader::findLastFrameIndex()
752 if (m_imSequence !=
nullptr) {
753 if (!m_lastFrameIndexIsSet) {
761 for (
size_t i = 0;
i < files.size(); ++
i) {
765 if ((imageIndex != -1) && (imageIndex > m_lastFrame)) {
766 m_lastFrame = imageIndex;
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) {
782 m_lastframe_unknown =
true;
783 m_lastFrame = 100000;
787 else if (!m_lastFrameIndexIsSet) {
788 m_lastFrame = (long)m_capture.get(CV_CAP_PROP_FRAME_COUNT);
789 if (m_lastFrame <= 2) {
793 m_lastframe_unknown =
true;
794 m_lastFrame = 100000;
804void vpVideoReader::findFirstFrameIndex()
806 if (m_imSequence !=
nullptr) {
807 if (!m_firstFrameIndexIsSet) {
815 for (
size_t i = 0;
i < files.size(); ++
i) {
820 if ((imageIndex != -1) && (imageIndex < m_firstFrame || m_firstFrame == -1)) {
821 m_firstFrame = imageIndex;
824 m_imSequence->setImageNumber(m_firstFrame);
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)))
831 else if (!m_firstFrameIndexIsSet) {
840bool vpVideoReader::isImageExtensionSupported()
const
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);
851bool vpVideoReader::isVideoExtensionSupported()
const
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);
928bool vpVideoReader::checkImageNameFormat(
const std::string &format)
const
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) {
935 for (
size_t i = indexBegin + 1;
i < indexEnd; ++
i) {
936 if (!std::isdigit(format[i])) {
953 switch (m_formatType) {
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ notInitialized
Used to indicate that a parameter is not initialized.
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.
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