New file |
| | |
| | | #include <stdio.h> |
| | | #include <iostream> |
| | | #include <opencv2/opencv.hpp> |
| | | #include "time_helper.h" |
| | | #include "cv_face.h" |
| | | #include <windows.h> |
| | | |
| | | #define DEFAULT_THRESHOLD (0.5) |
| | | using namespace std; |
| | | using namespace cv; |
| | | |
| | | // @获取人脸特征值 |
| | | // @param bgr_image 需要提取特征值的图片 |
| | | // @param handle_verify 已经初始化的人脸验证句柄 |
| | | cv_feature_t * getFeature(Mat bgr_image,cv_handle_t handle_verify) { |
| | | |
| | | cv_feature_t *p_feature = NULL; |
| | | Mat image_color; |
| | | image_color = bgr_image; |
| | | |
| | | //调用句柄。用于保存函数及数据的句柄 |
| | | cv_handle_t handle_detect = NULL; |
| | | |
| | | //人脸信息结构体 |
| | | cv_face_t *p_face = NULL; |
| | | |
| | | int face_count = 0; |
| | | |
| | | //函数返回的错误代码类型 |
| | | cv_result_t cv_result = CV_OK; |
| | | char *string_feature; |
| | | do |
| | | { |
| | | // 创建静态图片人脸检测句柄 |
| | | cv_result = cv_face_create_detector(&handle_detect, NULL, CV_DETECT_ENABLE_ALIGN_21); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "fail to init detect handle, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | // 人脸检测1.成功返回CV_OK,否则返回错误类型 |
| | | cv_result = cv_face_detect(handle_detect, image_color.data, CV_PIX_FMT_BGR888, |
| | | image_color.cols, image_color.rows, image_color.step, |
| | | CV_FACE_UP, &p_face, &face_count); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_detect failed, error code : %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | if (face_count > 0) { |
| | | //用于表示人脸特征信息 |
| | | float score; |
| | | unsigned int feature_length = 0; |
| | | |
| | | // get feature |
| | | __TIC__(); |
| | | //提取人脸特征1,可以把返回数组编码成字符串后存储起来以便以后使用 |
| | | cv_result = cv_verify_get_feature(handle_verify, image_color.data, CV_PIX_FMT_BGR888, |
| | | image_color.cols, image_color.rows, image_color.step, p_face, |
| | | &p_feature, &feature_length); |
| | | __TOC__(); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_verify_get_feature failed, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | if (feature_length > 0 ) { |
| | | |
| | | // test serial and deserial |
| | | string_feature = new char[CV_ENCODE_FEATURE_SIZE(p_feature)]; |
| | | cv_verify_serialize_feature(p_feature, string_feature); |
| | | |
| | | //释放提取人脸特征时分配的空间 |
| | | cv_verify_release_feature(p_feature); |
| | | break; |
| | | } else { |
| | | fprintf(stderr, "error, the feature length is 0!\n"); |
| | | } |
| | | // 释放提取人脸特征时分配的空间 |
| | | cv_verify_release_feature(p_feature); |
| | | |
| | | } else { |
| | | if (face_count == 0) { |
| | | fprintf(stderr, "can't find face in \n"); |
| | | } |
| | | } |
| | | } while (0); |
| | | cv_face_release_detector_result(p_face, face_count); |
| | | return string_feature; |
| | | } |
| | | |
| | | |
| | | //测试确定人脸位置 |
| | | int testface_detect(Mat bgr_image_color,char* output_image_path ){ |
| | | |
| | | int points_size = 106; |
| | | int config; |
| | | if (points_size == 21) { |
| | | config = CV_DETECT_ENABLE_ALIGN_21; |
| | | } |
| | | else if (points_size == 106) { |
| | | config = CV_DETECT_ENABLE_ALIGN_106; |
| | | } |
| | | else { |
| | | fprintf(stderr, "alignment point size error, must be 21 or 106\n"); |
| | | return -1; |
| | | } |
| | | |
| | | // load image |
| | | Mat image_color; |
| | | |
| | | |
| | | // cvtColor(bgr_image_color, image_color, CV_BGR2BGRA); // CV_PIX_FMT_BGRA8888 |
| | | image_color = bgr_image_color; // CV_PIX_FMT_BGR888 |
| | | |
| | | // init detect handle |
| | | cv_handle_t handle_detect = NULL; |
| | | cv_result_t cv_result = CV_OK; |
| | | cv_face_t* p_face = NULL; |
| | | int face_count = 0; |
| | | do |
| | | { |
| | | cv_result = cv_face_create_detector(&handle_detect, NULL, config); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_create_detector failed, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | /* |
| | | * test get and set threshold |
| | | */ |
| | | float default_threshold; |
| | | cv_result = cv_face_detect_get_threshold(handle_detect, &default_threshold); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_detect_get_threshold failed, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | fprintf(stderr, "default threshold : %f\n", default_threshold); |
| | | |
| | | cv_result = cv_face_detect_set_threshold(handle_detect, default_threshold); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_detect_set_threshold failed, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | fprintf(stderr, "threshold set : %f\n", default_threshold); |
| | | |
| | | |
| | | // detect |
| | | __TIC__(); |
| | | cv_result = cv_face_detect(handle_detect, image_color.data, CV_PIX_FMT_BGR888, |
| | | image_color.cols, image_color.rows, image_color.step, |
| | | CV_FACE_UP, &p_face, &face_count); |
| | | __TOC__(); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_detect error %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | if (face_count > 0) { |
| | | // draw result |
| | | for (int i = 0; i < face_count; i++) { |
| | | rectangle(image_color, Point(p_face[i].rect.left, p_face[i].rect.top), |
| | | Point(p_face[i].rect.right, p_face[i].rect.bottom), |
| | | Scalar(0, 255, 0), 2, 8, 0); |
| | | fprintf(stderr, "face number: %d\n", i + 1); |
| | | fprintf(stderr, "face rect: [%d, %d, %d, %d]\n", p_face[i].rect.top, |
| | | p_face[i].rect.left, |
| | | p_face[i].rect.right, p_face[i].rect.bottom); |
| | | fprintf(stderr, "score: %f\n", p_face[i].score); |
| | | fprintf(stderr, "face pose: [yaw: %f, pitch: %f, roll: %f, eye distance: %f]\n", |
| | | p_face[i].yaw, |
| | | p_face[i].pitch, p_face[i].roll, p_face[i].eye_dist); |
| | | fprintf(stderr, "face algin:\n"); |
| | | for (unsigned int j = 0; j < p_face[i].points_count; j++) { |
| | | float x = p_face[i].points_array[j].x; |
| | | float y = p_face[i].points_array[j].y; |
| | | fprintf(stderr, "(%.2f, %.2f)\n", x, y); |
| | | circle(image_color, Point2f(x, y), 2, Scalar(0, 0, 255), -1); |
| | | } |
| | | fprintf(stderr, "\n"); |
| | | } |
| | | // save image |
| | | imwrite(output_image_path, image_color); |
| | | } |
| | | else { |
| | | fprintf(stderr, "can't find face in "); |
| | | } |
| | | |
| | | } while (0); |
| | | |
| | | |
| | | // release the memory of face |
| | | cv_face_release_detector_result(p_face, face_count); |
| | | // destroy detect handle |
| | | cv_face_destroy_detector(handle_detect); |
| | | |
| | | |
| | | fprintf(stderr, "test finish!\n"); |
| | | return 0; |
| | | } |
| | | |
| | | // @brief 测试人脸对比 |
| | | // @param bgr_image_1 图像1 |
| | | // @param bgr_image_1 图像2 |
| | | int testface_verify(Mat bgr_image_1,Mat bgr_image_2){ |
| | | |
| | | // 保存两个图片的原始数据 |
| | | Mat image_color_1,image_color_2; |
| | | // cvtColor(bgr_image_1, image_color_color_1, CV_BGR2BGRA); // CV_PIX_FMT_BGRA8888 |
| | | image_color_1 = bgr_image_1; // CV_PIX_FMT_BGR888 |
| | | // cvtColor(bgr_image_2, image_color_2, CV_BGR2BGRA); |
| | | image_color_2 = bgr_image_2; |
| | | |
| | | int main_return = -1; |
| | | |
| | | //调用句柄。用于保存函数及数据的句柄 |
| | | cv_handle_t handle_detect = NULL; |
| | | cv_handle_t handle_verify = NULL; |
| | | |
| | | //人脸信息结构体 |
| | | cv_face_t *p_face_1 = NULL; |
| | | cv_face_t *p_face_2 = NULL; |
| | | |
| | | int face_count_1 = 0; |
| | | int face_count_2 = 0; |
| | | |
| | | //函数返回的错误代码类型 |
| | | cv_result_t cv_result = CV_OK; |
| | | |
| | | do { |
| | | cout<<"a"<<endl; |
| | | // 创建静态图片人脸检测句柄 |
| | | cv_result = cv_face_create_detector(&handle_detect, NULL, CV_DETECT_ENABLE_ALIGN_21); |
| | | |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "fail to init detect handle, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | // 人脸检测1.成功返回CV_OK,否则返回错误类型 |
| | | cv_result = cv_face_detect(handle_detect, image_color_1.data, CV_PIX_FMT_BGR888, |
| | | image_color_1.cols, image_color_1.rows, image_color_1.step, |
| | | CV_FACE_UP, &p_face_1, &face_count_1); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_detect failed, error code : %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | // 人脸检测2.成功返回CV_OK,否则返回错误类型 |
| | | cv_result = cv_face_detect(handle_detect, image_color_2.data, CV_PIX_FMT_BGR888, |
| | | image_color_2.cols, image_color_2.rows, image_color_2.step, |
| | | CV_FACE_UP, &p_face_2, &face_count_2); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_face_detect failed, error code : %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | // 人脸验证 |
| | | if (face_count_1 > 0 && face_count_2 > 0) { |
| | | // 创建人脸验证句柄 |
| | | cv_result = cv_verify_create_handle(&handle_verify, "../../../models/verify.model"); |
| | | if (cv_result != CV_OK) |
| | | { |
| | | fprintf(stderr, "fail to init verify handle, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | if (handle_verify) { |
| | | int model_version = cv_verify_get_version(handle_verify); |
| | | fprintf(stderr, "verify model version : %d\n", model_version); |
| | | int feature_length = cv_verify_get_feature_length(handle_verify); |
| | | fprintf(stderr, "verify model feature length : %d\n", feature_length); |
| | | |
| | | //用于表示人脸特征信息 |
| | | cv_feature_t *p_feature_1 = NULL, *p_feature_2 = NULL; |
| | | float score; |
| | | unsigned int feature_length_1 = 0, feature_length_2 = 0; |
| | | |
| | | // get feature |
| | | __TIC__(); |
| | | //提取人脸特征1,可以把返回数组编码成字符串后存储起来以便以后使用 |
| | | cv_result = cv_verify_get_feature(handle_verify, image_color_1.data, CV_PIX_FMT_BGR888, |
| | | image_color_1.cols, image_color_1.rows, image_color_1.step, p_face_1, |
| | | &p_feature_1, &feature_length_1); |
| | | __TOC__(); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_verify_get_feature failed, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | //提取人脸特征1,可以把返回数组编码成字符串后存储起来以便以后使用 |
| | | cv_result = cv_verify_get_feature(handle_verify, image_color_2.data, CV_PIX_FMT_BGR888, |
| | | image_color_2.cols, image_color_2.rows, image_color_2.step, p_face_2, |
| | | &p_feature_2, &feature_length_2); |
| | | if (cv_result != CV_OK) { |
| | | fprintf(stderr, "cv_verify_get_feature failed, error code %d\n", cv_result); |
| | | break; |
| | | } |
| | | |
| | | if (feature_length_1 > 0 && feature_length_2 > 0) { |
| | | cv_feature_header_t *p_feature_header = CV_FEATURE_HEADER(p_feature_1); |
| | | fprintf(stderr, "Feature information:\n"); |
| | | fprintf(stderr, " ver:\t0x%08x\n", p_feature_header->ver); |
| | | fprintf(stderr, " length:\t%d bytes\n", p_feature_header->len); |
| | | |
| | | // 人脸验证 |
| | | cv_result = cv_verify_compare_feature(handle_verify, p_feature_1, |
| | | p_feature_2, &score); |
| | | if (cv_result == CV_OK) { |
| | | fprintf(stderr, "score: %f\n", score); |
| | | // comapre score with DEFAULT_THRESHOLD |
| | | // > DEFAULT_THRESHOLD => the same person |
| | | // < DEFAULT_THRESHOLD => different people |
| | | if (score > DEFAULT_THRESHOLD) |
| | | fprintf(stderr, "the same person.\n"); |
| | | else |
| | | fprintf(stderr, "different people.\n"); |
| | | |
| | | main_return = 0; // success |
| | | } |
| | | else { |
| | | fprintf(stderr, "cv_verify_compare_feature failed, error code : %d\n", cv_result); |
| | | } |
| | | |
| | | // test serial and deserial |
| | | char *string_feature_1 = new char[CV_ENCODE_FEATURE_SIZE(p_feature_1)]; |
| | | cv_verify_serialize_feature(p_feature_1, string_feature_1); |
| | | cout<<string_feature_1<<endl; |
| | | cv_feature_t *p_feature_new_1 = cv_verify_deserialize_feature(string_feature_1); |
| | | delete[]string_feature_1; |
| | | char *string_feature_2; |
| | | string_feature_2 = new char[CV_ENCODE_FEATURE_SIZE(p_feature_2)]; |
| | | cv_verify_serialize_feature(p_feature_2, string_feature_2); |
| | | cout<<string_feature_2<<endl; |
| | | cv_feature_t *p_feature_new_2 = cv_verify_deserialize_feature(string_feature_2); |
| | | delete[]string_feature_2; |
| | | |
| | | score = 0.0; |
| | | cv_result = cv_verify_compare_feature(handle_verify, p_feature_1, |
| | | p_feature_2, &score); |
| | | fprintf(stderr, "after serial and deserial the feature compare score is %f \n", score); |
| | | cin>>string_feature_2; |
| | | //释放提取人脸特征时分配的空间 |
| | | cv_verify_release_feature(p_feature_new_1); |
| | | cv_verify_release_feature(p_feature_new_2); |
| | | } |
| | | else { |
| | | fprintf(stderr, "error, the feature length is 0!\n"); |
| | | } |
| | | // 释放提取人脸特征时分配的空间 |
| | | cv_verify_release_feature(p_feature_1); |
| | | cv_verify_release_feature(p_feature_2); |
| | | |
| | | } |
| | | } |
| | | else { |
| | | if (face_count_1 == 0) { |
| | | fprintf(stderr, "can't find face in \n"); |
| | | } |
| | | if (face_count_2 == 0) { |
| | | fprintf(stderr, "can't find face in \n"); |
| | | } |
| | | } |
| | | } while (0); |
| | | |
| | | |
| | | // release the memory of face |
| | | cv_face_release_detector_result(p_face_1, face_count_1); |
| | | cv_face_release_detector_result(p_face_2, face_count_2); |
| | | // destroy detect handle |
| | | cv_face_destroy_detector(handle_detect); |
| | | // destroy verify handle |
| | | cv_verify_destroy_handle(handle_verify); |
| | | fprintf(stderr, "test finish!\n"); |
| | | return 0; |
| | | } |
| | | |
| | | int main() { |
| | | |
| | | //图片入口,现需经过OPENCV处理后被sdk使用。 |
| | | char* input_image_path = "../../test_image/face_06.jpg"; |
| | | char* output_image_path = "../../test_image/face_06out.jpg"; |
| | | |
| | | // 创建人脸验证句柄并初始化 |
| | | //函数返回的错误代码类型 |
| | | cv_result_t cv_result = CV_OK; |
| | | cv_handle_t handle_verify =NULL; |
| | | cv_result = cv_verify_create_handle(&handle_verify, "../../../models/verify.model"); |
| | | if (cv_result != CV_OK) |
| | | { |
| | | fprintf(stderr, "fail to init verify handle, error code %d\n", cv_result); |
| | | |
| | | } |
| | | |
| | | |
| | | //-------测试人脸 识别位置 start------- |
| | | Mat bgr_image_1 = imread(input_image_path); |
| | | if (!bgr_image_1.data) { |
| | | fprintf(stderr, "fail to read %s\n", input_image_path); |
| | | return -1; |
| | | }else |
| | | { |
| | | testface_detect(bgr_image_1,output_image_path); |
| | | } |
| | | //-------测试人脸 识别位置 end------- |
| | | /* |
| | | //-------测试人脸 验证 start------- |
| | | output_image_path = "../../test_image/face_04.jpg"; |
| | | Mat bgr_image_2 = imread(output_image_path); |
| | | if (!bgr_image_2.data) { |
| | | fprintf(stderr, "fail to read %s\n", output_image_path); |
| | | return -1; |
| | | }else |
| | | { |
| | | testface_verify(bgr_image_color,bgr_image_2); |
| | | } |
| | | //-------测试人脸 验证 end------- |
| | | |
| | | |
| | | //-------测试提取人脸特征值 start------- |
| | | Mat bgr_image_1 = imread(input_image_path); |
| | | char *string_feature; |
| | | |
| | | if (!bgr_image_1.data) { |
| | | fprintf(stderr, "fail to read %s\n", input_image_path); |
| | | return -1; |
| | | }else |
| | | { |
| | | string_feature=getFeature(bgr_image_1,handle_verify); |
| | | } |
| | | cout<<string_feature<<endl; |
| | | //-------测试提取人脸特征值 end------- |
| | | */ |
| | | // |
| | | |
| | | |
| | | |
| | | |
| | | cin>>cv_result; |
| | | Sleep(100); |
| | | return 0; |
| | | } |
| | | |