Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpVideoWriter.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 * Write image sequences.
32 */
33
39#include <visp3/core/vpDebug.h>
40#include <visp3/core/vpIoTools.h>
41#include <visp3/io/vpVideoWriter.h>
42
43#if defined(HAVE_OPENCV_IMGPROC)
44#include <opencv2/imgproc/imgproc.hpp>
45#endif
46
51 :
52#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
53 m_writer(), m_framerate(25.0),
54#endif
55 m_formatType(FORMAT_UNKNOWN), m_videoName(), m_frameName(), m_initFileName(false), m_isOpen(false), m_frameCount(0),
56 m_firstFrame(0), m_width(0), m_height(0), m_frameStep(1)
57{
58#if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
59#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
60 m_fourcc = cv::VideoWriter::fourcc('P', 'I', 'M', '1');
61#else
62 m_fourcc = CV_FOURCC('P', 'I', 'M', '1'); // default is a MPEG-1 codec
63#endif
64#endif
65}
66
71
86void vpVideoWriter::setFileName(const std::string &filename)
87{
88 if (filename.empty()) {
89 throw(vpImageException(vpImageException::noFileNameError, "Filename empty in video writer"));
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 in video writer"));
99 }
100
101 m_initFileName = true;
102}
103
113{
114 if (!m_initFileName) {
115 throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set in video writer"));
116 }
117
119
120 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
121 m_formatType == FORMAT_PNG) {
122 m_width = I.getWidth();
123 m_height = I.getHeight();
124 } else if (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
125 m_formatType == FORMAT_MOV) {
126#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
127 m_writer = cv::VideoWriter(m_videoName, m_fourcc, m_framerate,
128 cv::Size(static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight())));
129
130 if (!m_writer.isOpened()) {
131 throw(vpException(vpException::fatalError, "Could not encode the video with OpenCV"));
132 }
133#else
134 throw(vpException(vpException::fatalError, "To encode video files ViSP should be build with OpenCV >= 2.1.0"));
135#endif
136 }
137
138 m_frameCount = m_firstFrame;
139
140 m_isOpen = true;
141}
142
152{
153 if (!m_initFileName) {
154 throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set in video writer"));
155 }
156
158
159 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
160 m_formatType == FORMAT_PNG) {
161 m_width = I.getWidth();
162 m_height = I.getHeight();
163 } else if (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
164 m_formatType == FORMAT_MOV) {
165#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
166 m_writer = cv::VideoWriter(m_videoName, m_fourcc, m_framerate,
167 cv::Size(static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight())));
168
169 if (!m_writer.isOpened()) {
170 throw(vpException(vpException::fatalError, "Could not encode the video with OpenCV"));
171 }
172#else
173 throw(vpException(vpException::fatalError, "To encode video files ViSP should be build with OpenCV >= 2.1.0"));
174#endif
175 }
176
177 m_frameCount = m_firstFrame;
178
179 m_isOpen = true;
180}
181
192{
193 if (!m_isOpen) {
194 throw(vpException(vpException::notInitialized, "The video has to be open first with video writer open() method"));
195 }
196
197 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
198 m_formatType == FORMAT_PNG) {
199 char name[FILENAME_MAX];
200 snprintf(name, FILENAME_MAX, m_videoName.c_str(), m_frameCount);
201 vpImageIo::write(I, name);
202 m_frameName = std::string(name);
203 } else {
204#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
205 cv::Mat matFrame;
206 vpImageConvert::convert(I, matFrame);
207 m_writer << matFrame;
208#endif
209 }
210
211 m_frameCount += m_frameStep;
212}
213
224{
225 if (!m_isOpen) {
226 throw(vpException(vpException::notInitialized, "The video has to be open first with video writer open() method"));
227 }
228
229 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
230 m_formatType == FORMAT_PNG) {
231 char name[FILENAME_MAX];
232 snprintf(name, FILENAME_MAX, m_videoName.c_str(), m_frameCount);
233 vpImageIo::write(I, name);
234 m_frameName = std::string(name);
235 } else {
236#if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_VIDEOIO)
237#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
238 cv::Mat matFrame, rgbMatFrame;
239 vpImageConvert::convert(I, matFrame);
240 cv::cvtColor(matFrame, rgbMatFrame, cv::COLOR_GRAY2BGR);
241 m_writer << rgbMatFrame;
242#else
243 cv::Mat matFrame, rgbMatFrame;
244 vpImageConvert::convert(I, matFrame);
245 cv::cvtColor(matFrame, rgbMatFrame, CV_GRAY2BGR);
246 m_writer << rgbMatFrame;
247#endif
248#endif
249 }
250
251 m_frameCount += m_frameStep;
252}
253
258{
259 if (!m_isOpen) {
260 throw(vpException(vpException::notInitialized, "Cannot close video writer: not yet opened"));
261 }
262}
263
269vpVideoWriter::vpVideoFormatType vpVideoWriter::getFormat(const std::string &filename)
270{
271 std::string ext = vpVideoWriter::getExtension(filename);
272
273 if (ext.compare(".PGM") == 0)
274 return FORMAT_PGM;
275 else if (ext.compare(".pgm") == 0)
276 return FORMAT_PGM;
277 else if (ext.compare(".PPM") == 0)
278 return FORMAT_PPM;
279 else if (ext.compare(".ppm") == 0)
280 return FORMAT_PPM;
281 else if (ext.compare(".JPG") == 0)
282 return FORMAT_JPEG;
283 else if (ext.compare(".jpg") == 0)
284 return FORMAT_JPEG;
285 else if (ext.compare(".JPEG") == 0)
286 return FORMAT_JPEG;
287 else if (ext.compare(".jpeg") == 0)
288 return FORMAT_JPEG;
289 else if (ext.compare(".PNG") == 0)
290 return FORMAT_PNG;
291 else if (ext.compare(".png") == 0)
292 return FORMAT_PNG;
293 else if (ext.compare(".AVI") == 0)
294 return FORMAT_AVI;
295 else if (ext.compare(".avi") == 0)
296 return FORMAT_AVI;
297 else if (ext.compare(".MPEG") == 0)
298 return FORMAT_MPEG;
299 else if (ext.compare(".mpeg") == 0)
300 return FORMAT_MPEG;
301 else if (ext.compare(".MPG") == 0)
302 return FORMAT_MPEG;
303 else if (ext.compare(".mpg") == 0)
304 return FORMAT_MPEG;
305 else if (ext.compare(".MPEG4") == 0)
306 return FORMAT_MPEG4;
307 else if (ext.compare(".mpeg4") == 0)
308 return FORMAT_MPEG4;
309 else if (ext.compare(".MP4") == 0)
310 return FORMAT_MPEG4;
311 else if (ext.compare(".mp4") == 0)
312 return FORMAT_MPEG4;
313 else if (ext.compare(".MOV") == 0)
314 return FORMAT_MOV;
315 else if (ext.compare(".mov") == 0)
316 return FORMAT_MOV;
317 else
318 return FORMAT_UNKNOWN;
319}
320
321// return the extension of the file including the dot
322std::string vpVideoWriter::getExtension(const std::string &filename)
323{
324 // extract the extension
325 size_t dot = filename.find_last_of(".");
326 std::string ext = filename.substr(dot, filename.size() - 1);
327 return ext;
328}
329
336{
337 if (first_frame < 0) {
338 throw(vpException(vpException::fatalError, "Video writer first frame index cannot be negative"));
339 }
340 m_firstFrame = first_frame;
341}
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ 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
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.
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:135
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:184
static void makeDirectory(const std::string &dirname)
static std::string getParent(const std::string &pathname)
void saveFrame(vpImage< vpRGBa > &I)
virtual ~vpVideoWriter()
void setFileName(const std::string &filename)
void open(vpImage< vpRGBa > &I)
void setFirstFrameIndex(int first_frame)