update readme
Showing
2 changed files
with
24 additions
and
9 deletions
1 | 1 | ||
2 | MNN1.0.0+opencv | 2 | MNN1.0.0+opencv |
3 | 3 | ||
4 | 信息结构体 | ||
5 | |||
6 | struct OutputInfo{ | ||
7 | int error_code; | ||
8 | bool result; | ||
9 | }; | ||
10 | |||
11 | struct InitModelError{ | ||
12 | vector<bool> init_error; | ||
13 | }; | ||
14 | |||
4 | 模型初始化 | 15 | 模型初始化 |
5 | 16 | ||
6 | FaceComparison face_rec=FaceComparison(det_model_path,landm_model_path,rec_model_path) | 17 | InitModelError init_model_code; |
18 | FaceComparison face_rec = FaceComparison(); | ||
19 | bool init_model = face_rec.init_model(face_det_model,face_landm_model,face_rec_model,init_model_code); | ||
7 | 20 | ||
8 | det_model_path:人脸检测模型retinaface的模型路径 | 21 | det_model_path:人脸检测模型retinaface的模型路径 |
9 | landm_model_path:106人脸关键点模型的模型路径 | 22 | landm_model_path:106人脸关键点模型的模型路径 |
10 | rec_model_path:人脸识别模型的模型路径 | 23 | rec_model_path:人脸识别模型的模型路径 |
24 | init_model_code:保存每个模型初始化状态true/false | ||
11 | 25 | ||
12 | 重要参数(include/facecomparison.h文件) | 26 | 重要参数(include/facecomparison.h文件) |
13 | 27 | ||
... | @@ -24,13 +38,18 @@ FaceComparison face_rec=FaceComparison(det_model_path,landm_model_path,rec_model | ... | @@ -24,13 +38,18 @@ FaceComparison face_rec=FaceComparison(det_model_path,landm_model_path,rec_model |
24 | 38 | ||
25 | 接口(返回结果 bool:true/false) | 39 | 接口(返回结果 bool:true/false) |
26 | 40 | ||
27 | bool inference(string image_path1,string image_path2);参数为两张图像地址,其中iamge1_path为face_id图像输入 | 41 | int inference(string image_path1,string image_path2,OutputInfo &output_info);参数为两张图像地址,其中iamge1_path为face_id图像输入 |
28 | bool inference(Mat image1,Mat image2);参数为两张opencv读取的图像矩阵,其中iamge1为face_id图像输入 | 42 | int inference(Mat image1,Mat image2,OutputInfo &output_info);参数为两张opencv读取的图像矩阵,其中iamge1为face_id图像输入 |
43 | |||
44 | 调用方式 | ||
45 | |||
46 | OutputInfo output_info; | ||
47 | int result = face_rec.inference(image1,image2,output_info); | ||
29 | 48 | ||
30 | 编译 | 49 | 编译 |
31 | 50 | ||
32 | 将CMakeLists.txt 中 set(FACECOMPARISON_DIR /home/situ/qfs/sdk_project/mnn_projects/face_recognize_mnn/lib) | 51 | 将CMakeLists.txt 中 set(FACECOMPARISON_DIR /home/situ/qfs/sdk_project/mnn_projects/face_recognize_mnn/include) |
33 | 改为lib文件夹所在的绝对地址 | 52 | 改为include文件夹所在的绝对地址 |
34 | mkdir build | 53 | mkdir build |
35 | cd build | 54 | cd build |
36 | cmake .. | 55 | cmake .. | ... | ... |
1 | |||
2 | |||
3 | #include "facerecognize.h" FaceRecognize::FaceRecognize(){} // FaceRecognize::~FaceRecognize(){ // net->releaseModel(); // net->releaseSession(session1); // net->releaseSession(session2); // } bool FaceRecognize::init_model(string model_path){ net=shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile(model_path.c_str())); ScheduleConfig config; config.numThread=num_thread; config.type=forward_type; session1 = net->createSession(config); session2 = net->createSession(config); input_tensor1 = net->getSessionInput(session1,NULL); input_tensor2 = net->getSessionInput(session2,NULL); net->resizeTensor(input_tensor1,{1,3,input_size[1],input_size[0]}); net->resizeSession(session1); net->resizeTensor(input_tensor2,{1,3,input_size[1],input_size[0]}); net->resizeSession(session2); //数据预处理 MNN::CV::ImageProcess::Config image_config; image_config.sourceFormat = MNN::CV::BGR; image_config.destFormat = MNN::CV::BGR; ::memcpy(image_config.mean,mean,sizeof(mean)); ::memcpy(image_config.normal,normal,sizeof(normal)); pretreat = shared_ptr<MNN::CV::ImageProcess>(MNN::CV::ImageProcess::create(image_config)); model_init = true; return model_init; } cv::Mat FaceRecognize::meanAxis0(const cv::Mat &src) { int num = src.rows; int dim = src.cols; cv::Mat output(1,dim,CV_32F); for(int i = 0 ; i < dim; i ++) { float sum = 0 ; for(int j = 0 ; j < num ; j++) { sum+=src.at<float>(j,i); } output.at<float>(0,i) = sum/num; } return output; } cv::Mat FaceRecognize::elementwiseMinus(const cv::Mat &A,const cv::Mat &B) { cv::Mat output(A.rows,A.cols,A.type()); assert(B.cols == A.cols); if(B.cols == A.cols) { for(int i = 0 ; i < A.rows; i ++) { for(int j = 0 ; j < B.cols; j++) { output.at<float>(i,j) = A.at<float>(i,j) - B.at<float>(0,j); } } } return output; } cv::Mat FaceRecognize::varAxis0(const cv::Mat &src) { cv:Mat temp_ = elementwiseMinus(src,meanAxis0(src)); cv::multiply(temp_ ,temp_ ,temp_ ); return meanAxis0(temp_); } int FaceRecognize::MatrixRank(cv::Mat M) { Mat w, u, vt; SVD::compute(M, w, u, vt); Mat1b nonZeroSingularValues = w > 0.0001; int rank = countNonZero(nonZeroSingularValues); return rank; } cv::Mat FaceRecognize::similarTransform(cv::Mat src,cv::Mat dst) { int num = src.rows; int dim = src.cols; cv::Mat src_mean = meanAxis0(src); cv::Mat dst_mean = meanAxis0(dst); cv::Mat src_demean = elementwiseMinus(src, src_mean); cv::Mat dst_demean = elementwiseMinus(dst, dst_mean); cv::Mat A = (dst_demean.t() * src_demean) / static_cast<float>(num); cv::Mat d(dim, 1, CV_32F); d.setTo(1.0f); if (cv::determinant(A) < 0) { d.at<float>(dim - 1, 0) = -1; } Mat T = cv::Mat::eye(dim + 1, dim + 1, CV_32F); cv::Mat U, S, V; SVD::compute(A, S,U, V); // the SVD function in opencv differ from scipy . int rank = MatrixRank(A); if (rank == 0) { assert(rank == 0); } else if (rank == dim - 1) { if (cv::determinant(U) * cv::determinant(V) > 0) { T.rowRange(0, dim).colRange(0, dim) = U * V; } else { int s = d.at<float>(dim - 1, 0) = -1; d.at<float>(dim - 1, 0) = -1; T.rowRange(0, dim).colRange(0, dim) = U * V; cv::Mat diag_ = cv::Mat::diag(d); cv::Mat twp = diag_*V; //np.dot(np.diag(d), V.T) Mat B = Mat::zeros(3, 3, CV_8UC1); Mat C = B.diag(0); T.rowRange(0, dim).colRange(0, dim) = U* twp; d.at<float>(dim - 1, 0) = s; } } else{ cv::Mat diag_ = cv::Mat::diag(d); cv::Mat twp = diag_*V.t(); //np.dot(np.diag(d), V.T) cv::Mat res = U* twp; // U T.rowRange(0, dim).colRange(0, dim) = -U.t()* twp; } cv::Mat var_ = varAxis0(src_demean); float val = cv::sum(var_).val[0]; cv::Mat res; cv::multiply(d,S,res); float scale = 1.0/val*cv::sum(res).val[0]; T.rowRange(0, dim).colRange(0, dim) = - T.rowRange(0, dim).colRange(0, dim).t(); cv::Mat temp1 = T.rowRange(0, dim).colRange(0, dim); // T[:dim, :dim] cv::Mat temp2 = src_mean.t(); //src_mean.T cv::Mat temp3 = temp1*temp2; // np.dot(T[:dim, :dim], src_mean.T) cv::Mat temp4 = scale*temp3; T.rowRange(0, dim).colRange(dim, dim+1)= -(temp4 - dst_mean.t()) ; T.rowRange(0, dim).colRange(0, dim) *= scale; return T; } Mat FaceRecognize::preprocess_face(Mat image,vector<vector<float>> land){ Mat out; cv::resize(image,out,Size(112,112)); float default1[5][2] = { {38.2946f, 51.6963f}, {73.5318f, 51.6963f}, {56.0252f, 71.7366f}, {41.5493f, 92.3655f}, {70.7299f, 92.3655f} }; float lands[5][2]={ {float(land[0][0]*112.0)/float(image.cols),float(land[0][1]*112.0)/float(image.rows)}, {float(land[1][0]*112.0)/float(image.cols),float(land[1][1]*112.0)/float(image.rows)}, {float(land[2][0]*112.0)/float(image.cols),float(land[2][1]*112.0)/float(image.rows)}, {float(land[3][0]*112.0)/float(image.cols),float(land[3][1]*112.0)/float(image.rows)}, {float(land[4][0]*112.0)/float(image.cols),float(land[4][1]*112.0)/float(image.rows)} }; cv::Mat src(5,2,CV_32FC1,default1); memcpy(src.data, default1, 2 * 5 * sizeof(float)); cv::Mat dst(5,2,CV_32FC1,lands); memcpy(dst.data, lands, 2 * 5 * sizeof(float)); cv::Mat M = similarTransform(dst, src); float M_[2][3]={ {M.at<float>(0,0),M.at<float>(0,1),M.at<float>(0,2)}, {M.at<float>(1,0),M.at<float>(1,1),M.at<float>(1,2)}, }; cv::Mat M__(2,3,CV_32FC1,M_); cv::Mat align_image; cv::warpAffine(out,align_image,M__,Size(112, 112)); return align_image; } double FaceRecognize::getMold(const vector<double>& vec) { int n = vec.size(); double sum = 0.0; for (int i = 0; i < n; ++i) sum += vec[i] * vec[i]; return sqrt(sum); } double FaceRecognize::cos_distance(const vector<double>& base, const vector<double>& target) { int n = base.size(); assert(n == target.size()); double tmp = 0.0; for (int i = 0; i < n; ++i) tmp += base[i] * target[i]; double simility = tmp / (getMold(base)*getMold(target)); return simility; } double FaceRecognize::inference(Mat image1,Mat image2){ cv::resize(image1,image1,Size2d(input_size[0],input_size[1])); cv::resize(image2,image2,Size2d(input_size[0],input_size[1])); pretreat->convert(image1.data,input_size[0],input_size[1],0,input_tensor1); pretreat->convert(image2.data,input_size[0],input_size[1],0,input_tensor2); //推理 net->runSession(session1); auto output1= net->getSessionOutput(session1, NULL); //推理 net->runSession(session2); auto output2= net->getSessionOutput(session2, NULL); MNN::Tensor feat_tensor1(output1, output1->getDimensionType()); MNN::Tensor feat_tensor2(output2, output2->getDimensionType()); output1->copyToHostTensor(&feat_tensor1); output2->copyToHostTensor(&feat_tensor2); auto feature1 = feat_tensor1.host<float>(); auto feature2 = feat_tensor2.host<float>(); vector<double> v1,v2; for(int i=0;i<int(feat_tensor1.size()/4);i++){ v1.push_back((double)feature1[i]); v2.push_back((double)feature2[i]); } double cos_score=cos_distance(v1,v2); return cos_score; } double FaceRecognize::inference(string image_path1,string image_path2){ Mat image1 = cv::imread(image_path1); Mat image2 = cv::imread(image_path2); cv::resize(image1,image1,Size2d(input_size[0],input_size[1])); cv::resize(image2,image2,Size2d(input_size[0],input_size[1])); pretreat->convert(image1.data,input_size[0],input_size[1],0,input_tensor1); pretreat->convert(image2.data,input_size[0],input_size[1],0,input_tensor2); //推理 net->runSession(session1); auto output1= net->getSessionOutput(session1, NULL); //推理 net->runSession(session2); auto output2= net->getSessionOutput(session2, NULL); MNN::Tensor feat_tensor1(output1, output1->getDimensionType()); MNN::Tensor feat_tensor2(output2, output2->getDimensionType()); output1->copyToHostTensor(&feat_tensor1); output2->copyToHostTensor(&feat_tensor2); auto feature1 = feat_tensor1.host<float>(); auto feature2 = feat_tensor2.host<float>(); vector<double> v1,v2; for(int i=0;i<int(feat_tensor1.size()/4);i++){ v1.push_back((double)feature1[i]); v2.push_back((double)feature2[i]); } double cos_score=cos_distance(v1,v2); return cos_score; } | ||
4 | |||
5 | #include "facerecognize.h" | 1 | #include "facerecognize.h" |
6 | 2 | ||
7 | // FaceRecognize::~FaceRecognize(){ | 3 | // FaceRecognize::~FaceRecognize(){ | ... | ... |
-
Please register or sign in to post a comment