我正在尝试使用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);
}
}
答案 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文件夹中使用的图像文件)
答案 1 :(得分:0)
请参阅我在这个网站上的回答:Unable to execute OpenCV template matching on Android device,如果你按照这个答案,我相信它会起作用