Add functions for working with arrays of images to match

Also, change "threshold" to "tolerance," it's much more descriptive
This commit is contained in:
Bradlee Speice 2012-06-22 09:16:44 -04:00
parent f1048394c8
commit a63c54f9c4
6 changed files with 106 additions and 30 deletions

View File

@ -41,7 +41,7 @@ int main( int argc, char** argv )
char *separator = ","; char *separator = ",";
char *root_location = "root.png"; char *root_location = "root.png";
char *sub_location = "sub.png"; char *sub_location = "sub.png";
int threshold = INT_MAX; int tolerance = INT_MAX;
int search_method = CV_TM_SQDIFF; int search_method = CV_TM_SQDIFF;
int useX = 0; /* bool useX = false; */ int useX = 0; /* bool useX = false; */
char *xDisplay; char *xDisplay;
@ -60,7 +60,7 @@ int main( int argc, char** argv )
{"sub-image", required_argument, 0, 's'}, {"sub-image", required_argument, 0, 's'},
{"separator", required_argument, 0, 'p'}, {"separator", required_argument, 0, 'p'},
{"search-method",required_argument, 0, 'm'}, {"search-method",required_argument, 0, 'm'},
{"threshold", required_argument, 0, 't'}, {"tolerance", required_argument, 0, 't'},
{"x-root", optional_argument, 0, 'x'}, {"x-root", optional_argument, 0, 'x'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -112,7 +112,7 @@ int main( int argc, char** argv )
break; break;
case 't': case 't':
threshold = atoi(optarg); tolerance = atoi(optarg);
break; break;
case 'x': case 'x':
@ -148,9 +148,9 @@ int main( int argc, char** argv )
sub_location = list_curr->fileName; sub_location = list_curr->fileName;
if (useX) if (useX)
result_point = matchSubImage_X11_location( xDisplay, sub_location, search_method, threshold ); result_point = matchSubImage_X11_location( xDisplay, sub_location, search_method, tolerance );
else else
result_point = matchSubImage_location( root_location, sub_location, search_method, threshold ); result_point = matchSubImage_location( root_location, sub_location, search_method, tolerance );
if ( result_point.x != -1 && result_point.y != -1 ) if ( result_point.x != -1 && result_point.y != -1 )
/* Output the match location */ /* Output the match location */
@ -195,8 +195,8 @@ Usage: \n\
\t-r, --root-image:\tLocation of the root image to compare against.\n\ \t-r, --root-image:\tLocation of the root image to compare against.\n\
\t-s, --sub-image:\tLocation of the sub-image to find in root.\n\ \t-s, --sub-image:\tLocation of the sub-image to find in root.\n\
\t-p, --separator:\tSeparator of the X and Y coordinates.\n\ \t-p, --separator:\tSeparator of the X and Y coordinates.\n\
\t-t, --threshold:\tSet how strict the match is - 100 is recommended lowest value.\n\ \t-t, --tolerance:\tSet how strict the match is - 100 is recommended lowest value.\n\
\t\t\t\tNote: When using CCORR or CCOEFF threshold works in opposite direction,\n\ \t\t\t\tNote: When using CCORR or CCOEFF tolerance works in opposite direction,\n\
\t\t\t\tso -50 is recommended highest value.\n\ \t\t\t\tso -50 is recommended highest value.\n\
\t-m, --search-method:\tSet which method is used to search for sub-images.\n\ \t-m, --search-method:\tSet which method is used to search for sub-images.\n\
\t\t\t\tMethods:\n\ \t\t\t\tMethods:\n\

View File

@ -25,7 +25,7 @@
* ===================================================================================== * =====================================================================================
*/ */
CvPoint matchSubImage ( IplImage *rootImage, IplImage *subImage, int searchMethod, double threshold ) CvPoint matchSubImage ( IplImage *rootImage, IplImage *subImage, int searchMethod, double tolerance )
{ {
/* We have the two OpenCV images we want, go ahead and find if there are any matches */ /* We have the two OpenCV images we want, go ahead and find if there are any matches */
IplImage *result; IplImage *result;
@ -71,14 +71,14 @@ CvPoint matchSubImage ( IplImage *rootImage, IplImage *subImage, int searchMetho
/* Return the match location */ /* Return the match location */
if ( searchMethod == CV_TM_SQDIFF || searchMethod == CV_TM_SQDIFF_NORMED ) if ( searchMethod == CV_TM_SQDIFF || searchMethod == CV_TM_SQDIFF_NORMED )
{ {
if ( minval < threshold ) if ( minval < tolerance )
return minloc; return minloc;
else else
return badpoint; return badpoint;
} }
else else
{ {
if ( maxval > threshold ) if ( maxval > tolerance )
return maxloc; return maxloc;
else else
return badpoint; return badpoint;
@ -92,7 +92,7 @@ CvPoint matchSubImage ( IplImage *rootImage, IplImage *subImage, int searchMetho
* Description: Match a root image and sub image from filename * Description: Match a root image and sub image from filename
* ===================================================================================== * =====================================================================================
*/ */
CvPoint matchSubImage_location ( char *rootImage_location, char *subImage_location, int searchMethod, double threshold ) CvPoint matchSubImage_location ( char *rootImage_location, char *subImage_location, int searchMethod, double tolerance )
{ {
/* This is basically a wrapper for matchSubImage( IplImage, IplImage ) /* This is basically a wrapper for matchSubImage( IplImage, IplImage )
* All we do is load the images from the given filenames, and then * All we do is load the images from the given filenames, and then
@ -113,7 +113,7 @@ CvPoint matchSubImage_location ( char *rootImage_location, char *subImage_locati
return return_point; return return_point;
} }
return_point = matchSubImage( rootImage, subImage, searchMethod, threshold ); return_point = matchSubImage( rootImage, subImage, searchMethod, tolerance );
/* Free up the memory we created */ /* Free up the memory we created */
cvReleaseImage( &rootImage ); cvReleaseImage( &rootImage );
@ -123,3 +123,66 @@ CvPoint matchSubImage_location ( char *rootImage_location, char *subImage_locati
return return_point; return return_point;
} /* ----- end of function matchSubImage ----- */ } /* ----- end of function matchSubImage ----- */
/*
* === FUNCTION ======================================================================
* Name: matchSubImage_list
* Description: Match a root image and sub image from a list of sub-images.
* The list contains an element for each sub-image to specify its own
* searchMethod and threshold value.
* =====================================================================================
*/
void matchSubImage_list ( IplImage *rootImage, cvautomationList *subImageListHead, int listSize )
{
/* This is also a higher-end wrapper for matchSubImage, but is mostly aimed
* at making python support for multiple images very easy. */
CvPoint resultPoint;
cvautomationList curr;
int x = 0;
for ( x = 0; x < listSize; x++ )
{
curr = subImageList[x];
if ( subImageListHead[x].cvaImage != 0 )
resultPoint = matchSubImage ( rootImage, curr.cvaImage, curr.searchMethod, curr.tolerance );
else
resultPoint = matchSubImage ( rootImage, curr.fileName, curr.searchMethod, curr.tolerance );
curr.resultPoint = resultPoint;
}
}
/*
* === FUNCTION ======================================================================
* Name: matchSubImage_list_location
* Description: Match a root image from location, and sub image from
* a list of sub-images.
* The list contains an element for each sub-image to specify its own
* searchMethod and threshold value.
* =====================================================================================
*/
void matchSubImage_list ( char *rootImageFileName, cvautomationList *subImageListHead, int listSize )
{
/* This is also a higher-end wrapper for matchSubImage, but is mostly aimed
* at making python support for multiple images very easy. */
CvPoint resultPoint;
cvautomationList curr;
IplImage *rootImage;
rootImage = cvLoadImage ( rootImageFileName, CV_LOAD_IMAGE_COLOR );
int x = 0;
for ( x = 0; x < listSize; x++ )
{
curr = subImageList[x];
if ( subImageListHead[x].cvaImage != 0 )
resultPoint = matchSubImage ( rootImage, curr.cvaImage, curr.searchMethod, curr.tolerance );
else
resultPoint = matchSubImage ( rootImage, curr.fileName, curr.searchMethod, curr.tolerance );
curr.resultPoint = resultPoint;
}
}

View File

@ -18,8 +18,7 @@
#ifndef LIBCVAUTOMATION_OPENCV_H #ifndef LIBCVAUTOMATION_OPENCV_H
#define LIBCVAUTOMATION_OPENCV_H #define LIBCVAUTOMATION_OPENCV_H
#include <opencv/cv.h> #include "libcvautomation.h"
#include <opencv/highgui.h>
/* It should be noted that the following are the macros for template matching: /* It should be noted that the following are the macros for template matching:
* CV_TM_SQDIFF (default) * CV_TM_SQDIFF (default)
@ -31,9 +30,12 @@
*/ */
/* Match a root image and sub image */ /* Match a root image and sub image */
CvPoint matchSubImage ( IplImage *rootImage, IplImage *subImage, int searchMethod, double threshold ); CvPoint matchSubImage ( IplImage *rootImage, IplImage *subImage, int searchMethod, double tolerance );
/* Match a root image and sub image from filename */ /* Match a root image and sub image from filename */
CvPoint matchSubImage_location ( char *rootImage_location, char *subImage_location, int searchMethod, double threshold ); CvPoint matchSubImage_location ( char *rootImage_location, char *subImage_location, int searchMethod, double tolerance );
/* Match a root image and sub images from a list of images */
void matchSubImage_list ( IplImage *rootImage, cvautomationList *subImageListHead, int listSize )
#endif /* LIBCVAUTOMATION_OPENCV_H */ #endif /* LIBCVAUTOMATION_OPENCV_H */

View File

@ -24,7 +24,7 @@
* Description: Match a sub image using the X11 root window as root * Description: Match a sub image using the X11 root window as root
* ===================================================================================== * =====================================================================================
*/ */
CvPoint matchSubImage_X11( char *displayLocation, IplImage *subImage, int searchMethod, int threshold ) CvPoint matchSubImage_X11( char *displayLocation, IplImage *subImage, int searchMethod, int tolerance )
{ {
/* First things first, grab the root X window and convert it to /* First things first, grab the root X window and convert it to
* the IplImage format. * the IplImage format.
@ -159,7 +159,7 @@ CvPoint matchSubImage_X11( char *displayLocation, IplImage *subImage, int search
* However, we don't want to do any more work than we have to - send our images off * However, we don't want to do any more work than we have to - send our images off
* to matchSubImage in libopencvautomation-opencv. */ * to matchSubImage in libopencvautomation-opencv. */
resultPoint = matchSubImage ( X_IPL, subImage, searchMethod, threshold ); resultPoint = matchSubImage ( X_IPL, subImage, searchMethod, tolerance );
/* Clean up the CV image we created, as well as all X resources */ /* Clean up the CV image we created, as well as all X resources */
XDestroyImage( rootImage ); XDestroyImage( rootImage );
@ -177,7 +177,7 @@ CvPoint matchSubImage_X11( char *displayLocation, IplImage *subImage, int search
* Description: Match a sub image using the X11 root window as root, from filename * Description: Match a sub image using the X11 root window as root, from filename
* ===================================================================================== * =====================================================================================
*/ */
CvPoint matchSubImage_X11_location( char *displayLocation, char *subImage_location, int searchMethod, int threshold ) CvPoint matchSubImage_X11_location( char *displayLocation, char *subImage_location, int searchMethod, int tolerance )
{ {
/* This is basically a wrapper for matchSubImage_X11( char *display, IplImage ) /* This is basically a wrapper for matchSubImage_X11( char *display, IplImage )
* All we do is load the sub-image from the given filename, and then * All we do is load the sub-image from the given filename, and then
@ -195,7 +195,7 @@ CvPoint matchSubImage_X11_location( char *displayLocation, char *subImage_locati
return return_point; return return_point;
} }
return_point = matchSubImage_X11( displayLocation, subImage, searchMethod, threshold ); return_point = matchSubImage_X11( displayLocation, subImage, searchMethod, tolerance );
/* Free up the memory we created */ /* Free up the memory we created */
cvReleaseImage( &subImage ); cvReleaseImage( &subImage );

View File

@ -19,12 +19,6 @@
#ifndef LIBCVAUTOMATION_X11_H #ifndef LIBCVAUTOMATION_X11_H
#define LIBCVAUTOMATION_X11_H #define LIBCVAUTOMATION_X11_H
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "libcvautomation.h" #include "libcvautomation.h"
/* It should be noted that the following are the macros for template matching: /* It should be noted that the following are the macros for template matching:
@ -36,7 +30,7 @@
* CV_TM_CCOEFF_NORMED * CV_TM_CCOEFF_NORMED
*/ */
CvPoint matchSubImage_X11( char *displayLocation, IplImage *subImage, int searchMethod, int threshold ); /* Match a sub image using the X11 root window as root */ CvPoint matchSubImage_X11( char *displayLocation, IplImage *subImage, int searchMethod, int tolerance ); /* Match a sub image using the X11 root window as root */
CvPoint matchSubImage_X11_location( char *displayLocation, char *rootImage_location, int search_method, int threshold ); /* Match a sub image using X11 as root, from filename */ CvPoint matchSubImage_X11_location( char *displayLocation, char *rootImage_location, int search_method, int tolerance ); /* Match a sub image using X11 as root, from filename */
#endif /* LIBCVAUTOMATION_X11_H */ #endif /* LIBCVAUTOMATION_X11_H */

View File

@ -19,7 +19,24 @@
#define LIBCVAUTOMATION_H #define LIBCVAUTOMATION_H
#include <stdio.h> #include <stdio.h>
#include "libcvautomation-opencv.h"
#include "libcvautomation-x11.h" #include <opencv/cv.h>
#include <opencv/highgui.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/* Define a basic structure to help us with using multiple-picture arguments
* Yes, it's a hackish implementation, nobody said you had to use this one. */
typedef struct {
/* Use one or the other of fileName or cvaImage - cvaImage takes priority */
IplImage *cvaImage;
char *fileName;
CvPoint resultPoint;
int searchMethod;
int tolerance;
} cvautomationList;
#endif /* LIBCVAUTOMATION_H */ #endif /* LIBCVAUTOMATION_H */