1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2008, Nils Hasler, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 // Author: Nils Hasler <hasler@mpi-inf.mpg.de>
44 // Max-Planck-Institut Informatik
47 // capture video from a sequence of images
48 // the filename when opening can either be a printf pattern such as
49 // video%04d.png or the first frame of the sequence i.e. video0001.png
52 #include "precomp.hpp"
56 #define CV_WARN(message)
58 #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
62 #define _MAX_PATH 1024
65 class CvCapture_Images : public CvCapture
71 currentframe = firstframe = 0;
76 virtual ~CvCapture_Images()
81 virtual bool open(const char* _filename);
83 virtual double getProperty(int);
84 virtual bool setProperty(int, double);
85 virtual bool grabFrame();
86 virtual IplImage* retrieveFrame(int);
89 char* filename; // actually a printf-pattern
90 unsigned currentframe;
91 unsigned firstframe; // number of first frame
92 unsigned length; // length of sequence
98 void CvCapture_Images::close()
105 currentframe = firstframe = 0;
107 cvReleaseImage( &frame );
111 bool CvCapture_Images::grabFrame()
114 sprintf(str, filename, firstframe + currentframe);
116 cvReleaseImage(&frame);
117 frame = cvLoadImage(str, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
124 IplImage* CvCapture_Images::retrieveFrame(int)
129 double CvCapture_Images::getProperty(int id)
133 case CV_CAP_PROP_POS_MSEC:
134 CV_WARN("collections of images don't have framerates\n");
136 case CV_CAP_PROP_POS_FRAMES:
138 case CV_CAP_PROP_POS_AVI_RATIO:
139 return (double)currentframe / (double)(length - 1);
140 case CV_CAP_PROP_FRAME_WIDTH:
141 return frame ? frame->width : 0;
142 case CV_CAP_PROP_FRAME_HEIGHT:
143 return frame ? frame->height : 0;
144 case CV_CAP_PROP_FPS:
145 CV_WARN("collections of images don't have framerates\n");
147 case CV_CAP_PROP_FOURCC:
148 CV_WARN("collections of images don't have 4-character codes\n");
154 bool CvCapture_Images::setProperty(int id, double value)
158 case CV_CAP_PROP_POS_MSEC:
159 case CV_CAP_PROP_POS_FRAMES:
161 CV_WARN("seeking to negative positions does not work - clamping\n");
164 if(value >= length) {
165 CV_WARN("seeking beyond end of sequence - clamping\n");
168 currentframe = cvRound(value);
170 case CV_CAP_PROP_POS_AVI_RATIO:
172 CV_WARN("seeking beyond end of sequence - clamping\n");
174 } else if(value < 0) {
175 CV_WARN("seeking to negative positions does not work - clamping\n");
178 currentframe = cvRound((length - 1) * value);
181 CV_WARN("unknown/unhandled property\n");
185 static char* icvExtractPattern(const char *filename, unsigned *offset)
187 char *name = (char *)filename;
192 // check whether this is a valid image sequence filename
193 char *at = strchr(name, '%');
197 if(sscanf(at + 1, "%ud", &dummy) != 1)
199 name = strdup(filename);
201 else // no pattern filename was given - extract the pattern
205 // ignore directory names
206 char *slash = strrchr(at, '/');
207 if (slash) at = slash + 1;
210 slash = strrchr(at, '\\');
211 if (slash) at = slash + 1;
214 while (*at && !isdigit(*at)) at++;
219 sscanf(at, "%u", offset);
221 int size = (int)strlen(filename) + 20;
222 name = (char *)malloc(size);
223 strncpy(name, filename, at - filename);
224 name[at - filename] = 0;
230 for(i = 0, extension = at; isdigit(at[i]); i++, extension++)
233 sprintf(places, "%dd", i);
235 strcat(name, places);
236 strcat(name, extension);
243 bool CvCapture_Images::open(const char * _filename)
248 filename = icvExtractPattern(_filename, &offset);
252 // determine the length of the sequence
257 sprintf(str, filename, offset + length);
261 if(length == 0 && offset == 0) // allow starting with 0 or 1
268 if(!cvHaveImageReader(str))
285 CvCapture* cvCreateFileCapture_Images(const char * filename)
287 CvCapture_Images* capture = new CvCapture_Images;
289 if( capture->open(filename) )
298 // image sequence writer
301 class CvVideoWriter_Images : public CvVideoWriter
304 CvVideoWriter_Images()
309 virtual ~CvVideoWriter_Images() { close(); }
311 virtual bool open( const char* _filename );
312 virtual void close();
313 virtual bool writeFrame( const IplImage* );
317 unsigned currentframe;
320 bool CvVideoWriter_Images::writeFrame( const IplImage* image )
323 sprintf(str, filename, currentframe);
324 int ret = cvSaveImage(str, image);
331 void CvVideoWriter_Images::close()
342 bool CvVideoWriter_Images::open( const char* _filename )
348 filename = icvExtractPattern(_filename, &offset);
353 sprintf(str, filename, 0);
354 if(!cvHaveImageWriter(str))
360 currentframe = offset;
365 CvVideoWriter* cvCreateVideoWriter_Images( const char* filename )
367 CvVideoWriter_Images *writer = new CvVideoWriter_Images;
369 if( writer->open( filename ))