No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cva-match.c 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: cva-match.c
  5. *
  6. * Description: Match an image to its parent image, and return the coordinates
  7. *
  8. * Version: 0.1
  9. * Created: 06/20/2012
  10. * Revision: none
  11. * Compiler: gcc
  12. *
  13. * Author: Bradlee Speice, bspeice@uncc.edu
  14. * Organization: MOSAIC at University of North Carolina at Charlotte
  15. *
  16. * =====================================================================================
  17. */
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <unistd.h>
  21. #include <getopt.h>
  22. #include <limits.h>
  23. #include <libcvautomation/libcvautomation.h>
  24. void usage ();
  25. /// \cond
  26. struct list {
  27. char *fileName;
  28. struct list *next;
  29. };
  30. typedef struct list basic_list;
  31. /// \endcond
  32. int main( int argc, char** argv )
  33. {
  34. cvaPoint result_point;
  35. result_point.x = result_point.y = 0;
  36. /* Set up everything for getopt */
  37. char *separator = ",";
  38. char *root_location = "root.png";
  39. char *sub_location = "sub.png";
  40. int tolerance = INT_MAX;
  41. int search_method = CV_TM_SQDIFF;
  42. int useX = 0; /* bool useX = false; */
  43. Bool useCenter = False;
  44. char *xDisplayLocation;
  45. Display *display = NULL;
  46. /* Set the default display */
  47. xDisplayLocation = "";
  48. /* Set up the linked list for slave images */
  49. basic_list *list_head, *list_curr, *list_prev;
  50. list_head = list_curr = list_prev = NULL;
  51. int returnCode = 1;
  52. /* Start getopt */
  53. while (1)
  54. {
  55. static struct option long_options[] =
  56. {
  57. {"help", no_argument, 0, 'h'},
  58. {"usage", no_argument, 0, 'u'},
  59. {"version", no_argument, 0, 'v'},
  60. {"root-image", required_argument, 0, 'r'},
  61. {"sub-image", required_argument, 0, 's'},
  62. {"separator", required_argument, 0, 'p'},
  63. {"search-method",required_argument, 0, 'm'},
  64. {"tolerance", required_argument, 0, 't'},
  65. {"x-root", optional_argument, 0, 'x'},
  66. {"center", no_argument, 0, 'c'},
  67. {"sane-tolerance", required_argument, 0, 'o'},
  68. {0, 0, 0, 0}
  69. };
  70. int option_index = 0;
  71. opterr = 0;
  72. int c = getopt_long (argc, argv, "hur:s:p:m:t:x::c",
  73. long_options, &option_index);
  74. /* We're done with parsing options */
  75. if (c == -1)
  76. break;
  77. switch (c)
  78. {
  79. case 0:
  80. break;
  81. case 'h':
  82. usage();
  83. break;
  84. case 'u':
  85. usage();
  86. break;
  87. case 'v':
  88. usage();
  89. break;
  90. case 'r':
  91. root_location = optarg;
  92. break;
  93. case 's':
  94. if ( list_head == NULL )
  95. {
  96. list_head = (basic_list *) malloc (sizeof(basic_list));
  97. list_curr = list_head;
  98. }
  99. list_curr->fileName = optarg;
  100. list_curr->next = (basic_list *) malloc (sizeof(basic_list));
  101. list_curr->next->fileName = NULL;
  102. list_curr = list_curr->next;
  103. break;
  104. case 'p':
  105. separator = optarg;
  106. break;
  107. case 'm':
  108. search_method = atoi(optarg);
  109. break;
  110. case 't':
  111. tolerance = atoi(optarg);
  112. break;
  113. case 'x':
  114. if ( optarg != NULL ) {
  115. useX = 1;
  116. xDisplayLocation = optarg;
  117. display = XOpenDisplay(xDisplayLocation);
  118. } else {
  119. useX = 1;
  120. xDisplayLocation = "";
  121. display = XOpenDisplay(xDisplayLocation);
  122. }
  123. break;
  124. case 'c':
  125. useCenter = True;
  126. break;
  127. case 'o':
  128. tolerance = atoi(optarg);
  129. /* Provide a more sane way to configure tolerance:
  130. * --sane-tolerance=100 ~= INT_MAX */
  131. tolerance = pow(1.2397076, tolerance);
  132. break;
  133. case '?':
  134. /* Error routine */
  135. break;
  136. default:
  137. fprintf( stderr, "Unknown option..." );
  138. exit(0);
  139. };
  140. }
  141. /* Make sure we have a linked list,
  142. * and reset the linked list to go back through from the top */
  143. if ( list_head == NULL )
  144. return 1;
  145. else
  146. list_curr = list_head;
  147. do
  148. {
  149. sub_location = list_curr->fileName;
  150. if (useX && useCenter)
  151. result_point = matchSubImage_X11_location_center( display, sub_location, search_method, tolerance );
  152. else if (useX && !useCenter)
  153. result_point = matchSubImage_X11_location( display, sub_location, search_method, tolerance );
  154. else if (!useX && useCenter)
  155. result_point = matchSubImage_location_center( root_location, sub_location, search_method, tolerance );
  156. else /* if (!useX && !useCenter) */
  157. result_point = matchSubImage_location( root_location, sub_location, search_method, tolerance );
  158. if ( result_point.x != -1 && result_point.y != -1 )
  159. {
  160. /* Output the match location */
  161. printf ("%s%s%i%s%i\n", list_curr->fileName, separator,
  162. result_point.x, separator, result_point.y );
  163. returnCode = 0;
  164. }
  165. /* With the way we allocate the list, we ensure that we always
  166. * have at least one element past the end of the list.
  167. * Also, deconstruct the list as we go. */
  168. list_prev = list_curr;
  169. list_curr = list_curr->next;
  170. free(list_prev);
  171. } while ( list_curr->fileName != NULL );
  172. /* And free the final element */
  173. free(list_curr);
  174. /* Clean up X */
  175. if (useX)
  176. XCloseDisplay(display);
  177. return returnCode;
  178. }
  179. /*
  180. * === FUNCTION ======================================================================
  181. * Name: usage
  182. * Description: I really shouldn't need to write this
  183. * =====================================================================================
  184. */
  185. void usage ( )
  186. {
  187. fprintf( stderr, "\
  188. Libcvautomation version: %s\n\
  189. cva-match -r <root_image> -s <sub_image> \n\
  190. cva-match -s <sub_image> -x \n\
  191. \n\
  192. This program uses OpenCV in order to recognize an image within an image.\n\
  193. The return code is 0 for at least one successful match, and 1 otherwise.\n\
  194. \n\
  195. Usage: \n\
  196. \n\
  197. \t-h, --help:\t\tDisplay this usage message.\n\
  198. \t-u, --usage:\t\tDisplay this usage message.\n\
  199. \t-r, --root-image:\tLocation of the root image to compare against.\n\
  200. \t-s, --sub-image:\tLocation of the sub-image to find in root.\n\
  201. \t-p, --separator:\tSeparator of the X and Y coordinates.\n\
  202. \t-t, --tolerance:\tSet how strict the match is - 100 is recommended lowest value.\n\
  203. \t\t\t\tNote: When using CCORR or CCOEFF tolerance works in opposite direction,\n\
  204. \t\t\t\tso -50 is recommended highest value.\n\
  205. \t-m, --search-method:\tSet which method is used to search for sub-images.\n\
  206. \t\t\t\tMethods:\n\
  207. \t\t\t\t\tCV_TM_SQDIFF = 0\n\
  208. \t\t\t\t\tCV_TM_SQDIFF_NORMED = 1\n\
  209. \t\t\t\t\tCV_TM_CCORR = 2\n\
  210. \t\t\t\t\tCV_TM_CCORR_NORMED = 3\n\
  211. \t\t\t\t\tCV_TM_CCOEFF = 4\n\
  212. \t\t\t\t\tCV_TM_COEFF_NORMED = 5\n\
  213. \t-x, --x-root[=DISPLAY]:\tSet the root image to come from X11\n\
  214. \t\t\t\tThe DISPLAY variable is optional, not specifying it will cause X\n\
  215. \t\t\t\tto use the default display (not specifically :0.0)\n\
  216. \t\t\t\tPlease note also that the '-x' must come at the end\n\
  217. \t\t\t\tsince it is an optional argument.\n\
  218. \t-c, --center:\t\tThe output points should be centered on the sub-image, rather\n\
  219. \t\t\t\tthan the top-left corner.\n\
  220. \t-o, --sane-tolerance:\tSet the tolerance using a scale of 1-100,\n\
  221. \t\t\t\trather than INT_MIN to INT_MAX (100 ~= INT_MAX)\n\
  222. \n\
  223. If you have any questions, comments, concerns, email <%s>\n", LIBCVAUTOMATION_VERSION, LIBCVAUTOMATION_BUGREPORT );
  224. exit (0);
  225. } /* ----- end of function usage ----- */
  226. /* Doxygen Information */
  227. /** \file cva-match.c
  228. * \brief The cva-input program to demonstrate Libcvautomation's XTest functionality
  229. * \author Bradlee Speice <bspeice@uncc.edu>
  230. */
  231. /* The biggest purpose of documenting this code is to trick doxygen into making a man page for it. */
  232. /** \page cva-match
  233. *
  234. * \author Bradlee Speice <bspeice@uncc.edu>
  235. * \section usage Usage:
  236. * This program uses OpenCV in order to recognize an image within an image. The return code is 0 for at least one successful match, and 1 otherwise.
  237. *
  238. * \section example Example Usage:
  239. * Match two images against the root X11 window:
  240. *
  241. * cva-match --x-root -s "<image_name>" -s "<image_name_2>"
  242. *
  243. * Match a root and sub image with a custom tolerance and search method
  244. *
  245. * cva-match -r "<root_image>" -s "<image_name>" -o 75 -m 1
  246. *
  247. * \section options Full Options:
  248. * -h, --help: Display this usage message.
  249. *
  250. * -u, --usage: Display this usage message.
  251. *
  252. * -r, --root-image: Location of the root image to compare against.
  253. *
  254. * -s, --sub-image: Location of the sub-image to find in root.
  255. *
  256. * -p, --separator: Separator of the X and Y coordinates.
  257. *
  258. * -t, --tolerance: Set how strict the match is - 100 is recommended lowest value.
  259. *
  260. * \note When using CCORR or CCOEFF tolerance works in opposite direction, so -50 is recommended highest value.
  261. *
  262. * -m, --search-method: Set which method is used to search for sub-images.
  263. *
  264. * \note Search Methods: CV_TM_SQDIFF = 0, CV_TM_SQDIFF_NORMED = 1, CV_TM_CCORR = 2, CV_TM_CCORR_NORMED = 3, CV_TM_CCOEFF = 4, CV_TM_COEFF_NORMED = 5
  265. *
  266. * -x, --x-root[=DISPLAY]: Set the root image to come from X11
  267. *
  268. * \note The DISPLAY variable is optional, not specifying it will cause X to use the default display (not specifically :0.0)
  269. *
  270. * -c, --center: The output points should be centered on the sub-image, rather than the top-left corner.
  271. *
  272. * -o, --sane-tolerance: Set the tolerance using a scale of 1-100, rather than INT_MIN to INT_MAX (100 ~= INT_MAX)
  273. *
  274. *
  275. * \section contact Contact Information:
  276. * Questions? Comments? Concerns? Suggestions? Send all feedback to Bradlee Speice at <bspeice@uncc.edu>
  277. */