OpenCV Android templateMatch FATAL EXCEPTION

时间:2013-07-10 19:59:47

标签: java android opencv adt template-matching

我正在尝试使用Java中的OpenCV库进行模板匹配。我正在尝试使用我发现here的代码来完成这项工作。

当我执行应用时,我得到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)

我认为它必须与文件的大小有关,但执行的应该是(main image, small image, image to write to)

我使用.bmp文件作为输入:

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

作为更新,我已尝试按照OpenCV docs here的说明将我的图像转换为单通道8位.png,但仍然没有喜悦......

我的 Start.java 代码:

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);


}

}

2 个答案:

答案 0 :(得分:0)

导致应用程序失败的原因有很多,主要是因为您与图像资源的交互方式,即您没有正确指向文件并且正在尝试写入只读区域。

最好在设备上创建一个文件夹(在外部媒体上),然后从那里读取/写入文件。

// 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();
                }
            }    
        });
    } 

另外,不要忘记在清单文件中启用写入权限     <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE"/>

你可以从这里下载我的示例应用程序来测试并遍历代码(nb我转储了我在assets文件夹中使用的图像文件)

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

答案 1 :(得分:0)

请参阅我在这个网站上的回答:Unable to execute OpenCV template matching on Android device,如果你按照这个答案,我相信它会起作用