Hello everyone,
I'm working on a Image Processing project on Java for mobile devices. In application, there're some dialogs/buttons which I try to find with image recognition and click on. But, if there's NOT a matching, OpenCV template matching function still finds a match. I've tried to fix this based on minMaxVal but I could't make it. So here's my question: How should I prevent it to find not existing matches? How should I do thresholding?
I'm using Canny edge detector and here's my code:
...
// Some parameters to use in every turn of for loop.
double[] found = new double[4];
Point mLoc = null;
float r = 0;
// Variables for linspace.
double linStart;
double linEnd;
double counter;
double space;
// Start counter
int ctr = 0;
// Values for linspace and for loop.
linStart = 1.0;
linEnd = 0.2;
counter = 20;
space = (linStart - linEnd) / counter;
// For loop. The mothership of automation.
for (double scale = linStart; scale >= linEnd; scale = scale - space) {
// Get H and W of grayed image. And multiply the width with the scale for multi-scaling.
int gryW = Highgui.imread(imageGrayStr).width();
double newWidth = gryW * scale;
int gryH = Highgui.imread(imageGrayStr).height();
// Change the name for easy use in resizeCanny() function.
imageCanny = imageGray;
// Start resizeCanny function. It resizes the image to Canny and match for later.
// This is for multiple scaling
resizeCanny(imageCanny, resizedCanny, resultCanny, (int) newWidth, gryH, Imgproc.INTER_AREA);
// Get H and W of resized image.
int rszH = Highgui.imread(resizedCannyStr).height();
int rszW = Highgui.imread(resizedCannyStr).width();
// r = grayed image's width / resized image's width.
r = gryW / (float) rszW;
// If resized image is smaller than template, then break.
if (rszH < tH || rszW < tW)
{
break;
}
// Some matrix conversions.
Mat resizedCannyMat = Highgui.imread(resizedCannyStr);
String edged = resizedCannyStr;
Mat edgedMat = Highgui.imread(edged);
// Canny and write the image that has been resized.
Imgproc.Canny(resizedCannyMat, edgedMat, 50, 200);
Highgui.imwrite(resultCannyStr, edgedMat);
// Some matrix conversions.
Mat resultCannyMat = Highgui.imread(resultCannyStr);
String matchResult = resultCannyStr;
Mat matchResultMat = Highgui.imread(matchResult);
Mat matchTemplateMat = Highgui.imread(templateStr); // 352
// Match Canny'd template and Canny'd image.
Imgproc.matchTemplate(resultCannyMat, matchTemplateMat, matchResultMat, Imgproc.TM_CCOEFF);
// Get maximum value and maximum location.
Core.MinMaxLocResult mmrValues = Core.minMaxLoc(matchResultMat);
mLoc = mmrValues.maxLoc;
double mVal = mmrValues.maxVal;
// If found array is empty or maximum value is bigger than previous max value, then update the variables.
if (found == null || mVal > found[0]) {
found[0] = mVal;
found[1] = mLoc.x;
found[2] = mLoc.y;
found[3] = (double) r;
} // end if
}// end for
// After for loop; update maximum locations (x,y) with found array to choose/show.
mLoc.x = found[1];
mLoc.y = found[2];
r = (float) found[3];
// Find template's edges.
int startX, startY;
startX = (int) ((mLoc.x) * r);
startY = (int) ((mLoc.y) * r);
int endX, endY;
endX = (int) ((mLoc.x + tW) * r);
endY = (int) ((mLoc.y + tH) * r);
if (startX == 0 && startY == 0){
_driver2.quit(); }
// Tap action
_driver2.tap(1, startX, startY, 100);
return;