![]() |
University of Murcia, Spain ![]() |
examples/OpenCV/siftDetector/hess/utils.cpp00001 /* 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 */ |