无法在Android

时间:2018-04-03 21:09:47

标签: java android c++ opencv java-native-interface

我正在开发一个需要进行图像处理的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)

我的代码有什么问题,如何解决?

1 个答案:

答案 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;