cva-match.c

Go to the documentation of this file.
00001 /*
00002  * =====================================================================================
00003  *
00004  *       Filename:  cva-match.c
00005  *
00006  *    Description:  Match an image to its parent image, and return the coordinates
00007  *
00008  *        Version:  0.1
00009  *        Created:  06/20/2012
00010  *       Revision:  none
00011  *       Compiler:  gcc
00012  *
00013  *         Author:  Bradlee Speice, bspeice@uncc.edu
00014  *   Organization:  MOSAIC at University of North Carolina at Charlotte
00015  *
00016  * =====================================================================================
00017  */
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <unistd.h>
00021 #include <getopt.h>
00022 #include <limits.h>
00023 
00024 #include <libcvautomation/libcvautomation.h>
00025 
00026 void usage ();
00027 
00028 struct list {
00029     char *fileName;
00030     struct list *next;
00031 };
00032 
00033 typedef struct list basic_list; 
00034 
00035 int main( int argc, char** argv )
00036 {
00037     CvPoint result_point;
00038     result_point.x = result_point.y = 0;
00039 
00040     /* Set up everything for getopt */
00041     char *separator = ",";
00042     char *root_location = "root.png";
00043     char *sub_location = "sub.png";
00044     int tolerance = INT_MAX;
00045     int search_method = CV_TM_SQDIFF;
00046     int useX = 0; /* bool useX = false; */
00047     int useCenter = 0;
00048     char *xDisplayLocation;
00049     Display *display;
00050     /* This line to suppress a compiler warning */
00051     display = NULL;
00052 
00053     /* Set the default display */
00054     xDisplayLocation = "";
00055 
00056     /* Set up the linked list for slave images */
00057     basic_list *list_head = NULL, *list_curr = NULL, *list_prev = NULL;
00058 
00059     /* Start getopt */
00060     while (1)
00061     {
00062         static struct option long_options[] =
00063         {
00064                 {"help",        no_argument,        0,  'h'},
00065                 {"usage",       no_argument,        0,  'u'},
00066                 {"version",     no_argument,        0,  'v'},
00067                 {"root-image",  required_argument,  0,  'r'},
00068                 {"sub-image",   required_argument,  0,  's'},
00069                 {"separator",   required_argument,  0,  'p'},
00070                 {"search-method",required_argument, 0,  'm'},
00071                 {"tolerance",   required_argument,  0,  't'},
00072                 {"x-root",      optional_argument,  0,  'x'},
00073                 {"center",      no_argument,        0,  'c'},
00074                 {"sane-tolerance", required_argument, 0, 'o'},
00075                 {0, 0, 0, 0}
00076         };
00077 
00078         int option_index = 0;
00079         opterr = 0;
00080 
00081         int c = getopt_long (argc, argv, "hur:s:p:m:t:x::c",
00082                             long_options, &option_index);
00083 
00084         /* We're done with parsing options */
00085         if (c == -1)
00086             break;
00087 
00088         switch (c)
00089         {
00090             case 0:
00091                 break;
00092 
00093             case 'h':
00094                 usage();
00095                 break;
00096 
00097             case 'u':
00098                 usage();
00099                 break;
00100 
00101             case 'v':
00102                 usage();
00103                 break;
00104 
00105             case 'r':
00106                 root_location = optarg;
00107                 break;
00108 
00109             case 's':
00110                 if ( list_head == NULL )
00111                 {
00112                     list_head = (basic_list *) malloc (sizeof(basic_list));
00113                     list_curr = list_head;
00114                 }
00115                 list_curr->fileName = optarg;
00116                 list_curr->next = (basic_list *) malloc (sizeof(basic_list));
00117                 list_curr = list_curr->next;
00118                 break;
00119 
00120             case 'p':
00121                 separator = optarg;
00122                 break;
00123 
00124             case 'm':
00125                 search_method = atoi(optarg);
00126                 break;
00127 
00128             case 't':
00129                 tolerance = atoi(optarg);
00130                 break;
00131 
00132             case 'x':
00133                 if ( optarg != NULL ) {
00134                     useX = 1;
00135                     xDisplayLocation = optarg;
00136                     display = XOpenDisplay(xDisplayLocation);
00137                 } else {
00138                     useX = 1;
00139                     xDisplayLocation = "";
00140                     display = XOpenDisplay(xDisplayLocation);
00141                 }
00142                 break;
00143 
00144             case 'c':
00145                 useCenter = 1;
00146 
00147             case 'o':
00148                 tolerance = atoi(optarg);
00149                 /* Provide a more sane way to configure tolerance:
00150                  * --sane-tolerance=100 ~= INT_MAX */
00151                 tolerance = pow(1.2397076, tolerance);
00152                 break;
00153 
00154             case '?':
00155                 /* Error routine */
00156                 break;
00157 
00158             default:
00159                 fprintf( stderr, "Unknown option..." );
00160                 exit(0);
00161         };
00162     }
00163 
00164     /* Make sure we have a linked list, 
00165      * and reset the linked list to go back through from the top */
00166     if ( list_head == NULL )
00167         return 1;
00168     else
00169         list_curr = list_head;
00170 
00171     do
00172     {
00173         sub_location = list_curr->fileName;
00174 
00175         if (useX && useCenter)
00176             result_point = matchSubImage_X11_location_center( display, sub_location, search_method, tolerance );
00177         else if (useX && !useCenter)
00178             result_point = matchSubImage_X11_location( display, sub_location, search_method, tolerance );
00179         else if (!useX && useCenter)
00180             result_point = matchSubImage_location_center( root_location, sub_location, search_method, tolerance );
00181         else /* if (!useX && !useCenter) */
00182             result_point = matchSubImage_location( root_location, sub_location, search_method, tolerance );
00183 
00184         if ( result_point.x != -1 && result_point.y != -1 )
00185             /* Output the match location */
00186             printf ("%s%s%i%s%i\n", list_curr->fileName, separator,
00187                     result_point.x, separator, result_point.y );
00188 
00189         /* With the way we allocate the list, we ensure that we always
00190          * have at least one element past the end of the list.
00191          * Also, deconstruct the list as we go. */
00192         list_prev = list_curr;
00193         list_curr = list_curr->next;
00194         free(list_prev);
00195 
00196     } while ( list_curr->fileName != NULL );
00197 
00198     /* And free the final element */
00199     free(list_curr);
00200 
00201     /* Clean up X */
00202     if (useX)
00203         XCloseDisplay(display);
00204 
00205     return 0;
00206 }
00207 
00208 /* 
00209  * ===  FUNCTION  ======================================================================
00210  *         Name:  usage
00211  *  Description:  I really shouldn't need to write this
00212  * =====================================================================================
00213  */
00214 void usage ( )
00215 {
00216     fprintf( stderr, "\
00217 Libcvautomation version: %s\n\
00218 cva-match -r <root_image> -s <sub_image> \n\
00219 cva-match -s <sub_image> -x \n\
00220 \n\
00221 This program uses OpenCV in order to recognize an image within an image.\n\
00222 The return code is how many matches were found - return 0 for no matches,\n\
00223 1 for one match, etc.\n\
00224 \n\
00225 Usage: \n\
00226 \n\
00227 \t-h, --help:\t\tDisplay this usage message.\n\
00228 \t-u, --usage:\t\tDisplay this usage message.\n\
00229 \t-r, --root-image:\tLocation of the root image to compare against.\n\
00230 \t-s, --sub-image:\tLocation of the sub-image to find in root.\n\
00231 \t-p, --separator:\tSeparator of the X and Y coordinates.\n\
00232 \t-t, --tolerance:\tSet how strict the match is - 100 is recommended lowest value.\n\
00233 \t\t\t\tNote: When using CCORR or CCOEFF tolerance works in opposite direction,\n\
00234 \t\t\t\tso -50 is recommended highest value.\n\
00235 \t-m, --search-method:\tSet which method is used to search for sub-images.\n\
00236 \t\t\t\tMethods:\n\
00237 \t\t\t\t\tCV_TM_SQDIFF = 0\n\
00238 \t\t\t\t\tCV_TM_SQDIFF_NORMED = 1\n\
00239 \t\t\t\t\tCV_TM_CCORR = 2\n\
00240 \t\t\t\t\tCV_TM_CCORR_NORMED = 3\n\
00241 \t\t\t\t\tCV_TM_CCOEFF = 4\n\
00242 \t\t\t\t\tCV_TM_COEFF_NORMED = 5\n\
00243 \t-x, --x-root[=DISPLAY]:\tSet the root image to come from X11\n\
00244 \t\t\t\tThe DISPLAY variable is optional, not specifying it will cause X\n\
00245 \t\t\t\tto use the default display (not specifically :0.0)\n\
00246 \t\t\t\tPlease note also that the '-x' must come at the end\n\
00247 \t\t\t\tsince it is an optional argument.\n\
00248 \t-c, --center:\t\tThe output points should be centered on the sub-image, rather\n\
00249 \t\t\t\tthan the top-left corner.\n\
00250 \t-o, --sane-tolerance:\tSet the tolerance using a scale of 1-100,\n\
00251 \t\t\t\trather than INT_MIN to INT_MAX (100 ~= INT_MAX)\n\
00252 \n\
00253 If you have any questions, comments, concerns, email <%s>\n", LIBCVAUTOMATION_VERSION, LIBCVAUTOMATION_BUGREPORT );
00254 
00255     exit (0);
00256 
00257 }       /* -----  end of function usage  ----- */
00258 
00259 /* Doxygen Information */
00266 /* The biggest purpose of documenting this code is to trick doxygen into making a man page for it. */

Generated on Tue Jul 17 12:19:00 2012 for libcvautomation by  doxygen 1.4.7