Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpVideoWriter.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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
38
39#include <visp3/core/vpIoTools.h>
40#include <visp3/io/vpVideoWriter.h>
41
42#if defined(HAVE_OPENCV_IMGPROC)
43#include <opencv2/imgproc/imgproc.hpp>
44#endif
45
47
52 :
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_writer(), m_framerate(25.0),
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_width(0), m_height(0), m_frameStep(1)
60{
61#if defined(VISP_HAVE_OPENCV) && \
62 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
63 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
64#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
65 m_fourcc = cv::VideoWriter::fourcc('P', 'I', 'M', '1');
66#else
67 m_fourcc = CV_FOURCC('P', 'I', 'M', '1'); // default is a MPEG-1 codec
68#endif
69#endif
70}
71
76
91void vpVideoWriter::setFileName(const std::string &filename)
92{
93 if (filename.empty()) {
94 throw(vpImageException(vpImageException::noFileNameError, "Filename empty in video writer"));
95 }
96
97 m_videoName = filename;
98 m_frameName = filename;
99
100 m_formatType = getFormat(filename);
101
102 if (m_formatType == FORMAT_UNKNOWN) {
103 throw(vpException(vpException::badValue, "Filename extension not supported in video writer"));
104 }
105
106 m_initFileName = true;
107}
108
118{
119 if (!m_initFileName) {
120 throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set in video writer"));
121 }
122
124
125 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
126 m_formatType == FORMAT_PNG) {
127 m_width = I.getWidth();
128 m_height = I.getHeight();
129 }
130 else if (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
131 m_formatType == FORMAT_MOV) {
132#if defined(VISP_HAVE_OPENCV) && \
133 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
134 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
135 m_writer = cv::VideoWriter(m_videoName, m_fourcc, m_framerate,
136 cv::Size(static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight())));
137
138 if (!m_writer.isOpened()) {
139 throw(vpException(vpException::fatalError, "Could not encode the video with OpenCV"));
140 }
141#else
142 throw(vpException(vpException::fatalError, "To encode video files ViSP should be build with OpenCV >= 2.1.0"));
143#endif
144 }
145
146 m_frameCount = m_firstFrame;
147
148 m_isOpen = true;
149}
150
160{
161 if (!m_initFileName) {
162 throw(vpImageException(vpImageException::noFileNameError, "The generic filename has to be set in video writer"));
163 }
164
166
167 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
168 m_formatType == FORMAT_PNG) {
169 m_width = I.getWidth();
170 m_height = I.getHeight();
171 }
172 else if (m_formatType == FORMAT_AVI || m_formatType == FORMAT_MPEG || m_formatType == FORMAT_MPEG4 ||
173 m_formatType == FORMAT_MOV) {
174#if defined(VISP_HAVE_OPENCV) && \
175 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
176 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
177 m_writer = cv::VideoWriter(m_videoName, m_fourcc, m_framerate,
178 cv::Size(static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight())));
179
180 if (!m_writer.isOpened()) {
181 throw(vpException(vpException::fatalError, "Could not encode the video with OpenCV"));
182 }
183#else
184 throw(vpException(vpException::fatalError, "To encode video files ViSP should be build with OpenCV >= 2.1.0"));
185#endif
186 }
187
188 m_frameCount = m_firstFrame;
189
190 m_isOpen = true;
191}
192
203{
204 if (!m_isOpen) {
205 throw(vpException(vpException::notInitialized, "The video has to be open first with video writer open() method"));
206 }
207
208 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
209 m_formatType == FORMAT_PNG) {
210 m_frameName = vpIoTools::formatString(m_videoName, m_frameCount);
211 vpImageIo::write(I, m_frameName);
212 }
213 else {
214#if defined(VISP_HAVE_OPENCV) && \
215 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
216 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
217 cv::Mat matFrame;
218 vpImageConvert::convert(I, matFrame);
219 m_writer << matFrame;
220#endif
221 }
222
223 m_frameCount += m_frameStep;
224}
225
236{
237 if (!m_isOpen) {
238 throw(vpException(vpException::notInitialized, "The video has to be open first with video writer open() method"));
239 }
240
241 if (m_formatType == FORMAT_PGM || m_formatType == FORMAT_PPM || m_formatType == FORMAT_JPEG ||
242 m_formatType == FORMAT_PNG) {
243 m_frameName = vpIoTools::formatString(m_videoName, m_frameCount);
244 vpImageIo::write(I, m_frameName);
245 }
246 else {
247#if defined(VISP_HAVE_OPENCV) && \
248 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || \
249 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
250#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
251 cv::Mat matFrame, rgbMatFrame;
252 vpImageConvert::convert(I, matFrame);
253 cv::cvtColor(matFrame, rgbMatFrame, cv::COLOR_GRAY2BGR);
254 m_writer << rgbMatFrame;
255#else
256 cv::Mat matFrame, rgbMatFrame;
257 vpImageConvert::convert(I, matFrame);
258 cv::cvtColor(matFrame, rgbMatFrame, CV_GRAY2BGR);
259 m_writer << rgbMatFrame;
260#endif
261#endif
262 }
263
264 m_frameCount += m_frameStep;
265}
266
271{
272 if (!m_isOpen) {
273 throw(vpException(vpException::notInitialized, "Cannot close video writer: not yet opened"));
274 }
275}
276
282vpVideoWriter::vpVideoFormatType vpVideoWriter::getFormat(const std::string &filename)
283{
284 std::string ext = vpVideoWriter::getExtension(filename);
285
286 if (ext.compare(".PGM") == 0)
287 return FORMAT_PGM;
288 else if (ext.compare(".pgm") == 0)
289 return FORMAT_PGM;
290 else if (ext.compare(".PPM") == 0)
291 return FORMAT_PPM;
292 else if (ext.compare(".ppm") == 0)
293 return FORMAT_PPM;
294 else if (ext.compare(".JPG") == 0)
295 return FORMAT_JPEG;
296 else if (ext.compare(".jpg") == 0)
297 return FORMAT_JPEG;
298 else if (ext.compare(".JPEG") == 0)
299 return FORMAT_JPEG;
300 else if (ext.compare(".jpeg") == 0)
301 return FORMAT_JPEG;
302 else if (ext.compare(".PNG") == 0)
303 return FORMAT_PNG;
304 else if (ext.compare(".png") == 0)
305 return FORMAT_PNG;
306 else if (ext.compare(".AVI") == 0)
307 return FORMAT_AVI;
308 else if (ext.compare(".avi") == 0)
309 return FORMAT_AVI;
310 else if (ext.compare(".MPEG") == 0)
311 return FORMAT_MPEG;
312 else if (ext.compare(".mpeg") == 0)
313 return FORMAT_MPEG;
314 else if (ext.compare(".MPG") == 0)
315 return FORMAT_MPEG;
316 else if (ext.compare(".mpg") == 0)
317 return FORMAT_MPEG;
318 else if (ext.compare(".MPEG4") == 0)
319 return FORMAT_MPEG4;
320 else if (ext.compare(".mpeg4") == 0)
321 return FORMAT_MPEG4;
322 else if (ext.compare(".MP4") == 0)
323 return FORMAT_MPEG4;
324 else if (ext.compare(".mp4") == 0)
325 return FORMAT_MPEG4;
326 else if (ext.compare(".MOV") == 0)
327 return FORMAT_MOV;
328 else if (ext.compare(".mov") == 0)
329 return FORMAT_MOV;
330 else
331 return FORMAT_UNKNOWN;
332}
333
334// return the extension of the file including the dot
335std::string vpVideoWriter::getExtension(const std::string &filename)
336{
337 // extract the extension
338 size_t dot = filename.find_last_of(".");
339 std::string ext = filename.substr(dot, filename.size() - 1);
340 return ext;
341}
342
349{
350 if (first_frame < 0) {
351 throw(vpException(vpException::fatalError, "Video writer first frame index cannot be negative"));
352 }
353 m_firstFrame = first_frame;
354}
355
356END_VISP_NAMESPACE
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ 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
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:131
static std::string formatString(const std::string &name, unsigned int val)
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)