Android 中与 OpenCV 进行模板匹配时断言失败错误
Assertion failed Error during template matching with OpenCV in Android
我在 Netbeans
中编写了一个 OpenCV
匹配 class 的模板,并且在 JVM
中运行良好。
只是我想把它变成 android 应用程序。不过我对编程没兴趣Android。所以我阅读了教程并决定 IntentService
看起来对我的目标很有帮助。因为我不想要任何 UI 只是处理图像和拍摄结果图像。
我终于将 OpenCV
导入到我的简单 Android 项目中。 Template Matching
在 JVM
中运行良好,但在 Android 中出现错误。只是我更改了 Android 的图像文件路径形式。并在 JVM
.
中使用相同的图像文件
--编辑--
我将图像文件复制到 Android 虚拟设备下载文件夹。我用虚拟设备测试它。
让我分享我的代码和结果;
MyService.java(Android工作室)
import android.content.Intent;
import android.app.IntentService;
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.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class MyService extends IntentService {
public MyService() {
super("MyService");
}
@Override
protected void onHandleIntent(Intent workIntent) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = Imgcodecs.imread("/sdcard/Download/bigpicture.png");
Mat templ = Imgcodecs.imread("/sdcard/Download/template.png");
String outFile = "/sdcard/Download/result.png";
// 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 Normalize and Perform the template matching operation
Imgproc.matchTemplate(img, templ, result, 3);
// Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Imgproc.threshold(result, result,0.98,1,Imgproc.THRESH_TOZERO);
// Localizing the best match with minMaxLoc. We localize the minimum and maximum values in the result matrix R by using minMaxLoc.
Point matchLoc;
Point maxLoc;
Point minLoc;
MinMaxLocResult mmr;
while(true)
{
mmr = Core.minMaxLoc(result);
matchLoc = mmr.maxLoc;
if(mmr.maxVal >= 0.997)
{
Imgproc.rectangle(img, matchLoc,
new Point(matchLoc.x + templ.cols(),matchLoc.y + templ.rows()),
new Scalar(0,255,0));
Imgproc.rectangle(result, matchLoc,
new Point(matchLoc.x + templ.cols(),matchLoc.y + templ.rows()),
new Scalar(0,255,0),-1);
System.out.println(matchLoc.x + "---" + matchLoc.y);
//break;
}
else
{
break; //No more results within tolerance, break search
}
}
Imgcodecs.imwrite(outFile, img);
}
}
MainActivity.java(Android工作室)
import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
}
结果
E/cv::error(): 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 /builds/master_pack-android/opencv/modules/imgproc/src/templmatch.cpp, line 658
E/org.opencv.imgproc: imgproc::matchTemplate_11() caught cv::Exception: /builds/master_pack-android/opencv/modules/imgproc/src/templmatch.cpp:658: 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)
E/AndroidRuntime: FATAL EXCEPTION: IntentService[MyService]
Process: com.lacrymae.bapplication, PID: 6565
CvException [org.opencv.core.CvException: cv::Exception: /builds/master_pack-android/opencv/modules/imgproc/src/templmatch.cpp:658: 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)
]
at org.opencv.imgproc.Imgproc.matchTemplate_1(Native Method)
at org.opencv.imgproc.Imgproc.matchTemplate(Imgproc.java:2105)
at com.lacrymae.bapplication.MyService.onHandleIntent(MyService.java:36)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
确保 matchTemplate() 的所有参数的大小和类型都正确。
来自 OpenCV 文档:
image – Image where the search is running. It must be 8-bit or 32-bit floating-point.
templ – Searched template. It must be not greater than the source image and have the same data type.
因此请确保您的 roi 是类型(8 位或 32 位浮点数)。
还要检查你的图像是否正确打开,因为如果模板太小,它会给出错误。
--已解决--
第 1 期
AndroidManifest.xml需要这样的权限;
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
第 2 期
文件路径错误已更改;
Mat img = Imgcodecs.imread("/sdcard/Download/bigpicture.png");
Mat templ = Imgcodecs.imread("/sdcard/Download/template.png");
String outFile = "/sdcard/Download/result.png";
至
String path = Environment.getExternalStorageDirectory().getPath();
Mat img = Imgcodecs.imread(path + "/Download/bigpicture.png");
Mat templ = Imgcodecs.imread(path + "/Download/template.png");
String outFile = path + "/Download/result.png";
感谢您的关注和努力。
我在 Netbeans
中编写了一个 OpenCV
匹配 class 的模板,并且在 JVM
中运行良好。
只是我想把它变成 android 应用程序。不过我对编程没兴趣Android。所以我阅读了教程并决定 IntentService
看起来对我的目标很有帮助。因为我不想要任何 UI 只是处理图像和拍摄结果图像。
我终于将 OpenCV
导入到我的简单 Android 项目中。 Template Matching
在 JVM
中运行良好,但在 Android 中出现错误。只是我更改了 Android 的图像文件路径形式。并在 JVM
.
--编辑--
我将图像文件复制到 Android 虚拟设备下载文件夹。我用虚拟设备测试它。
让我分享我的代码和结果;
MyService.java(Android工作室)
import android.content.Intent;
import android.app.IntentService;
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.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class MyService extends IntentService {
public MyService() {
super("MyService");
}
@Override
protected void onHandleIntent(Intent workIntent) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = Imgcodecs.imread("/sdcard/Download/bigpicture.png");
Mat templ = Imgcodecs.imread("/sdcard/Download/template.png");
String outFile = "/sdcard/Download/result.png";
// 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 Normalize and Perform the template matching operation
Imgproc.matchTemplate(img, templ, result, 3);
// Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Imgproc.threshold(result, result,0.98,1,Imgproc.THRESH_TOZERO);
// Localizing the best match with minMaxLoc. We localize the minimum and maximum values in the result matrix R by using minMaxLoc.
Point matchLoc;
Point maxLoc;
Point minLoc;
MinMaxLocResult mmr;
while(true)
{
mmr = Core.minMaxLoc(result);
matchLoc = mmr.maxLoc;
if(mmr.maxVal >= 0.997)
{
Imgproc.rectangle(img, matchLoc,
new Point(matchLoc.x + templ.cols(),matchLoc.y + templ.rows()),
new Scalar(0,255,0));
Imgproc.rectangle(result, matchLoc,
new Point(matchLoc.x + templ.cols(),matchLoc.y + templ.rows()),
new Scalar(0,255,0),-1);
System.out.println(matchLoc.x + "---" + matchLoc.y);
//break;
}
else
{
break; //No more results within tolerance, break search
}
}
Imgcodecs.imwrite(outFile, img);
}
}
MainActivity.java(Android工作室)
import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
}
结果
E/cv::error(): 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 /builds/master_pack-android/opencv/modules/imgproc/src/templmatch.cpp, line 658
E/org.opencv.imgproc: imgproc::matchTemplate_11() caught cv::Exception: /builds/master_pack-android/opencv/modules/imgproc/src/templmatch.cpp:658: 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)
E/AndroidRuntime: FATAL EXCEPTION: IntentService[MyService]
Process: com.lacrymae.bapplication, PID: 6565
CvException [org.opencv.core.CvException: cv::Exception: /builds/master_pack-android/opencv/modules/imgproc/src/templmatch.cpp:658: 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)
]
at org.opencv.imgproc.Imgproc.matchTemplate_1(Native Method)
at org.opencv.imgproc.Imgproc.matchTemplate(Imgproc.java:2105)
at com.lacrymae.bapplication.MyService.onHandleIntent(MyService.java:36)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
确保 matchTemplate() 的所有参数的大小和类型都正确。 来自 OpenCV 文档:
image – Image where the search is running. It must be 8-bit or 32-bit floating-point.
templ – Searched template. It must be not greater than the source image and have the same data type.
因此请确保您的 roi 是类型(8 位或 32 位浮点数)。 还要检查你的图像是否正确打开,因为如果模板太小,它会给出错误。
--已解决--
第 1 期
AndroidManifest.xml需要这样的权限;
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
第 2 期
文件路径错误已更改;
Mat img = Imgcodecs.imread("/sdcard/Download/bigpicture.png");
Mat templ = Imgcodecs.imread("/sdcard/Download/template.png");
String outFile = "/sdcard/Download/result.png";
至
String path = Environment.getExternalStorageDirectory().getPath();
Mat img = Imgcodecs.imread(path + "/Download/bigpicture.png");
Mat templ = Imgcodecs.imread(path + "/Download/template.png");
String outFile = path + "/Download/result.png";
感谢您的关注和努力。