Проблема с написанием FaceRecognizer для Java с OpenCV 2.4.8

Мне дали проект, основанный на распознавании лиц, написанный на JavaCV, который нужно улучшить. Идея состояла в том, чтобы либо переписать программу с использованием C ++, либо написать привязки JNI, чтобы все еще использовать Java. Я провел некоторые исследования и, согласно официальному сайту OpenCV, начиная с версии 2.4.4, есть привязки для Java и Python. И так, так как официальный сайт заявил, что я решил пойти с ним. Обратите внимание, что я не программировал на C ++ раньше и не писал никаких JNI-оболочек в прошлом. Если на официальном сайте не указано, что он содержит привязки для Java, я просто написал бы это на C ++, используя Qt Digia.

Так или иначе, я сделал все остальное, что хотел сделать с проектом Java, и у меня осталась часть распознавания лиц. К сожалению согласно (Актуальный вопрос № 1, Актуальный вопрос № 2) Я обнаружил, что в FaceRecognizer есть ошибка и что JNI-оболочка для распознавания лиц должна быть написана от руки.

Я нашел довольно хороший JNI C ++ Java-учебник и я попытался использовать это с кодом, упомянутым в соответствующем вопросе № 1, связанном выше. На скриншоте ниже показано, что я получил прямо сейчас.
C ++ JNI Скриншот проекта
Код выглядит следующим образом:
LBPHFaceRecognizer.java

import org.opencv.contrib.FaceRecognizer;
public class LBPHFaceRecognizer extends FaceRecognizer
{

static{
System.loadLibrary("opencv_java248");
System.loadLibrary("facerec");
}

private static native long n_createLBPHFaceRecognizer();

public LBPHFaceRecognizer()
{
super(n_createLBPHFaceRecognizer());
}
FaceRecognizer facerec = new LBPHFaceRecognizer();
}

LBPHFaceRecognizer.c

// facerec.dll
#include "jni.h"#include "opencv2/contrib/contrib.hpp"

extern "C" {JNIEXPORT jlong JNICALL Java_org_matxx_n_createLBPHFaceRecognizer(JNIEnv* env, jclass, jint);

JNIEXPORT jlong JNICALL Java_org_matxx_n_createLBPHFaceRecognizer(JNIEnv* env, jclass, jint)
{
try {

cv::Ptr<cv::FaceRecognizer> ptr = cv::createLBPHFaceRecognizer();
cv::FaceRecognizer * pf = ptr.get();
ptr.addref(); //don't let it self-destroy here..
return (jlong) pf;
} catch (...) {
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, "sorry, dave..");
}
return 0;
}
} // extern "C"

Makefile

# Define a variable for classpath
CLASS_PATH = ../bin

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all : facerec.dll

# $@ matches the target, $< matches the first dependancy
facerec.dll : LBPHFaceRecognizer.o
gcc -m64 -Wl,--add-stdcall-alias -shared -o $@ $<

# $@ matches the target, $< matches the first dependancy
LBPHFaceRecognizer.o : LBPHFaceRecognizer.c LBPHFaceRecognizer.h
gcc -m64 -I"C:\Program Files\Java\jdk1.7.0_51\include" -I"C:\Program Files\Java\jdk1.7.0_51\include\win32"  -I"C:\Users\User\Desktop\OPENCVINSTALLATION\opencv" -I"C:\Users\User\Desktop\OPENCVINSTALLATION\opencv\build\java\x64" -c $< -o $@

# $* matches the target filename without the extension
LBPHFaceRecognizer.h : LBPHFaceRecognizer.class
javah -classpath $(CLASS_PATH) $*

clean :
rm LBPHFaceRecognizer.h LBPHFaceRecognizer.o facerec.dll

В целом мне удалось создать facerec.dll, но есть ряд проблем. Сначала, когда я создавал facerec.dll, у LBPHFacerecognizer.java не было импорта вверху, потому что он жаловался на это. Я добавил это позже, чтобы не видеть ошибку.
Во-вторых, код .c жалуется на все, как показано на скриншоте ниже..c код ошибки

и что интересно, он не жалуется на импорт jni.h, тогда как заголовочный файл, как видно на скриншоте ниже, делает.
ошибка о jni.h

Вот и все, может кто-нибудь взглянуть на это и сказать мне, правильно ли я это сделал? Есть что-то, что я должен изменить? Эти ошибки в порядке, учитывая тот факт, что DLL была создана? Или, может быть, кто-то делал это в прошлом и хочет поделиться файлом DLL. Я еще не удосужился протестировать его с помощью Java-кода JavaCV.

Я использую OpenCV 2.4.8, Win 7 64 бит, Mingw 64 бит, Java 64 бит 7_0_51 релиз, Eclipse 64 бит.

Заранее спасибо.

0

Решение

  1. #include "jni.h" не то же самое, что #include <jni.h> Вот почему он жалуется на одно, а не на другое. Цитаты означают относительный путь. Другими словами, файл находится в той же папке, что и ваш проект. Или подпапка. В противном случае вы используете <...> и включает в себя файлы в каталоге поиска компилятора.

  2. Подпись принимает параметры: JNIEnv*, jclass, jint когда это должно быть: принимая JNIEnv*, jclass, Зачем? Потому что согласно подписи у вас на стороне Java private static native long n_createLBPHFaceRecognizer();.. это не принимает никаких параметров .. Однако, вы объявили на нативной стороне, что принимают int.

  3. По этой подписи: Java_org_matxx_n_createLBPHFaceRecognizer, n_createLBPHFaceRecognizer находится в пакете под названием Java_org_matxxx но ваш java-код, похоже, не находится ни в каком пакете, кроме пакета «по умолчанию».

  4. Если у функции jni есть подчеркивание в ее имени на стороне Java, вы должны заменить подчеркивание на _1 на родной стороне .. Пример:

Сторона Java (в пакете com.foo.bar): n_createLBPHFaceRecognizer

Родная сторона: Java_com_foo_bar_n_1createLBPHFaceRecognizer

В качестве простого обходного решения целесообразно не использовать подчеркивания в названии.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]