0

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

当我执行应用程序时,我得到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 文档中的说明将图像转换为单通道 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);


}

}
4

2 回答 2

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 我转储了我在资产文件夹中使用的图像文件)

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

于 2013-07-12T17:37:12.053 回答
0

请参阅我在此站点上的答案:无法在 Android 设备上执行 OpenCV 模板匹配,如果您遵循该答案,我确定它会起作用

于 2013-12-17T07:29:08.017 回答