Ask Your Question

Revision history [back]

Check if There's Matching or Not

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;