Rainbow Soft Face Recognition-Introduction of ArcFace SDK and Points for Attention in Use

Posted by chugger93 on Wed, 15 May 2019 06:02:55 +0200

Many friends will encounter a variety of problems when developing face recognition system. Now we take Android platform for example, which uses HongSoft's free offline face recognition SDK development, to introduce how to develop a face recognition system with image detection, video picture face attribute detection, face registration recognition and other functions.

I. Acquisition of SDK

1. Application Address for ArcFace 2.0

https://ai.arcsoft.com.cn/product/arcface.html

2. Fill in the application for information and submit it it

After the application is approved, you can download the SDK and view APP_ID and SDK_KEY.

<br/>

II. Introduction of SDK Function

Rainbow Soft ArcFace 2.0 Android SDK includes face detection, age information detection, gender information detection, three-dimensional face angle detection, biopsy detection, face feature extraction and face feature comparison. SDK also supports static graph mode detection and video stream mode detection.


<br/>

3. Using SDK

1. Engineering Configuration

Put the jar file and so file in the corresponding directory, and add the jar to the project dependency

<br/>

2. Activating Engine

FaceEngine faceEngine = new FaceEngine();

//Activation method calls network and file operation for the first time, and only file operation for the next time. It is suggested that it should not be placed in the main thread.

int activeCode = faceEngine.active(SettingsActivity.this, Constants.APP_ID, Constants.SDK_KEY);

if (activeCode == ErrorInfo.MOK || activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) {

    //Successful or activated activation

}else{

    //Failure of activation

}

3. Initialization engine, recommended at startup

faceEngine = new FaceEngine();

int afCode = faceEngine.init(context.getApplicationContext(), FaceEngine.ASF_DETECT_MODE_VIDEO, FaceEngine.ASF_OP_0_HIGHER_EXT,

        16, 10, FaceEngine.ASF_FACE_RECOGNITION | FaceEngine.ASF_FACE_DETECT | FaceEngine.ASF_FACE3DANGLE|....);

if (afCode != ErrorInfo.MOK) {

    //Successful initialization

}else{

    //initialization failed

}

4. Face Detection

List faceInfoList = new ArrayList<>();

int code = faceEngine.detectFaces(nv21, width, height, FaceEngine.CP_PAF_NV21, faceInfoList);

if (code == ErrorInfo.MOK && faceInfoList.size() >0) {

    //Face Detection Successfully and Face Detection

}else{

    //Failure or failure of face detection

}

5. Feature extraction

FaceFeature faceFeature = new FaceFeature();

int code = faceEngine.extractFaceFeature(nv21, width, height, FaceEngine.CP_PAF_NV21, faceInfo, faceFeature);

if (code == ErrorInfo.MOK) {

    //Successful feature extraction

}else{

    //Failure of feature extraction, you can view the reason according to code

}

6. Characteristic comparison

public void compareFace(FaceFeature faceFeature1,FaceFeature faceFeature2){

    FaceSimilar faceSimilar = new FaceSimilar();

    int code = faceEngine.compareFaceFeature(faceFeature1, faceFeature2, faceSimilar);

    if (code == ErrorInfo.MOK){

        //If the comparison is successful, you can see the similarity in faceSimilar

    }else{

        //Comparing failures, you can see the reason according to code

    }

}

7. Detection of three-dimensional angle, age and gender in vivo and face

int faceProcessCode = faceEngine.process(nv21, width, height, FaceEngine.CP_PAF_NV21, faceInfoList, FaceEngine.ASF_AGE | FaceEngine.ASF_GENDER | FaceEngine.ASF_FACE3DANGLE | FaceEngine.ASF_LIVENESS);

if (faceProcessCode != ErrorInfo.MOK){

    //Failure

}else{

    //The process succeeds and results are available

    List ageInfoList = new ArrayList<>();

    List genderInfoList = new ArrayList<>();

    List face3DAngleList = new ArrayList<>();

    List faceLivenessInfoList = new ArrayList<>();

    int ageCode = faceEngine.getAge(ageInfoList);

    int genderCode = faceEngine.getGender(genderInfoList);

    int face3DAngleCode = faceEngine.getFace3DAngle(face3DAngleList);

    int livenessCode = faceEngine.getLiveness(faceLivenessInfoList);

    //Error code checking to determine whether all successful

    if ((ageCode | genderCode | face3DAngleCode | livenessCode) != ErrorInfo.MOK) {

        return;

    }else{

        //All the tests are successful and the results can be obtained from ageInfoList, genderInfoList, face3D AngleList and faceLivenessInfoList.

    }

}

