/**** capture images with OpenCV from a list of files This is like the OpenCV cvCreateFileCapture, but instead of a video file, it uses a list of single image files. It therefore needs an own init-function (cvCaptureFromSingleFiles). The other functions can be accessed with the standard-OpenCV-functions cvReleaseCapture, cvGrabFrame, cvRetrieveFrame, cvQueryFrame, cvGetCaptureProperty and cvSetCaptureProperty. :Version: 2009-03-11 :Status: beta :Usage: CvCapture* cvCaptureFromSingleFiles(char **filenames, int frames, int manually); :Parameter: - filenames: array of files to use - frames: number of frames; if -1: use all frames of *NULL-terminated* filenames-array - manually: | should the frames be controlled manually? | 0 = at each grab: return next frame | 1 = at each grab: show frame, manually select which frame to return :Example: Load images from a NULL-terminates list:: const char *imagefiles[] = { "image1.tif", "image2.tif", "image3.tif", "image4.tif", NULL } CvCapture *capture = cvCaptureFromSingleFiles(imagefiles, -1, 0); IplImage *frame; cvNamedWindow("test", CV_WINDOW_AUTOSIZE); while(1) { frame = cvQueryFrame(capture); if(!frame) break; cvShowImage("test", frame); if(27 == (cvWaitKey(-1) & 0xFFFF)) break; } Set the images-filenames from command-line-parameters:: capture = cvCaptureFromSingleFiles(&(argv[1]), argc-1, 0); Get the filename of the current image:: char *filename = ((CvCapture_SingleFiles*)capture)->current_filename; :Note: manual frame control: | '+',SPACE: next frame | '-': previous frame | RETURN: return this frame | ESC: return no frame :Uses: OpenCV 1.0.0, GLib 2.0 :SeeAlso: OpenCV-documentation, cvcap*.c :Author: Roland Koebler (rk@koebler.com) :Copyright: (c) 2007-2009 by Roland Koebler (rk@koebler.com) :License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***/ //======================================== #include #include #include "cvcap_singlefiles.h" //======================================== //--------------------- //directly copied from from _highgui.h typedef void (CV_CDECL* CvCaptureCloseFunc) ( CvCapture* capture ); typedef int (CV_CDECL* CvCaptureGrabFrameFunc) ( CvCapture* capture ); typedef IplImage * (CV_CDECL* CvCaptureRetrieveFrameFunc) ( CvCapture* capture ); typedef double (CV_CDECL* CvCaptureGetPropertyFunc) ( CvCapture* capture, int id ); typedef int (CV_CDECL* CvCaptureSetPropertyFunc) ( CvCapture* capture, int id, double value ); typedef const char * (CV_CDECL* CvCaptureGetDescriptionFunc)( CvCapture* capture ); typedef struct CvCaptureVTable { int count; CvCaptureCloseFunc close; CvCaptureGrabFrameFunc grab_frame; CvCaptureRetrieveFrameFunc retrieve_frame; CvCaptureGetPropertyFunc get_property; CvCaptureSetPropertyFunc set_property; CvCaptureGetDescriptionFunc get_description; } CvCaptureVTable; /*typedef struct CvCapture { CvCaptureVTable* vtable; } CvCapture;*/ //--------------------- typedef struct CvCapture_SingleFiles { CvCaptureVTable* vtable; char **filenames; const char *current_filename; int current; int next; int frame_count; IplImage* rgb_frame; int manually; } CvCapture_SingleFiles; //======================================== /****************** Capturing video from a list of image-files *******************/ static int icvOpen_SingleFiles( CvCapture_SingleFiles *capture, char **filenames, int frames ) { capture->current_filename = NULL; capture->current = 0; capture->next = 0; if( frames == -1 ) { capture->filenames = g_strdupv(filenames); capture->frame_count = g_strv_length(filenames); } else { g_assert( frames >= 0 ); capture->frame_count = frames; capture->filenames = g_new0(char*, frames+1); int i; for(i=0; ifilenames[i] = g_strdup(filenames[i]); } } capture->rgb_frame = NULL; return 1; } static void icvClose_SingleFiles( CvCapture_SingleFiles *capture ) { if( capture->rgb_frame ) { cvReleaseImage( &(capture->rgb_frame) ); } capture->rgb_frame = NULL; g_strfreev(capture->filenames); capture->filenames = NULL; capture->frame_count = 0; } static int icvGrabFrame_SingleFiles( CvCapture_SingleFiles *capture ) { if( !capture->manually ) { if( capture->next <= capture->frame_count && capture->filenames[capture->next] ) { capture->current = capture->next; capture->next++; if( capture->rgb_frame ) { cvReleaseImage( &capture->rgb_frame ); capture->rgb_frame = NULL; } capture->current_filename = capture->filenames[capture->current]; capture->rgb_frame = cvLoadImage( capture->current_filename, CV_LOAD_IMAGE_ANYCOLOR ); return 1; } return 0; } else { int key; g_message("cvcap_singlefiles: please press +/SPACE/-/RETURN/ESC"); while(1) { if( capture->rgb_frame ) { cvReleaseImage( &capture->rgb_frame ); capture->rgb_frame = NULL; } capture->current_filename = capture->filenames[capture->current]; capture->rgb_frame = cvLoadImage( capture->current_filename, CV_LOAD_IMAGE_ANYCOLOR ); if( capture->rgb_frame == NULL ) { g_warning("cannot load image '%s'", capture->current_filename); return 0; } g_debug("image '%s'", capture->current_filename); cvNamedWindow("cvcap_singlefiles (+,Space|-|Return|ESC)", CV_WINDOW_AUTOSIZE); cvShowImage( "cvcap_singlefiles (+,Space|-|Return|ESC)", capture->rgb_frame); key = cvWaitKey(-1) & 0x7F; switch(key) { case(' '): case('+'): if( capture->next <= capture->frame_count && capture->filenames[capture->next] ) { capture->current = capture->next; capture->next++; } break; case('-'): if( capture->next-2 >= 0 && capture->filenames[capture->next-2] ) { capture->current = capture->next-2; capture->next--; } break; case('\n'): case('\r'): return 1; case(27): //ESC return 0; } } } } static IplImage* icvRetrieveFrame_SingleFiles( CvCapture_SingleFiles *capture ) { return capture->rgb_frame; } static double icvGetProperty_SingleFiles( CvCapture_SingleFiles *capture, int property_id ) { switch( property_id ) { case CV_CAP_PROP_POS_FRAMES: return capture->next; case CV_CAP_PROP_FRAME_WIDTH: if( capture->rgb_frame) return capture->rgb_frame->width; break; case CV_CAP_PROP_FRAME_HEIGHT: if( capture->rgb_frame) return capture->rgb_frame->height; break; case CV_CAP_PROP_FRAME_COUNT: return capture->frame_count; case CV_CAP_PROP_CAPTURETYPE: return CAPTURE_TYPE_SINGLEFILES; break; } return 0; } static int icvSetProperty_SingleFiles( CvCapture_SingleFiles *capture, int property_id, double value ) { switch( property_id ) { case CV_CAP_PROP_POS_FRAMES: if( (int)value <= capture->frame_count ) { capture->next = (int)value; return 1; } break; case CV_CAP_PROP_FRAME_WIDTH: if( capture->rgb_frame) return capture->rgb_frame->width; break; case CV_CAP_PROP_FRAME_HEIGHT: if( capture->rgb_frame) return capture->rgb_frame->height; break; } return 0; } static CvCaptureVTable capture_SingleFiles_vtable = { 6, (CvCaptureCloseFunc)icvClose_SingleFiles, (CvCaptureGrabFrameFunc)icvGrabFrame_SingleFiles, (CvCaptureRetrieveFrameFunc)icvRetrieveFrame_SingleFiles, (CvCaptureGetPropertyFunc)icvGetProperty_SingleFiles, (CvCaptureSetPropertyFunc)icvSetProperty_SingleFiles, (CvCaptureGetDescriptionFunc)0 }; CvCapture* cvCaptureFromSingleFiles(char **filenames, int frames, int manually ) { g_assert(manually == 0 || manually == 1); CvCapture_SingleFiles *capture = (CvCapture_SingleFiles*)cvAlloc(sizeof(CvCapture_SingleFiles)); memset( capture, 0, sizeof(*capture)); capture->vtable = &capture_SingleFiles_vtable; capture->manually = manually; icvOpen_SingleFiles( capture, filenames, frames ); return (CvCapture*)capture; } //========================================