From 0034d2bcd5408c55feff6d46428df78a0df32008 Mon Sep 17 00:00:00 2001 From: pans <pans@454eff88-639b-444f-9e54-f578c98de674> Date: 星期二, 20 十二月 2016 16:12:59 +0800 Subject: [PATCH] --- RtspFace/demo/sample_face_detect.cpp | 636 ++++++++++++++++++++------------------------------------- 1 files changed, 225 insertions(+), 411 deletions(-) diff --git a/RtspFace/demo/sample_face_detect.cpp b/RtspFace/demo/sample_face_detect.cpp index 1839ebd..eb7f34f 100644 --- a/RtspFace/demo/sample_face_detect.cpp +++ b/RtspFace/demo/sample_face_detect.cpp @@ -1,442 +1,256 @@ -#include <stdio.h> #include <iostream> -#include <opencv2/opencv.hpp> +#include <vector> +#include <stdio.h> +#include <cv_face.h> #include "time_helper.h" -#include "cv_face.h" -#include <windows.h> +#include <opencv2/opencv.hpp> #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) { +//人脸验证 +static cv_handle_t handle_verify = NULL; +//数据库操作 +static cv_handle_t handle_db = NULL; +//静态人脸识别 +static cv_handle_t handle_detect = NULL; + +#define _MAX_PATH 260 + +//提取图片特征值 +cv_feature_t *extract_feature(Mat image_color) { + + Mat image_color_color; + // cvtColor(image_color, image_color_color, CV_BGR2BGRA); // CV_PIX_FMT_BGRA8888 + image_color_color = image_color; // CV_PIX_FMT_BGR888 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; + cv_result_t st_result = CV_OK; + //检测人脸 + st_result = cv_face_detect(handle_detect, image_color_color.data, CV_PIX_FMT_BGR888, + image_color_color.cols, image_color_color.rows, image_color_color.step, + CV_FACE_UP, &p_face, &face_count); + if (face_count >= 1) { + //获取人脸特征 + st_result = cv_verify_get_feature(handle_verify, + (unsigned char *)image_color_color.data, CV_PIX_FMT_BGR888, + image_color_color.cols, image_color_color.rows, image_color_color.step, + p_face, &p_feature, NULL); + if (st_result != CV_OK) { + fprintf(stderr, "cv_verify_get_feature failed, error code %d\n", st_result); } - - // 人脸检测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); + } else { + fprintf(stderr, "can't find face in "); + } + // 释放内存 cv_face_release_detector_result(p_face, face_count); - return string_feature; + return p_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; +//数据库添加数据,并返回记录得id +int db_add(cv_feature_t *p_feature) { + /*cv_feature_t *p_feature = extract_feature(image_color); + if (!p_feature) { + return -1; + }*/ + int idx; + cv_result_t cv_result = cv_verify_add_face(handle_db, p_feature, &idx); + if (cv_result != CV_OK) { + fprintf(stderr, "cv_verify_add_face failed, error code %d\n", cv_result); } - 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; + cv_verify_release_feature(p_feature); + return idx; } -// @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; - - //函数返回的错误代码类型 +//根据id删除记录 +bool db_del(int idx) { + if (idx < 0) { + fprintf(stderr, "invalid idx!\n"); + return false; + } 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; + cv_result = cv_verify_delete_face(handle_db, idx); + if (cv_result != CV_OK) { + fprintf(stderr, "cv_verify_delete_face failed, error code %d\n", cv_result); + } else { + fprintf(stderr, "delete succeed\n"); + } } -int main() { - - //图片入口,现需经过OPENCV处理后被sdk使用。 - char* input_image_path = "../../test_image/face_06.jpg"; - char* output_image_path = "../../test_image/face_06out.jpg"; - - // 创建人脸验证句柄并初始化 - //函数返回的错误代码类型 +//数据库保存 +bool db_save(char *db_path) { cv_result_t cv_result = CV_OK; - cv_handle_t handle_verify =NULL; + cv_result = cv_verify_save_db(handle_db, db_path); + if (cv_result != CV_OK) { + fprintf(stderr, "cv_verify_save_db failed, error code %d\n", cv_result); + return false; + } else { + fprintf(stderr, "save done!\n"); + } + + return true; +} + +//数据库加载 +bool db_load(char *db_path) { + cv_result_t cv_result = CV_OK; + cv_result = cv_verify_load_db(handle_db, db_path); + + if (cv_result != CV_OK) { + fprintf(stderr, "cv_verify_load_db failed, error code %d\n", cv_result); + return false; + } else { + fprintf(stderr, "load done!\n"); + } + + return true; +} + +//搜索数据库 +bool search_db(Mat image_color,char *db_path) { + + cv_feature_t *p_feature = extract_feature(image_color); + if (p_feature == NULL) { + fprintf(stderr, "extract failed !\n"); + return false; + } + db_load(db_path); + //查询前10条 + int top_k = 10; + int *top_idxs = new int[top_k]; + float *top_scores = new float[top_k]; + unsigned int result_length = 0; + cv_result_t cv_result = cv_verify_search_face(handle_verify, handle_db, + p_feature, top_k, + top_idxs, top_scores, &result_length); + if (cv_result == CV_OK) { + //输出检查结果 + for (unsigned int t = 0; t < result_length; t++) { + // const cv_feature_t item = result[t].item; + fprintf(stderr, "%d\t", top_idxs[t]); + fprintf(stderr, "%0.2f\n", top_scores[t]); + } + } else { + fprintf(stderr, "cv_verify_search_face failed, error code %d\n", cv_result); + } + if (top_idxs) { + delete[]top_idxs; + } + if (top_scores) { + delete[]top_scores; + } + cv_verify_release_feature(p_feature); + return true; +} + +//批量导入图片进行分析 +bool db_gen(char *image_list, char *db_path) { + bool bresult = true; + //读取图片列表 + FILE *fp_path = fopen(image_list, "r"); + if(!fp_path) { + fprintf(stderr, "failed to load %s\n", image_list); + return false; + } + + //人脸特征信息 数据结构 + std::vector<cv_feature_t *> list_feature; + list_feature.clear(); + + for (;;) { + char image_path[1024]; + int num = fscanf(fp_path, "%s", image_path); + if (num != 1) { + bresult = false; + break; + } + fprintf(stderr, "extracting %s\n", image_path); + + + // get the face feature + Mat image_color = imread(image_path); + if (!image_color.data) { + return NULL; + } + + cv_feature_t *p_feature = extract_feature(image_color); + if (!p_feature) { + fprintf(stderr, "failed to extract image: %s\n", image_path); + continue; + } + list_feature.push_back(p_feature); + } + fclose(fp_path); + + + cv_verify_destroy_db(handle_db); + cv_result_t cv_result = CV_OK; + cv_verify_create_db(&handle_db); + //创建新的数据库,应该改为判断,如果数据库存在则进行插入,否则新建。 + if(db_load(db_path)){ + for (int x = 0; x < list_feature.size(); x++) { + db_add(list_feature[x]); + } + }else{ + cv_result = cv_verify_build_db(handle_db, &list_feature[0], list_feature.size()); + if (cv_result != CV_OK) { + fprintf(stderr, "cv_verify_build_db failed, error code %d\n", cv_result); + bresult = false; + } + for (int i = 0; i < list_feature.size(); i++) { + cv_verify_release_feature(list_feature[i]); + } + } + cv_verify_save_db(handle_db, db_path); + + + return bresult; +} + +int main(int argc, char *argv[]) { + + //文件路径 + char *db_path = "./out1.db"; + char *image_path = "../../test_image/face_08.jpg"; + char *image_list = "../../test_image/imglist"; + + //创建静态人脸识别句柄,同时创建状态标量 + cv_result_t cv_result = cv_face_create_detector(&handle_detect, NULL, CV_DETECT_ENABLE_ALIGN_21); + if (cv_result != CV_OK){ + fprintf(stderr, "create detect handle failed, error code %d\n", cv_result); + } + //创建人脸验证句柄并初始化 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); - + if (cv_result != CV_OK){ + fprintf(stderr, "create verify handle failed, error code %d\n", cv_result); + } + // 创建人脸数据库句柄 + cv_result = cv_verify_create_db(&handle_db); + if (cv_result != CV_OK){ + fprintf(stderr, "create db handle failed, 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); + //批量插入数据库 + db_gen(image_list,db_path); + + //待搜索的图像 + Mat image_color = imread(image_path); + if (!image_color.data) { + return NULL; } - //-------测试人脸 识别位置 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); + //搜索数据库 + if(search_db(image_color,db_path)){ + cout<<"search db"<<endl; } - //-------测试人脸 验证 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); + //回收内存 + cv_face_destroy_detector(handle_detect); + cv_verify_destroy_db(handle_db); + cv_verify_destroy_handle(handle_verify); return 0; } -- Gitblit v1.8.0