我正在开发一个需要进行图像处理的Android应用程序。我正在通过JNI从java调用c ++代码。我正在使用OpenCV进行图像处理。首先,我承认我刚开始使用OpenCv并学习图像处理。我现在要做的是尝试将开放的CV mat数据从本机C ++返回到Java。
我也不是C ++开发人员。我正在关注此链接 - http://answers.opencv.org/question/12090/returning-a-mat-from-native-jni-to-java/。
这是我的原生C ++代码
#include <jni.h>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
using namespace std;
using namespace cv;
extern "C"
JNIEXPORT jstring
JNICALL
Java_media_memento_memento_SphereCameraActivity_stitchPhotos(
JNIEnv *env,
jobject /* this */, jlong addrMat, jlong addrNewMat) {
Mat& mat = *(Mat*)addrMat;
Mat& newMat = *(Mat*)addrNewMat;
newMat.create(mat.rows, mat.rows, mat.type());
memcpy(newMat.data, mat.data , mat.step * mat.rows);
std::string hello = "Stitching the photo in C++";
return env->NewStringUTF(hello.c_str());
}
如你所见,这一行
memcpy(newMat.data,mat.data,mat.step * mat.rows);
会将新值传递给java中的mat。这是我的Java代码。
Mat mat;
bitmap.getHeight();
bitmap.getWidth();
mat = new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_8UC3);
mat.put(0, 0, jpeg);
Mat newMat = new Mat();
stitchPhotos(mat.getNativeObjAddr(), newMat.getNativeObjAddr());
根据我的代码,当我从Java调用本机函数时,java中的newMat变量应该获得另一个mat变量值。对?但是当我运行该代码时,我的应用程序崩溃了。 它给了我这个错误
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: media.memento.memento, PID: 4823
java.lang.UnsupportedOperationException: Provided data element number (39397) should be multiple of the Mat channels count (3)
at org.opencv.core.Mat.put(Mat.java:1011)
at media.memento.memento.SphereCameraActivity$MyCameraListener$1.onBitmapReady(SphereCameraActivity.java:276)
at com.otaliastudios.cameraview.CameraUtils$1$1.run(CameraUtils.java:95)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我的代码有什么问题,如何解决?
答案 0 :(得分:2)
在stitchPhotos()
调用之前,Java调用堆栈指向此行:
mat.put(0, 0, jpeg);
根据错误消息,jpeg
的尺寸错误。似乎put()
期望接收一个3的倍数的数组(因为mat
被声明为类型CV_8UC3
,它是8位,无符号,每个像素有3个通道)。
P.S。在C ++中将一个Mat
复制到另一个的更简单方法是copyTo
或赋值运算符。例子:
Mat& mat = *(Mat*)addrMat;
Mat& newMat = *(Mat*)addrNewMat;
mat.copyTo(newMat);
newMat = mat;