将Mat传递给JNI函数-OpenCV

Pass Mat to JNI function - OpenCV

本文关键字:JNI 函数 -OpenCV Mat      更新时间:2023-10-16

我试图使用jlong通过JNI函数传递Mat对象,但在运行时遇到了以下异常:

(__gnu_cxx::__verbose_terminate_handler()+276)
(__cxxabiv1::__terminate(void (*)())+8)
(std::terminate()+20)
(__cxa_throw+148)
(cv::error(cv::Exception const&)+80)
(cv::Mat::copySize(cv::Mat const&)+18)
(cv::Mat::Mat(cv::Mat const&)+122)
(cv::_InputArray::getMat(int) const+252)
(cv::split(cv::_InputArray const&, cv::_OutputArray const&)+20)
(cv::split(cv::Mat const&, std::vector<cv::Mat, std::allocator<cv::Mat> >&)+28)
(cv::xphoto::balanceWhite(cv::Mat const&, cv::Mat&, int, float, float, float, float)+54)
(Java_com_myapp_camera_CameraManager_simpleWhiteBalance+18)

本机函数定义如下

public native static void simpleWhiteBalance(Mat source, Mat dest);

它以以下方式实现

#include <jni.h>
#include <opencv2/core/core.hpp>
#include "opencv2/xphoto.hpp"
#include "simple_color_balance.cpp"
#include "com_myapp_camera_CameraManager.h"
JNIEXPORT void JNICALL Java_com_myapp_camera_CameraManager_simpleWhiteBalance
  (JNIEnv *, jclass, jlong in, jlong out) {
     cv::Mat& inMat = *(cv::Mat*)in;
     cv::Mat& outMat = *(cv::Mat*)out;
    cv::xphoto::balanceWhite(inMat, outMat, cv::xphoto::WHITE_BALANCE_SIMPLE);
}

我是C++的新手,这个异常是什么意思?

jlong不是映射对象,而是映射long(对象映射为jobject),并且Mat的Java实例与cv::Mat的实例完全不同,不能以这种方式进行强制转换。这里的常用方法是在Java中使用longs作为C++中指针的近似值,并按照您使用的方式进行强制转换。

此外,这不是一个异常,而是由未捕获的异常引起的崩溃。要获得异常,您需要在C++代码中使用try-catch。C++异常与Java异常不兼容,因此您不能在Java中抛出C++并捕获它,反之亦然。

cv::Mat *inMat = (cv::Mat*)in;
cv::Mat *outMat = (cv::Mat*)out;

并且请传递指针而不是引用。参见示例