PARP Research Group University of Murcia, Spain


examples/OpenCV/siftDetector/hess/utils.cpp

00001 /*
00002   Miscellaneous utility functions.
00003   
00004   Copyright (C) 2006-2007  Rob Hess <hess@eecs.oregonstate.edu>
00005 
00006   @version 1.1.1-20070913
00007 */
00008 
00009 #include "utils.h"
00010 
00011 #include <cv.h>
00012 #include <cxcore.h>
00013 #include <highgui.h>
00014 
00015 //#include <gdk/gdk.h>
00016 //#include <gtk/gtk.h>
00017 
00018 #include <errno.h>
00019 #include <string.h>
00020 #include <stdlib.h>
00021 #include <stdarg.h>
00022 
00023 /*************************** Function Definitions ****************************/
00024 
00025 
00026 /*
00027   Prints an error message and aborts the program.  The error message is
00028   of the form "Error: ...", where the ... is specified by the \a format
00029   argument
00030   
00031   @param format an error message format string (as with \c printf(3)).
00032 */
00033 void fatal_error(char* format, ...)
00034 {
00035   va_list ap;
00036   
00037   fprintf( stderr, "Error: ");
00038 
00039   va_start( ap, format );
00040   vfprintf( stderr, format, ap );
00041   va_end( ap );
00042   fprintf( stderr, "\n" );
00043   abort();
00044 }
00045 
00046 
00047 
00048 /*
00049   Replaces a file's extension, which is assumed to be everything after the
00050   last dot ('.') character.
00051   
00052   @param file the name of a file
00053   
00054   @param extn a new extension for \a file; should not include a dot (i.e.
00055     \c "jpg", not \c ".jpg") unless the new file extension should contain
00056     two dots.
00057     
00058   @return Returns a new string formed as described above.  If \a file does
00059     not have an extension, this function simply adds one.
00060 */
00061 char* replace_extension( const char* file, const char* extn )
00062 {
00063   char* new_file, * lastdot;
00064 
00065   new_file = (char *) calloc( strlen( file ) + strlen( extn ) + 2,  sizeof( char ) );
00066   strcpy( new_file, file );
00067   lastdot = strrchr( new_file, '.' );
00068   if( lastdot )
00069     *(lastdot + 1) = '\0';
00070   else
00071     strcat( new_file, "." );
00072   strcat( new_file, extn );
00073 
00074   return new_file;
00075 }
00076 
00077 
00078 
00079 /*
00080   Prepends a path to a filename.
00081   
00082   @param path a path
00083   @param file a file name
00084   
00085   @return Returns a new string containing a full path name consisting of
00086     \a path prepended to \a file.
00087 */
00088 char* prepend_path( const char* path, const char* file )
00089 {
00090   int n = strlen(path) + strlen(file) + 2;
00091   char* pathname = (char *) calloc( n, sizeof(char) );
00092 
00093   snprintf( pathname, n, "%s/%s", path, file );
00094 
00095   return pathname;
00096 }
00097 
00098 
00099 
00100 /*
00101   A function that removes the path from a filename.  Similar to the Unix
00102   basename command.
00103   
00104   @param pathname a (full) path name
00105   
00106   @return Returns the basename of \a pathname.
00107 */
00108 /*char* basename( const char* pathname )
00109 {
00110   char* base, * last_slash;
00111 
00112   last_slash = strrchr( pathname, '/' );
00113   if( ! last_slash )
00114     {
00115       base = (char *) calloc( strlen( pathname ) + 1, sizeof( char ) );
00116       strcpy( base, pathname );
00117     }
00118   else
00119     {
00120       base = (char *) calloc( strlen( last_slash++ ), sizeof( char ) );
00121       strcpy( base, last_slash );
00122     }
00123 
00124   return base;
00125 }*/
00126 
00127 
00128 
00129 /*
00130   Displays progress in the console with a spinning pinwheel.  Every time this
00131   function is called, the state of the pinwheel is incremented.  The pinwheel
00132   has four states that loop indefinitely: '|', '/', '-', '\'.
00133   
00134   @param done if 0, this function simply increments the state of the pinwheel;
00135     otherwise it prints "done"
00136 */
00137 void progress( int done )
00138 {
00139   char state[4] = { '|', '/', '-', '\\' };
00140   static int cur = -1;
00141   
00142   if( cur == -1 )
00143     fprintf( stderr, "  " );
00144 
00145   if( done )
00146     {
00147       fprintf( stderr, "\b\bdone\n");
00148       cur = -1;
00149     }
00150   else
00151     {
00152       cur = ( cur + 1 ) % 4;
00153       fprintf( stdout, "\b\b%c ", state[cur] );
00154       fflush(stderr);
00155     }
00156 }
00157 
00158 
00159 
00160 /*
00161   Erases a specified number of characters from a stream.
00162 
00163   @param stream the stream from which to erase characters
00164   @param n the number of characters to erase
00165 */
00166 void erase_from_stream( FILE* stream, int n )
00167 {
00168   int j;
00169   for( j = 0; j < n; j++ )
00170     fprintf( stream, "\b" );
00171   for( j = 0; j < n; j++ )
00172     fprintf( stream, " " );
00173   for( j = 0; j < n; j++ )
00174     fprintf( stream, "\b" );
00175 }
00176 
00177 
00178 
00179 /*
00180   Doubles the size of an array with error checking
00181   
00182   @param array pointer to an array whose size is to be doubled
00183   @param n number of elements allocated for \a array
00184   @param size size in bytes of elements in \a array
00185   
00186   @return Returns the new number of elements allocated for \a array.  If no
00187     memory is available, returns 0.
00188 */
00189 int array_double( void** array, int n, int size )
00190 {
00191   void* tmp;
00192 
00193   tmp = realloc( *array, 2 * n * size );
00194   if( ! tmp )
00195     {
00196       fprintf( stderr, "Warning: unable to allocate memory in array_double(),"
00197                " %s line %d\n", __FILE__, __LINE__ );
00198       if( *array )
00199         free( *array );
00200       *array = NULL;
00201       return 0;
00202     }
00203   *array = tmp;
00204   return n*2;
00205 }
00206 
00207 
00208 
00209 /*
00210   Calculates the squared distance between two points.
00211 
00212   @param p1 a point
00213   @param p2 another point
00214 */
00215 double dist_sq_2D( CvPoint2D64f p1, CvPoint2D64f p2 )
00216 {
00217   double x_diff = p1.x - p2.x;
00218   double y_diff = p1.y - p2.y;
00219 
00220   return x_diff * x_diff + y_diff * y_diff;
00221 }
00222 
00223 
00224 
00225 /*
00226   Draws an x on an image.
00227   
00228   @param img an image
00229   @param pt the center point of the x
00230   @param r the x's radius
00231   @param w the x's line weight
00232   @param color the color of the x
00233 */
00234 void draw_x( IplImage* img, CvPoint pt, int r, int w, CvScalar color )
00235 {
00236   cvLine( img, pt, cvPoint( pt.x + r, pt.y + r), color, w, 8, 0 );
00237   cvLine( img, pt, cvPoint( pt.x - r, pt.y + r), color, w, 8, 0 );
00238   cvLine( img, pt, cvPoint( pt.x + r, pt.y - r), color, w, 8, 0 );
00239   cvLine( img, pt, cvPoint( pt.x - r, pt.y - r), color, w, 8, 0 );
00240 }
00241 
00242 
00243 
00244 /*
00245   Combines two images by scacking one on top of the other
00246   
00247   @param img1 top image
00248   @param img2 bottom image
00249   
00250   @return Returns the image resulting from stacking \a img1 on top if \a img2
00251 */
00252 extern IplImage* stack_imgs( IplImage* img1, IplImage* img2 )
00253 {
00254   IplImage* stacked = cvCreateImage( cvSize( MAX(img1->width, img2->width),
00255                                              img1->height + img2->height ),
00256                                      IPL_DEPTH_8U, 3 );
00257 
00258   cvZero( stacked );
00259   cvSetImageROI( stacked, cvRect( 0, 0, img1->width, img1->height ) );
00260   cvAdd( img1, stacked, stacked, NULL );
00261   cvSetImageROI( stacked, cvRect(0, img1->height, img2->width, img2->height) );
00262   cvAdd( img2, stacked, stacked, NULL );
00263   cvResetImageROI( stacked );
00264 
00265   return stacked;
00266 }
00267 
00268 
00269 
00270 /*
00271   Displays an image, making sure it fits on screen.  cvWaitKey() must be
00272   called after this function so the event loop is entered and the
00273   image is displayed.
00274   
00275   @param img an image, possibly too large to display on-screen
00276   @param title the title of the window in which \a img is displayed
00277 */
00278 /*void display_big_img( IplImage* img, char* title )
00279 {
00280   IplImage* small;
00281   GdkScreen* scr;
00282   int scr_width, scr_height;
00283   double img_aspect, scr_aspect, scale;
00284 
00285   gdk_init( NULL, NULL );
00286   scr = gdk_screen_get_default();
00287   scr_width = gdk_screen_get_width( scr );
00288   scr_height = gdk_screen_get_height( scr );
00289 
00290   if( img->width >= 0.90 * scr_width  ||  img->height >= 0.90 * scr_height )
00291     {
00292       img_aspect = (double)(img->width) / img->height;
00293       scr_aspect = (double)(scr_width) / scr_height;
00294       
00295       if( img_aspect > scr_aspect )
00296         scale = 0.90 * scr_width / img->width;
00297       else
00298         scale = 0.90 * scr_height / img->height;
00299 
00300       small = cvCreateImage( cvSize( img->width * scale, img->height * scale ),
00301                              img->depth, img->nChannels );
00302       cvResize( img, small, CV_INTER_AREA );
00303     }
00304   else
00305     small = cvCloneImage( img );
00306   
00307   cvNamedWindow( title, 1 );
00308   cvShowImage( title, small );
00309   cvReleaseImage( &small );
00310 }
00311 */
00312 
00313 
00314 /*
00315   Allows user to view an array of images as a video.  Keyboard controls
00316   are as follows:
00317 
00318   <ul>
00319   <li>Space - start and pause playback</li>
00320   <li>Page Down - skip forward 10 frames</li>
00321   <li>Page Up - jump back 10 frames</li>
00322   <li>Right Arrow - skip forward 1 frame</li>
00323   <li>Left Arrow - jump back 1 frame</li>
00324   <li>Backspace - jump back to beginning</li>
00325   <li>Esc - exit playback</li>
00326   <li>Closing the window also exits playback</li>
00327   </ul>
00328   
00329   @param imgs an array of images
00330   @param n number of images in \a imgs
00331   @param win_name name of window in which images are displayed
00332 */
00333 /*void vid_view( IplImage** imgs, int n, char* win_name )
00334 {
00335   int k, i = 0, playing = 0;
00336 
00337   display_big_img( imgs[i], win_name );
00338   while( ! win_closed( win_name ) )
00339     {
00340 
00341       if( playing )
00342         {
00343           i = MIN( i + 1, n - 1 );
00344           display_big_img( imgs[i], win_name );
00345           k = cvWaitKey( 33 );
00346           if( k == ' '  ||  i == n - 1 )
00347             playing = 0;
00348         }
00349 
00350       else
00351         {
00352           k = cvWaitKey( 0 );
00353           switch( k )
00354             {
00355 
00356             case ' ':
00357               playing = 1;
00358               break;
00359 
00360 
00361             case 27:
00362             case 1048603:
00363               cvDestroyWindow( win_name );
00364               break;
00365 
00366 
00367             case '\b':
00368               i = 0;
00369               display_big_img( imgs[i], win_name );
00370               break;
00371 
00372 
00373             case 65288:
00374             case 1113937:
00375               i = MAX( i - 1, 0 );
00376               display_big_img( imgs[i], win_name );
00377               break;
00378 
00379 
00380             case 65363:
00381             case 1113939:
00382               i = MIN( i + 1, n - 1 );
00383               display_big_img( imgs[i], win_name );
00384               break;
00385 
00386 
00387             case 65365:
00388             case 1113941:
00389               i = MAX( i - 10, 0 );
00390               display_big_img( imgs[i], win_name );
00391               break;
00392 
00393 
00394             case 65366:
00395             case 1113942:
00396               i = MIN( i + 10, n - 1 );
00397               display_big_img( imgs[i], win_name );
00398               break;
00399             }
00400         }
00401     }
00402 }
00403 */
00404 
00405 
00406 /*
00407   Checks if a HighGUI window is still open or not
00408   
00409   @param name the name of the window we're checking
00410   
00411   @return Returns 1 if the window named \a name has been closed or 0 otherwise
00412 */
00413 /*
00414 int win_closed( char* win_name )
00415 {
00416   if( ! cvGetWindowHandle(win_name) )
00417     return 1;
00418   return 0;
00419 }
00420 */



QVision framework. PARP research group, copyright 2007, 2008.