47413

Issue with writing FaceRecognizer for Java with OpenCV 2.4.8

Question:

I have been given a project based around face recognition written in JavaCV to be improved. The idea was to either rewrite the program using C++ or write JNI bindings to still use Java. I did some research and according to the official website OpenCV as of version 2.4.4 has bindings for Java and Python. And so, since the official website stated so I decided to go with it. Please note I haven't programmed in C++ before nor have I written any JNI wrappers in the past. If the official website didn't state that it includes bindings for Java I would just write it with C++ using Qt Digia.

This way or another I did everything else that I wanted to do with the Java project and was left with the face recognition part. Unfortunately according (<a href="https://stackoverflow.com/questions/21880941/opencv-java-createfisherface-ptr/21881622#21881622" rel="nofollow">Relevant question #1</a>, <a href="https://stackoverflow.com/questions/21761641/how-do-you-pass-the-labels-parameter-as-a-mat-to-facerecognizer-from-opencv-in" rel="nofollow">Relevant question #2</a>) I found out that there is a bug with FaceRecognizer and that JNI wrapper for face recognition has to be written by hand.

I found a pretty good <a href="http://www.bogotobogo.com/cplusplus/eclipse_CDT_JNI_MinGW_64bit.php" rel="nofollow">jni c++ java tutorial</a> and I tried to use that with the code mentioned in Relevant question #1 linked above. The screenshot below shows what I have got right now. <img alt="c++ jni project screenshot" class="b-lazy" data-src="https://i.stack.imgur.com/de4JX.png" data-original="https://i.stack.imgur.com/de4JX.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /><br /> The code is as follows: 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

All in all I managed to create facerec.dll, but there are a number of problems. First when I was creating the facerec.dll the LBPHFacerecognizer.java did not have the import at the top, because it was complaining about it. I added it afterwards just not to see the error. Secondly the .c code complains about everything as seen on the screenshot below.<img alt=".c code errors" class="b-lazy" data-src="https://i.stack.imgur.com/Of8JU.png" data-original="https://i.stack.imgur.com/Of8JU.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

and interestingly enough it doesn't complain about the jni.h import whereas the header file as seen on screenshot below does.<br /><img alt="error about jni.h" class="b-lazy" data-src="https://i.stack.imgur.com/yYqjh.png" data-original="https://i.stack.imgur.com/yYqjh.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

That's it, can someone have a look at it and tell me if I've done it correctly? Is there something I should change? Are those errors ok considering the fact the the dll has been created? Or maybe someone has done it in the past and is willing to share the dll file. I haven't gotten around to testing it with the java equivalent of JavaCV code yet.

I use OpenCV 2.4.8, Win 7 64bit, Mingw 64 bit, Java 64 bit 7_0_51 release, Eclipse 64 bit.

Thanks in advance.

Answer1:

<ol><li>

#include "jni.h" isn't the same as #include <jni.h> That's why it complains about one and not the other.. Quotations means relative path.. In other words, the file is located in the same folder as your project. Or a sub-folder. Otherwise you use <...> and it includes files in the compiler's search directory.

</li> <li>

The signature is taking parameters: JNIEnv*, jclass, jint when it should be: taking JNIEnv*, jclass. Why? Because according to the signature you have on the Java side private static native long n_createLBPHFaceRecognizer();.. it takes no parameters.. However, you have it declared on the native side as taking an int.

</li> <li>

According to this signature name: Java_org_matxx_n_createLBPHFaceRecognizer, n_createLBPHFaceRecognizer is in a package called Java_org_matxxx but your java code doesn't seem to be in any package other than "default" package.

</li> <li>

If a jni function has an underscore in its name on the Java side, you must replace the underscore with an _1 on the native side.. Example:

</li> </ol>

Java side (in package com.foo.bar): n_createLBPHFaceRecognizer

Native side: Java_com_foo_bar_n_1createLBPHFaceRecognizer

As a simple work around, it is wise to just not have underscores in the name..

Recommend

  • JNI method: formal argument lists differ in length
  • No implementation found for native Lcom/jp/algi/
  • Sending java string as c/c++ bytes
  • JNI: converting unsigned int to jint
  • Issue with writing FaceRecognizer for Java with OpenCV 2.4.8
  • JNI: Can not get array length
  • Java JNI: Passing multibyte characters from java to c
  • convert c++ map to jobject JNI?
  • I have 2 very similar C functions being called from python and Java. How can I combine the 2 librari
  • OpenCV opencv2/core/core.hpp: No such file or directory
  • Problems compiling DLL using GCC on Windows
  • Radio Button Enum Helper for model with resource file
  • Error generating ScaffoldingConnectionFactory
  • Missing OpenFilesEvent for JavaFX on Mac
  • C# Getting window's title by handle in Hebrew return question marks
  • Help designing a order manager class
  • Programmatically set PIN/Password used to unlock device
  • How to solve “fatal: relocations remain against allocatable but non-writable sections” while using J
  • C++ reference variable across files
  • UML diagram generator in Visual Studio 2010
  • Embedded Glassfish JPA Datasource connection fail
  • Available space left on drive - WinAPI - Windows CE
  • Translating C# to PowerShell in InterIMAP
  • C++ pointer value changes with static_cast
  • Creating Java object from class name with constructor, which contains parameters [duplicate]
  • how to avoid repetitive constructor in children
  • Content-Length header not returned from Pylons response
  • Custom Tabgroup Appcelerator
  • Very simple C++ DLL that can be called from .net
  • Play WS (2.2.1): post/put large request
  • why do I get the error when installing the gem 'pg'? [duplicate]
  • How to access EntityManager inside Entity class in EJB3
  • ilmerge with a PFX file
  • Deleting and Updating values from a cusrsor adapter
  • Possible to stop flickering java tooltip in heavyweight mode?
  • vba code to select only visible cells in specific column except heading
  • Javascript + PHP Encryption with pidCrypt
  • Getting Messege Twice Using IMvxMessenger
  • How can i traverse a binary tree from right to left in java?
  • How can I use threading to 'tick' a timer to be accessed by other threads?