8. Destroy the engine and recommend execution on exit

if (faceEngine != null) {

  int faceEngineCode = faceEngine.unInit();

  Log.i(TAG, "unInitEngine: " + faceEngineCode);

}

<br/>

IV. NOTES

1. Selection of Detection Mode

Initialization of the engine requires an incoming detection mode (video stream mode or picture mode), in addition to identifying functional modules.( extractFaceFeature and compareFaceFeature ) Other functions are distinguished by detection modes. For face detection, age detection, gender detection, face three-dimensional angle, biopsy detection, using video stream mode processing speed is faster. But the biopsy detection of video stream mode is special: although the result can be obtained immediately after processing, the value returned after the first frame of a video stream is unknown, and the real algorithm result is the value obtained after a period of time.

2. Multithread Use of Engine

Algorithmic functions in the same function module of a single engine do not support multithreaded calls and cannot be destroyed during calls. If multithreaded calls are required, multiple engines need to be created.

For example:

3. Runtime report java.lang.UnsatisfiedLinkError

java.lang.UnsatisfiedLinkError is a common jni-related error. If this error occurs, there are generally the following reasons:

  • There are several ABI subdirectories in the dynamic library file directory or the related dynamic library file directory under the Android project directory, but the list of files in the subdirectory is different.

Detailed introduction:
First, when an application is installed on a device, only the best so libraries supported by the CPU architecture of the device will be copied to the local lib. For example, in the local library directory of a project, there are four dynamic library files under armeabi-v7: a.so,b.so,c.so,d.so, and two dynamic library files under arm64-v8a: c.so,d.so. A device supports arm64-v8a, arm64-v8a is better than armeabi-v7, so only so files in arm64-v8a directory are copied during installation. It is no problem to load C.so and d.so, but when loading A.so or b.so, because there are no such files in arm64-v8a directory, it will be reported to java.lang.UnsatisfiisfiedLinkError.
The following are some possible scenarios for dynamic library file storage:

Solution:
If the dynamic library directory is not reassigned in build.gradle, the default path for the dynamic library will be projectName - > moduleName - > SRC - > main - > jniLibs.
Make sure that the armeabi-v7a directory under the dynamic library directory or the armeabi-v7a-compatible directory contains ArcFace 2.0 Android SDK-related dynamic library files, and that the list of file names under each ABI directory is the same.

  • Although the dynamic library file was loaded successfully, the corresponding native method could not be found.

Detailed introduction:
For example, in the com.arcsoft.Test class, there is a method defined as:
private native int add(int a,int b),
When writing C++ code, the corresponding content is:
extern "C" JNIEXPORT jint JNICALL Java_com_arcsoft_Test_add(JNIEnv *env, jobject, jint a, jint b, jint c),
Native defines a method with one more parameter. The corresponding Java method will be private native int add(int a, int b, int c). The signatures of the two methods are inconsistent. Therefore, when calling add in Java, the corresponding native method will not be found.

Solution:
Generally, when using SDK, this problem is caused by using jars or dynamic libraries in different versions or platforms. In order to ensure the consistency of method signatures, make sure that jars and dynamic libraries are files in the same version of the same platform.

  • Relevant native methods are defined in Java, but dynamic library files are not loaded

Detailed introduction:
For example, in the com.arcsoft.Test class, there is a method defined as:
private native int add(int a,int b),
One of the corresponding C++ codes is:
Extern "C" JNIEXPORT jint JNICALL Java_com_arcsoft_Test_add (JNIEnv*env, jobject, jint a, jint b), but has been unable to load, it may also be that the dynamic library is not loaded to find the native method.

Solution:
Dynamic libraries need to be loaded before so files are called, usually in a static code block of a class.

<br/>

Reference documents:

Android Platform Development Guide:

https://ai.arcsoft.com.cn/man...

API Interface Description

http://ai.arcsoft.com.cn/stat...

Topics: Android SDK Java Attribute