PageRenderTime 150ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/videoio/src/cap_images.cpp

https://gitlab.com/dlts/opencv
C++ | 376 lines | 259 code | 61 blank | 56 comment | 34 complexity | 7a7f2b5f6d8f2f7f30a0df23378f0825 MD5 | raw file
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  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.
  8. //
  9. //
  10. // Intel License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2008, Nils Hasler, all rights reserved.
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  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.
  25. //
  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.
  28. //
  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.
  39. //
  40. //M*/
  41. // Author: Nils Hasler <hasler@mpi-inf.mpg.de>
  42. //
  43. // Max-Planck-Institut Informatik
  44. //
  45. // capture video from a sequence of images
  46. // the filename when opening can either be a printf pattern such as
  47. // video%04d.png or the first frame of the sequence i.e. video0001.png
  48. //
  49. #include "precomp.hpp"
  50. #include <sys/stat.h>
  51. #ifdef NDEBUG
  52. #define CV_WARN(message)
  53. #else
  54. #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
  55. #endif
  56. #ifndef _MAX_PATH
  57. #define _MAX_PATH 1024
  58. #endif
  59. class CvCapture_Images : public CvCapture
  60. {
  61. public:
  62. CvCapture_Images()
  63. {
  64. filename = 0;
  65. currentframe = firstframe = 0;
  66. length = 0;
  67. frame = 0;
  68. }
  69. virtual ~CvCapture_Images()
  70. {
  71. close();
  72. }
  73. virtual bool open(const char* _filename);
  74. virtual void close();
  75. virtual double getProperty(int) const;
  76. virtual bool setProperty(int, double);
  77. virtual bool grabFrame();
  78. virtual IplImage* retrieveFrame(int);
  79. protected:
  80. char* filename; // actually a printf-pattern
  81. unsigned currentframe;
  82. unsigned firstframe; // number of first frame
  83. unsigned length; // length of sequence
  84. IplImage* frame;
  85. };
  86. void CvCapture_Images::close()
  87. {
  88. if( filename )
  89. {
  90. free(filename);
  91. filename = 0;
  92. }
  93. currentframe = firstframe = 0;
  94. length = 0;
  95. cvReleaseImage( &frame );
  96. }
  97. bool CvCapture_Images::grabFrame()
  98. {
  99. char str[_MAX_PATH];
  100. sprintf(str, filename, firstframe + currentframe);
  101. cvReleaseImage(&frame);
  102. frame = cvLoadImage(str, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
  103. if( frame )
  104. currentframe++;
  105. return frame != 0;
  106. }
  107. IplImage* CvCapture_Images::retrieveFrame(int)
  108. {
  109. return frame;
  110. }
  111. double CvCapture_Images::getProperty(int id) const
  112. {
  113. switch(id)
  114. {
  115. case CV_CAP_PROP_POS_MSEC:
  116. CV_WARN("collections of images don't have framerates\n");
  117. return 0;
  118. case CV_CAP_PROP_POS_FRAMES:
  119. return currentframe;
  120. case CV_CAP_PROP_FRAME_COUNT:
  121. return length;
  122. case CV_CAP_PROP_POS_AVI_RATIO:
  123. return (double)currentframe / (double)(length - 1);
  124. case CV_CAP_PROP_FRAME_WIDTH:
  125. return frame ? frame->width : 0;
  126. case CV_CAP_PROP_FRAME_HEIGHT:
  127. return frame ? frame->height : 0;
  128. case CV_CAP_PROP_FPS:
  129. CV_WARN("collections of images don't have framerates\n");
  130. return 1;
  131. case CV_CAP_PROP_FOURCC:
  132. CV_WARN("collections of images don't have 4-character codes\n");
  133. return 0;
  134. }
  135. return 0;
  136. }
  137. bool CvCapture_Images::setProperty(int id, double value)
  138. {
  139. switch(id)
  140. {
  141. case CV_CAP_PROP_POS_MSEC:
  142. case CV_CAP_PROP_POS_FRAMES:
  143. if(value < 0) {
  144. CV_WARN("seeking to negative positions does not work - clamping\n");
  145. value = 0;
  146. }
  147. if(value >= length) {
  148. CV_WARN("seeking beyond end of sequence - clamping\n");
  149. value = length - 1;
  150. }
  151. currentframe = cvRound(value);
  152. return true;
  153. case CV_CAP_PROP_POS_AVI_RATIO:
  154. if(value > 1) {
  155. CV_WARN("seeking beyond end of sequence - clamping\n");
  156. value = 1;
  157. } else if(value < 0) {
  158. CV_WARN("seeking to negative positions does not work - clamping\n");
  159. value = 0;
  160. }
  161. currentframe = cvRound((length - 1) * value);
  162. return true;
  163. }
  164. CV_WARN("unknown/unhandled property\n");
  165. return false;
  166. }
  167. static char* icvExtractPattern(const char *filename, unsigned *offset)
  168. {
  169. char *name = (char *)filename;
  170. if( !filename )
  171. return 0;
  172. // check whether this is a valid image sequence filename
  173. char *at = strchr(name, '%');
  174. if(at)
  175. {
  176. int dummy;
  177. if(sscanf(at + 1, "%ud", &dummy) != 1)
  178. return 0;
  179. name = strdup(filename);
  180. }
  181. else // no pattern filename was given - extract the pattern
  182. {
  183. at = name;
  184. // ignore directory names
  185. char *slash = strrchr(at, '/');
  186. if (slash) at = slash + 1;
  187. #ifdef _WIN32
  188. slash = strrchr(at, '\\');
  189. if (slash) at = slash + 1;
  190. #endif
  191. while (*at && !isdigit(*at)) at++;
  192. if(!*at)
  193. return 0;
  194. sscanf(at, "%u", offset);
  195. int size = (int)strlen(filename) + 20;
  196. name = (char *)malloc(size);
  197. strncpy(name, filename, at - filename);
  198. name[at - filename] = 0;
  199. strcat(name, "%0");
  200. int i;
  201. char *extension;
  202. for(i = 0, extension = at; isdigit(at[i]); i++, extension++)
  203. ;
  204. char places[10];
  205. sprintf(places, "%dd", i);
  206. strcat(name, places);
  207. strcat(name, extension);
  208. }
  209. return name;
  210. }
  211. bool CvCapture_Images::open(const char * _filename)
  212. {
  213. unsigned offset = 0;
  214. close();
  215. filename = icvExtractPattern(_filename, &offset);
  216. if(!filename)
  217. return false;
  218. // determine the length of the sequence
  219. length = 0;
  220. char str[_MAX_PATH];
  221. for(;;)
  222. {
  223. sprintf(str, filename, offset + length);
  224. struct stat s;
  225. if(stat(str, &s))
  226. {
  227. if(length == 0 && offset == 0) // allow starting with 0 or 1
  228. {
  229. offset++;
  230. continue;
  231. }
  232. }
  233. if(!cvHaveImageReader(str))
  234. break;
  235. length++;
  236. }
  237. if(length == 0)
  238. {
  239. close();
  240. return false;
  241. }
  242. firstframe = offset;
  243. return true;
  244. }
  245. CvCapture* cvCreateFileCapture_Images(const char * filename)
  246. {
  247. CvCapture_Images* capture = new CvCapture_Images;
  248. if( capture->open(filename) )
  249. return capture;
  250. delete capture;
  251. return 0;
  252. }
  253. //
  254. //
  255. // image sequence writer
  256. //
  257. //
  258. class CvVideoWriter_Images : public CvVideoWriter
  259. {
  260. public:
  261. CvVideoWriter_Images()
  262. {
  263. filename = 0;
  264. currentframe = 0;
  265. }
  266. virtual ~CvVideoWriter_Images() { close(); }
  267. virtual bool open( const char* _filename );
  268. virtual void close();
  269. virtual bool writeFrame( const IplImage* );
  270. protected:
  271. char* filename;
  272. unsigned currentframe;
  273. };
  274. bool CvVideoWriter_Images::writeFrame( const IplImage* image )
  275. {
  276. char str[_MAX_PATH];
  277. sprintf(str, filename, currentframe);
  278. int ret = cvSaveImage(str, image);
  279. currentframe++;
  280. return ret > 0;
  281. }
  282. void CvVideoWriter_Images::close()
  283. {
  284. if( filename )
  285. {
  286. free( filename );
  287. filename = 0;
  288. }
  289. currentframe = 0;
  290. }
  291. bool CvVideoWriter_Images::open( const char* _filename )
  292. {
  293. unsigned offset = 0;
  294. close();
  295. filename = icvExtractPattern(_filename, &offset);
  296. if(!filename)
  297. return false;
  298. char str[_MAX_PATH];
  299. sprintf(str, filename, 0);
  300. if(!cvHaveImageWriter(str))
  301. {
  302. close();
  303. return false;
  304. }
  305. currentframe = offset;
  306. return true;
  307. }
  308. CvVideoWriter* cvCreateVideoWriter_Images( const char* filename )
  309. {
  310. CvVideoWriter_Images *writer = new CvVideoWriter_Images;
  311. if( writer->open( filename ))
  312. return writer;
  313. delete writer;
  314. return 0;
  315. }