0

I'm trying to do template matching using OpenCV libs in Java. I'm trying to utilize a code that I found here to do the job.

When I execute the app I get FATAL EXCEPTION

07-10 20:24:28.456: E/cv::error()(8608): OpenCV Error: Assertion failed (corrsize.height <= img.rows + templ.rows - 1 && corrsize.width <= img.cols + templ.cols - 1) in void cv::crossCorr(const cv::Mat&, const cv::Mat&, cv::Mat&, cv::Size, int, cv::Point, double, int), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/templmatch.cpp, line 70

&

07-10 20:55:15.706: E/AndroidRuntime(9622): FATAL EXCEPTION: main
07-10 20:55:15.706: E/AndroidRuntime(9622): CvException [org.opencv.core.CvException: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/templmatch.cpp:70: error: (-215) corrsize.height <= img.rows + templ.rows - 1 && corrsize.width <= img.cols + templ.cols - 1 in function void cv::crossCorr(const cv::Mat&, const cv::Mat&, cv::Mat&, cv::Size, int, cv::Point, double, int)

I presume that it must be something to do with the size of the files, but there are executed as should be (main image, small image, image to write to).

I use .bmp files as input:

bmp1.bmp - size 1280x960 - main image
bmp2.bmp - size 168x63   - template image
bmp3.bmp - size 1280x960 - (blank .bmp file to write the result) size 1280x960

As an update, I have tried converting my images to single channel 8 bit .png as instructed in OpenCV docs here but still no joy...

My Start.java code:

package com.example.matchtemplate;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class Start extends Activity {

    Button button;
    ImageView imageview;

    protected static final String TAG = null;
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i(TAG, "OpenCV loaded successfully");

                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    @Override
    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
        addListenerOnButton();
    }

    public void addListenerOnButton() {

        imageview = (ImageView) findViewById(R.id.imageView1);

        button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {


                matchTemplate("bmp1.bmp", "bmp2.bmp", "bmp3.bmp", Imgproc.TM_CCOEFF);
                imageview.setImageResource(R.drawable.bmp3);
            }

        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.start, menu);
        return true;
    }

    public void matchTemplate(String inFile, String templateFile, String outFile, int match_method) {
        System.out.println("\nRunning Template Matching");

        Mat img = Highgui.imread(inFile);
        Mat templ = Highgui.imread(templateFile);

        // / Create the result matrix
        int result_cols = img.cols() - templ.cols() + 1;
        int result_rows = img.rows() - templ.rows() + 1;
        Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);

        // / Do the Matching and Normalize
        Imgproc.matchTemplate(img, templ, result, match_method);
        Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

        // / Localizing the best match with minMaxLoc
        MinMaxLocResult mmr = Core.minMaxLoc(result);

        Point matchLoc;
        if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
            matchLoc = mmr.minLoc;
        } else {
            matchLoc = mmr.maxLoc;
        }

        // / Show me what you got
        Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
                matchLoc.y + templ.rows()), new Scalar(0, 255, 0));

        // Save the visualized detection.
        System.out.println("Writing "+ outFile);
        Highgui.imwrite(outFile, img);


}

}
Community
  • 1
  • 1
jaspernorth
  • 415
  • 1
  • 10
  • 28
  • Does the problem go away if you declare `Mat result = new Mat()` instead? Also, as a performance improvement, you don't need to normalize `result`. `MinMaxLoc` should find the same location without normalization. – Aurelius Jul 10 '13 at 21:10
  • No, problem persists, program still reports the same two errors. And thank you for the hint! – jaspernorth Jul 10 '13 at 21:20

2 Answers2

0

There are a number of reasons that's causing the app to fail most predominantly how you were interacting with the image resources, ie you were not pointing to the file correctly and were trying to write to a readonly area.

Its best to create a folder on the device (on the external media) and read/write the files from/to there.

// the following creates/inits the folder to be working in
// For your case, create the folder manually and drop the image files into it
// This code just validates the folder exists
public void initDir() {
    if (android.os.Environment.getExternalStorageState().equals(
            android.os.Environment.MEDIA_MOUNTED)) {
        cacheDir = new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
        if (!cacheDir.exists()) {
            cacheDir.mkdirs();
        }
    }
}

public String getFileAbsPath(String fileName) {
    File f = new File(cacheDir, fileName);
    return f.getAbsolutePath();
}


// there is also a few modifications to this code
// added another image resource, which will be used to set the new image
public void addListenerOnButton() {

        imageView = (ImageView) findViewById(R.id.imageView1);
        img2 = (ImageView) findViewById(R.id.imageView2);

        button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                String infile = getFileAbsPath("img1.png"); 
                String tp = getFileAbsPath("tp.png");
                String outFile = getFileAbsPath("img2.png");

                try {
                    matchTemplate(infile, tp, outFile, Imgproc.TM_CCOEFF);
                    Bitmap bm = BitmapFactory.decodeFile(outFile);
                    img2.setImageBitmap(bm);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }    
        });
    } 

Also don't forget to enable write permission in manifest file <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE"/>

You can download my sample application from here to test with and walk through the code (nb i dumped the image files i used in the assets folder)

https://bitbucket.org/kwamena/opencv-try

dotKwame
  • 181
  • 3
  • 13
  • Thanks! I have tried to execute your app, but it throws a error as your app is targeted for API 17 and mine is 11. I have tried to change it in Project->Properties but did not work. Also, do you mean that I sould create a dir on the actual phone to read/write images? – jaspernorth Jul 12 '13 at 19:38
0

Refer to my answer at this site:Unable to execute OpenCV template matching on Android device, If you folllw that answer, i m sure it will work

Community
  • 1
  • 1
Mehul Thakkar
  • 12,440
  • 10
  • 52
  • 81