В настоящее время я пишу библиотеку ускорителей JNI для замены методов Java в некоторых системах (Linux x64 и macOS).
У меня есть рабочий код, написанный на Kotlin / Java с JavaCV 3.4.2
Я создал библиотеку JNI, которая выполняет ту же работу, чтобы избежать многократного перехода между JVM и JNI.
Пример:
Сторона Котлина (JVM + JavaCV) без ускорения:
override fun process(image: Mat): FeaturesDetectorResult {
val faceDetection = Dlib.faceDetection(image)
...
}
JNI ускоритель часть:
Котлин
@ByVal
protected external fun Process(imagePtr: Long, lines: List<opencv_core.Rect>): opencv_core.Mat?;
// method of class overriding the native method
override fun process(image: opencv_core.Mat): FeaturesDetectorResult {
val lines = ArrayList<opencv_core.Rect>()
val rotatedMat = Process(image.address(), lines)
return FeaturesDetectorResult(rotatedMat, lines)
}
C ++
JNIEXPORT jlong JNICALL Java_fr_tessi_bmd_image_accel_MserFeaturesDetectorNative_Process
(JNIEnv *env, jobject self, jlong imagePtr, jobject list) {
В конце моего метода C ++ я застрял в преобразовании нативного cv::Mat
его Java-аналог opencv_core.Mat
(конструктор с собственным адресом отсутствует).
Я посмотрел на источники, сгенерированные javacpp, и кажется, что нативные объекты рассматриваются как jlong
, Все мои тесты таким образом приводят к краху.
Кто-нибудь знает, как пройти org.bytedeco.javacpp
возиться туда-сюда с домашней библиотекой JNI?
РЕДАКТИРОВАТЬ:
Я нашел частичный обходной путь для создания opencv_mat.Mat
от cv::Mat
:
//Safety checks removed for simplicity
#define ptr_to_jlong(a) ((jlong)(uintptr_t)(a))
Mat* toReturnToJava;
jclass pointerClass = env->FindClass("org/bytedeco/javacpp/Pointer");
jfieldID addressFld = env->GetFieldID(pointerClass, "address", "J");
jobject pointerObj = env->AllocObject(pointerClass);
env->SetLongField(pointerObj, addressFld, ptr_to_jlong(toReturnToJava));
Mat
возвращается в Java как jlong
в то время как сторона Java объявляет возвращаемое значение как opencv.Mat
,
Код того же типа, похоже, не работает для Rect (вместо этого я использовал конструктор Rect (x, y, w, h)).
Задача ещё не решена.
Других решений пока нет …