Use OpencV for face recognition of pictures to learn notes. 1. Integrate OpencV 2, transfer the picture to native layer 3, process the picture 4, detect the face 5, and save the characteristic value
Integration of opencv
1, download OpencV, decompress it and find all the supported dynamic link libraries in OpencV-Android-SDK \ SDK \native\libs. Import libopencv_java3.so into jniLibs. 2, import Opencv-Android-sdk SDK native jni include into jniLibs
Cmake_minimum_required (VERSION 3.4.1 track)#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
# check compiler type, if GCC compiler, add c++11 support to compiler options
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)
We need to import our header file based on this configured directory
include_directories(src/main/jniLibs/include)
# Add dependency opencv.so library
set(distribution_DIR ${CMAKE_SOURCE_DIR}/.. /.. /.. /.. /src/main/jniLibs) add_library( opencv_java3 SHARED IMPORTED) set_target_properties( opencv_java3 PROPERTIES IMPORTED_LOCATION .. /.. /.. /.. /src/main/jniLibs/armeabi/libopencv_java3.so) add_library( native-lib SHARED src/main/cpp/native-lib.cpp ) find_library(log-lib
log )
target_link_libraries(
native-lib opencv_java3
jnigraphics Add the dependency library
${log-lib} )
Copy the code
Transfer images to native layer
Define native methods and implement them in CPP.
Bitmap bitmap =
BitmapFactory.decodeResource(getResources(),
R.mipmap.face5);
mFaceDetection.faceDetectionSaveInfo(bitmap);
public native int faceDetectionSaveInfo(Bitmap bitmap);
extern "C" JNIEXPORT jint JNICALLJava_com_example_faceapplication_FaceDetection_faceDetectionSaveInfo(JNIEnv *env, jobject thiz, jobject bitmap) {}Copy the code
Processing images
1. Convert bitmap into Mat matrix object in c++. 2. Grayscale processing is carried out on the picture, and the colored picture is converted into grayscale picture. Direct equalization compensation.
A bitmap is transformed into a Mat matrix
RGB_565 corresponds to CV_8UC2. RGBA_8888 corresponds to CV_8UC4
Mat mat;
bitmap2Mat(env, mat, bitmap);
void bitmap2Mat(JNIEnv *env, Mat &mat, jobject bitmap) {
// Get bitmap information
AndroidBitmapInfo info;// Class provided by Android to get bitmap information.
AndroidBitmap_getInfo(env, bitmap, &info);
// Set mat's header pointer to bitmap's
// To manipulate bitmap, lock the canvas
void *pixels;// Decode the image and get the address pointer saved in memory after decoding the pixel
AndroidBitmap_lockPixels(env, bitmap, &pixels); // You need to use this method to lock the memory address of the image before operating the bitmap.
mat.create(info.height, info.width, CV_8UC4); // Create memory for MAT that is the same size as bitmap. To rGBA_8888 format.
if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
// The mat should be 8uc4
Mat temp(info.height, info.width, CV_8UC4, pixels);
// Copy data from temp to the master MAT
temp.copyTo(mat);
} else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
// The mat should be 8uc2
Mat temp(info.height, info.width, CV_8UC2, pixels);
// Convert 8UC2 to 8UC4
cvtColor(temp, mat, COLOR_BGR5652BGRA);
} else {
// Others automatically go to conversion
}
AndroidBitmap_unlockPixels(env, bitmap);
}
Copy the code
Gray processing
In order to improve the efficiency of the algorithm, it can also be directly recognized, but the effect is very poor, mainly because the original image contains too much information. Each pixel of gray image is 255, while color image is 255* 255* 255. R+G+B = 255 = 0.33r + 0.33g + 0.33b = 0.3r + 0.59g + 0.11b (suitable for human eyes)
Call the OpencV method for processing. Turn color to grey. The lines of the image are then deepened by compensating for the straight-square equalization. The texture is clearer.
Mat gray_mat; cvtColor(mat, gray_mat, COLOR_BGRA2GRAY); Mat equalize_MAT; equalizeHist(gray_mat, equalize_mat);Copy the code
Recognize faces
1, load face classifier file 2, recognition
Load the face classifier file
The lBPCascade_frontalface. XML file is in the opencV directory. Put it locally. The absolute path passes into the native layer.
private void copyCascadeFile(a) {
try {
// load cascade file from application resources
InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
if (mCascadeFile.exists())
return;
FileOutputStream os = new FileOutputStream(mCascadeFile);
byte[] buffer = new byte[4096];
int bytesRead;
while((bytesRead = is.read(buffer)) ! = -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
cascadeDir.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
mFaceDetection.loadCascade(mCascadeFile.getAbsolutePath());
public native void loadCascade(String absolutePath);
CascadeClassifier cascadeClassifier;
extern "C"
JNIEXPORT void JNICALL
Java_com_example_faceapplication_FaceDetection_loadCascade(JNIEnv *env, jobject thiz, jstring filePath_) {
const char *filePath = env->GetStringUTFChars(filePath_, 0);
cascadeClassifier.load(filePath);
LOGE("Classifier file loaded successfully");
env->ReleaseStringUTFChars(filePath_, filePath);
}
Copy the code
identify
CascadeClassifier. DetectMultiScale (equalize_mat, faces, 1.1, 5); The first parameter: mat matrix of the picture the second parameter: put all recognized faces into the set the third parameter: 1.1 default parameter the fourth parameter: The Times of detection. Fifth parameter: minimum face size sixth parameter: maximum face size
// To recognize the face, also need to load the face classifier file
std: :vector<Rect> faces;
cascadeClassifier.detectMultiScale(equalize_mat, faces, 1.1.5);
LOGE("Number of faces: %d",faces.size());
if(faces.size() >= 1) {for (int i = 0; i < faces.size(); ++i) {
Rect faceRect = faces[i];
rectangle(mat,faceRect,Scalar(255.155.155),8); // Draw the box
}
mat2Bitmap(env, mat, bitmap);
}
Copy the code
Saving characteristic data
Mat face_info_mat(equalize_mat,faceRect); // Intercept a portion of the face (recT from the Equalize matrix)Copy the code
The effect
Code links: pan.baidu.com/s/1ZUsJ6qTt… Extraction code: 3NYt