如何在Android中将OpenCV Mat从本机代码返回到java
我在Android工作室项目中使用OpenCV,我想返回一个用本地C++方法创建的Mat对象,它是java环境的。我已经试过了,但对我不起作用。我得到以下错误:如何在Android中将OpenCV Mat从本机代码返回到java,java,android,c++,opencv,native,Java,Android,C++,Opencv,Native,我在Android工作室项目中使用OpenCV,我想返回一个用本地C++方法创建的Mat对象,它是java环境的。我已经试过了,但对我不起作用。我得到以下错误: 07-27 12:10:48.433 11004-11004/com.visualdefence.mobileclient E/GLib: gst_app_sink_pull_sample: assertion 'GST_IS_APP_SINK (appsink)' failed 07-27 12:10:48.433 11004-110
07-27 12:10:48.433 11004-11004/com.visualdefence.mobileclient E/GLib: gst_app_sink_pull_sample: assertion 'GST_IS_APP_SINK (appsink)' failed
07-27 12:10:48.433 11004-11004/com.visualdefence.mobileclient E/cv::error(): OpenCV Error: Assertion failed (total() == 0 || data != NULL) in cv::Mat::Mat(cv::Size, int, void*, size_t), file src/main/jni/../opencvLib/include/opencv2/core/mat.inl.hpp, line 443
--------- beginning of crash
07-27 12:10:48.434 11004-11004/com.visualdefence.mobileclient A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 11004 (ce.mobileclient)
本机类(相关方法为本机\u获取\u屏幕截图):
所以我在这里做的是将一个在java中创建的Mat指针作为参数,以使我可以从C++本地代码中分配它的内存。 根据Mat构造函数给出的行号,该错误似乎发生在Mat构造函数中
如果我将指向java Mat的指针传递给本机代码以将其作为Mat进行操作,那么是什么导致了此错误?找到解决方案了吗?
...
#include <opencv2/core/mat.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
GST_DEBUG_CATEGORY_STATIC (debug_category);
#define GST_CAT_DEFAULT debug_category
#define GET_CUSTOM_DATA(env, thiz, fieldID) (Player *)(gintptr)env->GetLongField (thiz, fieldID)
#define SET_CUSTOM_DATA(env, thiz, fieldID, data) env->SetLongField (thiz, fieldID, (jlong)(gintptr)data)
typedef struct _Player
{
jobject java_player;
GstPlayer *player;
GstPlayerVideoRenderer *renderer;
ANativeWindow *native_window;
} Player;
...
...
...
static void
native_get_screenshot (JNIEnv * env, jobject thiz, jlong matAddr)
{
GstMapInfo mapInfo = {0, };
Mat *matRgb = (Mat*)matAddr;
Player *player = GET_CUSTOM_DATA (env, thiz, native_player_field_id);
if (!player) {
matRgb = NULL;
return;
}
GstElement *pipeline, *app_sink;
pipeline = gst_player_get_pipeline(player->player);
app_sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");
GstSample *gst_sample = gst_app_sink_pull_sample ((GstAppSink*)app_sink);
GstBuffer *gst_buffer = gst_sample_get_buffer (gst_sample);
gst_buffer_map (gst_buffer, &mapInfo, GST_MAP_READ);
*matRgb = Mat(Size(640, 360), CV_8UC3, (char*)mapInfo.data);
cvtColor(*matRgb, *matRgb, CV_RGB2BGR);
}
...
...
...
/* List of implemented native methods */
static JNINativeMethod native_methods[] = {
{"nativeGetScreenshot", "(J)V", (void *) native_get_screenshot}
...
};
...
...
...
...
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
public class Player implements Closeable {
private static native void nativeClassInit();
public static void init(Context context) throws Exception {
System.loadLibrary("opencv_java3");
System.loadLibrary("gstreamer_android");
GStreamer.init(context);
if (!OpenCVLoader.initDebug()) {
Log.e("Player", "Initializing OpenCV failed");
}
System.loadLibrary("gstplayer");
nativeClassInit();
}
private native void nativeGetScreenshot(long matAddr);
public Mat getScreenshot() {
Mat descriptor = new Mat();
nativeGetScreenshot(descriptor.getNativeObjAddr());
return descriptor;
}
}