c7e48e8e by 乔峰昇

the first submit

0 parents
1
2 opencv4.5.5
3
4 模型初始化
5
6 FaceRecognize face_rec=FaceRecognize(det_model_path,landm_model_path,rec_model_path)
7
8 det_model_path:人脸检测模型retinaface的onnx模型路径
9 landm_model_path:106人脸关键点模型的onnx模型路径
10 rec_model_path:人脸识别模型的onnx模型路径
11
12 重要参数(.h文件)
13
14 bool use_gpu=true; //是否使用gpu
15 float confidence_threshold = 0.5; //人脸检测阈值
16 float nms_threshold = 0.4; //nms阈值
17 double face_recongnize_thr = 0.2; //人脸相似度阈值
18
19 接口(返回结果 bool:true/false)
20
21 bool face_recognize(string image1_path,string image2_path);参数为两张图像地址,其中iamge1_path为face_id图像输入
22 bool face_recognize_image(Mat image1,Mat image2);参数为两张opencv读取的图像矩阵,其中iamge1为face_id图像输入
23
24 编译
25
26 g++ main.cpp -L . -lfacerecognize -o main
27 如果报错无法找到改用:g++ main.cpp -L . -lfacerecognize -o main pkg-config --libs --cflags opencv4
28 ./main
No preview for this file type
No preview for this file type
1 #include "facerecognize.h"
2 #include<iostream>
3 //人脸检测部分
4 // 生成anchors
5 vector<vector<float>> FaceRecognize::priorBox(vector<float> image_size){
6 vector<int> tmp1={16,32};
7 vector<int> tmp2={64,128};
8 vector<int> tmp3={256,512};
9 vector<vector<int>> min_sizes_;
10 min_sizes_.push_back(tmp1);
11 min_sizes_.push_back(tmp2);
12 min_sizes_.push_back(tmp3);
13 vector<int> steps={8,16,32};
14 vector<vector<int>> feature_maps;
15 vector<vector<float>> anchors;
16 for(int &step:steps){
17 vector<int> tmp(2,0);
18 tmp[0]=ceil(image_size[0]/step);
19 tmp[1]=ceil(image_size[1]/step);
20 feature_maps.push_back(tmp);
21 }
22 for(int k=0;k<feature_maps.size();k++){
23 vector<int> min_sizes=min_sizes_[k];
24
25 for(int i=0;i<feature_maps[k][0];i++){
26 for(int j=0;j<feature_maps[k][1];j++){
27 for(int &min_size:min_sizes){
28 float s_kx=float(min_size)/float(image_size[1]);
29 float s_ky=float(min_size)/float(image_size[0]);
30 float dense_cx=float((float(j)+float(0.5))*steps[k])/float(image_size[1]);
31 float dense_cy=float((float(i)+float(0.5))*steps[k])/float(image_size[1]);
32 vector<float> tmp_anchor={dense_cx,dense_cy,s_kx,s_ky};
33 anchors.push_back(tmp_anchor);
34 }
35 }
36 }
37 }
38 return anchors;
39 }
40
41 // 解析bounding box 包含置信度
42 vector<Bbox> FaceRecognize::decode(vector<vector<float>> loc,vector<vector<float>> score,vector<vector<float>>pre,vector<vector<float>> priors,vector<float> variances){
43 vector<Bbox> boxes;
44 for(int i=0;i<priors.size();++i){
45 float b1=priors[i][0]+loc[i][0]*variances[0]*priors[i][2];
46 float b2=priors[i][1]+loc[i][1]*variances[0]*priors[i][3];
47 float b3=priors[i][2]*exp(loc[i][2]*variances[1]);
48 float b4=priors[i][3]*exp(loc[i][3]*variances[1]);
49 b1=b1-b3/float(2);
50 b2=b2-b4/float(2);
51 b3=b3+b1;
52 b4=b4+b2;
53 float l1=priors[i][0]+pre[i][0]*variances[0]*priors[i][2];
54 float l2=priors[i][1]+pre[i][1]*variances[0]*priors[i][3];
55 float l3=priors[i][0]+pre[i][2]*variances[0]*priors[i][2];
56 float l4=priors[i][1]+pre[i][3]*variances[0]*priors[i][3];
57 float l5=priors[i][0]+pre[i][4]*variances[0]*priors[i][2];
58 float l6=priors[i][1]+pre[i][5]*variances[0]*priors[i][3];
59 float l7=priors[i][0]+pre[i][6]*variances[0]*priors[i][2];
60 float l8=priors[i][1]+pre[i][7]*variances[0]*priors[i][3];
61 float l9=priors[i][0]+pre[i][8]*variances[0]*priors[i][2];
62 float l10=priors[i][1]+pre[i][9]*variances[0]*priors[i][3];
63 Bbox tmp_box={.xmin=b1*input_size[0]/resize_scale,.ymin=b2*input_size[1]/resize_scale,.xmax=b3*input_size[0]/resize_scale,.ymax=b4*input_size[1]/resize_scale,
64 .score=float(score[i][0]),.x1=(l1*input_size[0])/resize_scale,.y1=l2*input_size[1]/resize_scale,.x2=l3*input_size[0]/resize_scale,.y2=l4*input_size[1]/resize_scale,
65 .x3=l5*input_size[0]/resize_scale,.y3=l6*input_size[1]/resize_scale,.x4=l7*input_size[0]/resize_scale,.y4=l8*input_size[1]/resize_scale,.x5=l9*input_size[0]/resize_scale,.y5=l10*input_size[1]/resize_scale};
66 boxes.push_back(tmp_box);
67 }
68 return boxes;
69 }
70
71 //NMS
72 void FaceRecognize::nms_cpu(std::vector<Bbox> &bboxes, float threshold){
73 if (bboxes.empty()){
74 return ;
75 }
76 // 1.之前需要按照score排序
77 std::sort(bboxes.begin(), bboxes.end(), [&](Bbox b1, Bbox b2){return b1.score>b2.score;});
78 // 2.先求出所有bbox自己的大小
79 std::vector<float> area(bboxes.size());
80 for (int i=0; i<bboxes.size(); ++i){
81 area[i] = (bboxes[i].xmax - bboxes[i].xmin + 1) * (bboxes[i].ymax - bboxes[i].ymin + 1);
82 }
83 // 3.循环
84 for (int i=0; i<bboxes.size(); ++i){
85 for (int j=i+1; j<bboxes.size(); ){
86 float left = std::max(bboxes[i].xmin, bboxes[j].xmin);
87 float right = std::min(bboxes[i].xmax, bboxes[j].xmax);
88 float top = std::max(bboxes[i].ymin, bboxes[j].ymin);
89 float bottom = std::min(bboxes[i].ymax, bboxes[j].ymax);
90 float width = std::max(right - left + 1, 0.f);
91 float height = std::max(bottom - top + 1, 0.f);
92 float u_area = height * width;
93 float iou = (u_area) / (area[i] + area[j] - u_area);
94 if (iou>=threshold){
95 bboxes.erase(bboxes.begin()+j);
96 area.erase(area.begin()+j);
97 }else{
98 ++j;
99 }
100 }
101 }
102 }
103 // Mat转vector
104 vector<vector<float>> FaceRecognize::mat2vector(Mat mat){
105 vector<vector<float>> vec;
106 for(int i=0;i<mat.rows;++i){
107 vector<float> m;
108 for(int j=0;j<mat.cols;++j){
109 m.push_back(mat.at<float>(i,j));
110 }
111 vec.push_back(m);
112 }
113 return vec;
114 }
115 // 根据阈值筛选
116 vector<Bbox> FaceRecognize::select_score(vector<Bbox> bboxes,float threshold,float w_r,float h_r){
117 vector<Bbox> results;
118 for(Bbox &box:bboxes){
119 if (float(box.score)>=threshold){
120 box.xmin=box.xmin/w_r;
121 box.ymin=box.ymin/h_r;
122 box.xmax=box.xmax/w_r;
123 box.ymax=box.ymax/h_r;
124 box.x1=box.x1/w_r;
125 box.y1=box.y1/h_r;
126 box.x2=box.x2/w_r;
127 box.y2=box.y2/h_r;
128 box.x3=box.x3/w_r;
129 box.y3=box.y3/h_r;
130 box.x4=box.x4/w_r;
131 box.y4=box.y4/h_r;
132 box.x5=box.x5/w_r;
133 box.y5=box.y5/h_r;
134 results.push_back(box);
135 }
136 }
137 return results;
138 }
139
140 // 数据后处理
141 vector<Bbox> FaceRecognize::bbox_process(vector<Bbox> bboxes,float frame_w,float frame_h){
142 vector<Bbox> result_bboxes;
143 for(Bbox &bbox:bboxes){
144 Bbox new_bbox;
145 float face_w=bbox.xmax-bbox.xmin;
146 float face_h=bbox.ymax-bbox.ymin;
147 new_bbox.xmin=bbox.xmin-face_w*0.15;
148 new_bbox.xmax=bbox.xmax+face_w*0.15;
149 new_bbox.ymin=bbox.ymin;
150 new_bbox.ymax=bbox.ymax+face_h*0.15;
151 new_bbox.xmin=new_bbox.xmin>0?new_bbox.xmin:0;
152 new_bbox.ymin=new_bbox.ymin>0?new_bbox.ymin:0;
153 new_bbox.xmax=new_bbox.xmax>frame_w?frame_w:new_bbox.xmax;
154 new_bbox.ymax=new_bbox.ymax>frame_h?frame_h:new_bbox.ymax;
155 new_bbox.score=bbox.score;
156 new_bbox.x1=bbox.x1>0?bbox.x1:0;
157 new_bbox.y1=bbox.y1>0?bbox.y1:0;
158 new_bbox.x2=bbox.x2>0?bbox.x2:0;
159 new_bbox.y2=bbox.y2>0?bbox.y2:0;
160 new_bbox.x3=bbox.x3>0?bbox.x3:0;
161 new_bbox.y3=bbox.y3>0?bbox.y3:0;
162 new_bbox.x4=bbox.x4>0?bbox.x4:0;
163 new_bbox.y4=bbox.y4>0?bbox.y4:0;
164 new_bbox.x5=bbox.x5>0?bbox.x5:0;
165 new_bbox.y5=bbox.y5>0?bbox.y5:0;
166 result_bboxes.push_back(new_bbox);
167
168 }
169 return result_bboxes;
170 }
171 // 推理
172 vector<Bbox> FaceRecognize::detect(string image_path){
173 cv::Mat image = cv::imread(image_path); // 读取图片
174 float w_r=float(640)/float(image.cols);
175 float h_r=float(640)/float(image.rows);
176 cv::Mat blob = cv::dnn::blobFromImage(image,resize_scale,Size(input_size[0],input_size[1]),Scalar(mean_data[0],mean_data[1],mean_data[2])); // 由图片加载数据 这里还可以进行缩放、归一化等预处理
177 det_net.setInput(blob); // 设置模型输入
178 std::vector<cv::Mat> det_netOutputImg;
179 det_net.forward(det_netOutputImg,det_net.getUnconnectedOutLayersNames()); // 推理出结果
180 cv::Mat scores_ = det_netOutputImg[2].reshape(1,16800);
181 cv::Mat boxes_ = det_netOutputImg[0].reshape(1,16800);
182 cv::Mat landms_ = det_netOutputImg[1].reshape(1,16800);
183 std::vector<vector<float>> scores,boxes,landms;
184
185 scores=mat2vector(scores_);
186 boxes=mat2vector(boxes_);
187 landms=mat2vector(landms_);
188
189
190 vector<vector<float>> anchors=priorBox(input_size);
191 vector<Bbox> result_boxes=decode(boxes,scores,landms,anchors,variances);
192 vector<Bbox> results=select_score(result_boxes,confidence_threshold,w_r,h_r);
193
194 // vector<Bbox> result_bboxes=vec2Bbox(boxes,w_r,h_r);
195
196 nms_cpu(results,nms_threshold);
197 if(is_bbox_process){
198 vector<Bbox> res_bboxes=bbox_process(results,input_size[0],input_size[1]);
199 return res_bboxes;
200
201 }else{
202 return results;
203 }
204 }
205
206 vector<Bbox> FaceRecognize::detect_image(Mat image){
207 float w_r=float(640)/float(image.cols);
208 float h_r=float(640)/float(image.rows);
209 cv::Mat blob = cv::dnn::blobFromImage(image,resize_scale,Size(input_size[0],input_size[1]),Scalar(mean_data[0],mean_data[1],mean_data[2])); // 由图片加载数据 这里还可以进行缩放、归一化等预处理
210 det_net.setInput(blob); // 设置模型输入
211 std::vector<cv::Mat> det_netOutputImg;
212 det_net.forward(det_netOutputImg,det_net.getUnconnectedOutLayersNames()); // 推理出结果
213 cv::Mat scores_ = det_netOutputImg[2].reshape(1,16800);
214 cv::Mat boxes_ = det_netOutputImg[0].reshape(1,16800);
215 cv::Mat landms_ = det_netOutputImg[1].reshape(1,16800);
216 std::vector<vector<float>> scores,boxes,landms;
217
218 scores=mat2vector(scores_);
219 boxes=mat2vector(boxes_);
220 landms=mat2vector(landms_);
221
222
223 vector<vector<float>> anchors=priorBox(input_size);
224 vector<Bbox> result_boxes=decode(boxes,scores,landms,anchors,variances);
225 vector<Bbox> results=select_score(result_boxes,confidence_threshold,w_r,h_r);
226
227 // vector<Bbox> result_bboxes=vec2Bbox(boxes,w_r,h_r);
228
229 nms_cpu(results,nms_threshold);
230 if(is_bbox_process){
231 vector<Bbox> res_bboxes=bbox_process(results,image.cols,image.rows);
232 return res_bboxes;
233
234 }else{
235 return results;
236 }
237 }
238
239
240 //人脸关键点部分
241 vector<vector<float>> FaceRecognize::detect_landmarks(string image_path){
242 cv::Mat image=cv::imread(image_path);
243 float w_r=image.cols/112;
244 float h_r=image.rows/112;
245
246 cv::Mat blob = cv::dnn::blobFromImage(image,1.0,Size(112,112)); // 由图片加载数据 这里还可以进行缩放、归一化等预处理
247 landm_net.setInput(blob); // 设置模型输入
248 std::vector<cv::Mat> landm_netOutputImg;
249 landm_net.forward(landm_netOutputImg,landm_net.getUnconnectedOutLayersNames()); // 推理出结果
250 cv::Mat predict_landmarks = landm_netOutputImg[0].reshape(1,106);
251 vector<vector<float>> result_landmarks;
252 for(int i=0;i<predict_landmarks.rows;++i){
253 vector<float> tmp_landm={predict_landmarks.at<float>(i,0)*w_r,predict_landmarks.at<float>(i,1)*h_r};
254 result_landmarks.push_back(tmp_landm);
255 }
256 return result_landmarks;
257 }
258
259 vector<vector<float>> FaceRecognize::detect_image_landmarks(cv::Mat image){
260 float w_r=image.cols/float(112);
261 float h_r=image.rows/float(112);
262 cv::Mat blob = cv::dnn::blobFromImage(image,1.0,Size(112,112)); // 由图片加载数据 这里还可以进行缩放、归一化等预处理
263 landm_net.setInput(blob); // 设置模型输入
264 std::vector<cv::Mat> landm_netOutputImg;
265 landm_net.forward(landm_netOutputImg,landm_net.getUnconnectedOutLayersNames()); // 推理出结果
266 cv::Mat predict_landmarks = landm_netOutputImg[0].reshape(1,106);
267 vector<vector<float>> result_landmarks;
268 for(int i=0;i<predict_landmarks.rows;++i){
269 vector<float> tmp_landm={predict_landmarks.at<float>(i,0)*w_r,predict_landmarks.at<float>(i,1)*h_r};
270 result_landmarks.push_back(tmp_landm);
271 }
272 return result_landmarks;
273 }
274
275
276
277 //人脸识别部分
278
279 cv::Mat FaceRecognize::meanAxis0(const cv::Mat &src)
280 {
281 int num = src.rows;
282 int dim = src.cols;
283
284 // x1 y1
285 // x2 y2
286
287 cv::Mat output(1,dim,CV_32F);
288 for(int i = 0 ; i < dim; i ++)
289 {
290 float sum = 0 ;
291 for(int j = 0 ; j < num ; j++)
292 {
293 sum+=src.at<float>(j,i);
294 }
295 output.at<float>(0,i) = sum/num;
296 }
297
298 return output;
299 }
300
301 cv::Mat FaceRecognize::elementwiseMinus(const cv::Mat &A,const cv::Mat &B)
302 {
303 cv::Mat output(A.rows,A.cols,A.type());
304
305 assert(B.cols == A.cols);
306 if(B.cols == A.cols)
307 {
308 for(int i = 0 ; i < A.rows; i ++)
309 {
310 for(int j = 0 ; j < B.cols; j++)
311 {
312 output.at<float>(i,j) = A.at<float>(i,j) - B.at<float>(0,j);
313 }
314 }
315 }
316 return output;
317 }
318
319 cv::Mat FaceRecognize::varAxis0(const cv::Mat &src)
320 {
321 cv:Mat temp_ = elementwiseMinus(src,meanAxis0(src));
322 cv::multiply(temp_ ,temp_ ,temp_ );
323 return meanAxis0(temp_);
324
325 }
326
327 int FaceRecognize::MatrixRank(cv::Mat M)
328 {
329 Mat w, u, vt;
330 SVD::compute(M, w, u, vt);
331 Mat1b nonZeroSingularValues = w > 0.0001;
332 int rank = countNonZero(nonZeroSingularValues);
333 return rank;
334
335 }
336
337 cv::Mat FaceRecognize::similarTransform(cv::Mat src,cv::Mat dst) {
338 int num = src.rows;
339 int dim = src.cols;
340 cv::Mat src_mean = meanAxis0(src);
341 cv::Mat dst_mean = meanAxis0(dst);
342 cv::Mat src_demean = elementwiseMinus(src, src_mean);
343 cv::Mat dst_demean = elementwiseMinus(dst, dst_mean);
344 cv::Mat A = (dst_demean.t() * src_demean) / static_cast<float>(num);
345 cv::Mat d(dim, 1, CV_32F);
346 d.setTo(1.0f);
347 if (cv::determinant(A) < 0) {
348 d.at<float>(dim - 1, 0) = -1;
349
350 }
351 Mat T = cv::Mat::eye(dim + 1, dim + 1, CV_32F);
352 cv::Mat U, S, V;
353 SVD::compute(A, S,U, V);
354
355 // the SVD function in opencv differ from scipy .
356
357
358 int rank = MatrixRank(A);
359 if (rank == 0) {
360 assert(rank == 0);
361
362 } else if (rank == dim - 1) {
363 if (cv::determinant(U) * cv::determinant(V) > 0) {
364 T.rowRange(0, dim).colRange(0, dim) = U * V;
365 } else {
366 int s = d.at<float>(dim - 1, 0) = -1;
367 d.at<float>(dim - 1, 0) = -1;
368
369 T.rowRange(0, dim).colRange(0, dim) = U * V;
370 cv::Mat diag_ = cv::Mat::diag(d);
371 cv::Mat twp = diag_*V; //np.dot(np.diag(d), V.T)
372 Mat B = Mat::zeros(3, 3, CV_8UC1);
373 Mat C = B.diag(0);
374 T.rowRange(0, dim).colRange(0, dim) = U* twp;
375 d.at<float>(dim - 1, 0) = s;
376 }
377 }
378 else{
379 cv::Mat diag_ = cv::Mat::diag(d);
380 cv::Mat twp = diag_*V.t(); //np.dot(np.diag(d), V.T)
381 cv::Mat res = U* twp; // U
382 T.rowRange(0, dim).colRange(0, dim) = -U.t()* twp;
383 }
384 cv::Mat var_ = varAxis0(src_demean);
385 float val = cv::sum(var_).val[0];
386 cv::Mat res;
387 cv::multiply(d,S,res);
388 float scale = 1.0/val*cv::sum(res).val[0];
389 T.rowRange(0, dim).colRange(0, dim) = - T.rowRange(0, dim).colRange(0, dim).t();
390 cv::Mat temp1 = T.rowRange(0, dim).colRange(0, dim); // T[:dim, :dim]
391 cv::Mat temp2 = src_mean.t(); //src_mean.T
392 cv::Mat temp3 = temp1*temp2; // np.dot(T[:dim, :dim], src_mean.T)
393 cv::Mat temp4 = scale*temp3;
394 T.rowRange(0, dim).colRange(dim, dim+1)= -(temp4 - dst_mean.t()) ;
395 T.rowRange(0, dim).colRange(0, dim) *= scale;
396 return T;
397 }
398
399 Mat FaceRecognize::preprocess_face(Mat image,vector<vector<float>> land){
400 Mat out;
401 cv::resize(image,out,Size(112,112));
402 float default1[5][2] = {
403 {38.2946f, 51.6963f},
404 {73.5318f, 51.6963f},
405 {56.0252f, 71.7366f},
406 {41.5493f, 92.3655f},
407 {70.7299f, 92.3655f}
408 };
409
410 float lands[5][2]={
411 {float(land[0][0]*112.0)/float(image.cols),float(land[0][1]*112.0)/float(image.rows)},
412 {float(land[1][0]*112.0)/float(image.cols),float(land[1][1]*112.0)/float(image.rows)},
413 {float(land[2][0]*112.0)/float(image.cols),float(land[2][1]*112.0)/float(image.rows)},
414 {float(land[3][0]*112.0)/float(image.cols),float(land[3][1]*112.0)/float(image.rows)},
415 {float(land[4][0]*112.0)/float(image.cols),float(land[4][1]*112.0)/float(image.rows)}
416 };
417 cv::Mat src(5,2,CV_32FC1,default1);
418 memcpy(src.data, default1, 2 * 5 * sizeof(float));
419 cv::Mat dst(5,2,CV_32FC1,lands);
420 memcpy(dst.data, lands, 2 * 5 * sizeof(float));
421 cv::Mat M = similarTransform(dst, src);
422 float M_[2][3]={
423 {M.at<float>(0,0),M.at<float>(0,1),M.at<float>(0,2)},
424 {M.at<float>(1,0),M.at<float>(1,1),M.at<float>(1,2)},
425 };
426
427 cv::Mat M__(2,3,CV_32FC1,M_);
428 cv::Mat align_image;
429 cv::warpAffine(out,align_image,M__,Size(112, 112));
430 return align_image;
431 }
432
433 double FaceRecognize::getMold(const vector<double>& vec)
434 {
435 int n = vec.size();
436 double sum = 0.0;
437 for (int i = 0; i < n; ++i)
438 sum += vec[i] * vec[i];
439 return sqrt(sum);
440 }
441
442 double FaceRecognize::cos_distance(const vector<double>& base, const vector<double>& target)
443 {
444 int n = base.size();
445 assert(n == target.size());
446 double tmp = 0.0;
447 for (int i = 0; i < n; ++i)
448 tmp += base[i] * target[i];
449 double simility = tmp / (getMold(base)*getMold(target));
450 return simility;
451 }
452
453 double FaceRecognize::get_samilar(Mat image1,Mat image2){
454 cv::Mat blob1 = cv::dnn::blobFromImage(image1,1.0/127.5,Size(112,112),Scalar(127.5,127.5,127.5),true); // 由图片加载数据 这里还可以进行缩放、归一化等预处理
455 rec_net.setInput(blob1); // 设置模型输入
456 std::vector<cv::Mat> rec_netOutputImg1;
457 rec_net.forward(rec_netOutputImg1,rec_net.getUnconnectedOutLayersNames()); // 推理出结果
458 cv::Mat blob2 = cv::dnn::blobFromImage(image2,1.0/127.5,Size(112,112),Scalar(127.5,127.5,127.5),true); // 由图片加载数据 这里还可以进行缩放、归一化等预处理
459 rec_net.setInput(blob2); // 设置模型输入
460 std::vector<cv::Mat> rec_netOutputImg2;
461 rec_net.forward(rec_netOutputImg2,rec_net.getUnconnectedOutLayersNames()); // 推理出结果
462 cv::Mat feature1=rec_netOutputImg1[0].reshape(1,512);
463 cv::Mat feature2=rec_netOutputImg2[0].reshape(1,512);
464 vector<double> v1,v2;
465 for(int i=0;i<feature1.rows;i++){
466 v1.push_back((double)feature1.at<float>(i,0));
467 v2.push_back((double)feature2.at<float>(i,0));
468 }
469 double cos_score=cos_distance(v1,v2);
470 return cos_score;
471 }
472
473
474 //整体pipeline
475 bool FaceRecognize::face_recognize(string image1_path,string image2_path){
476 bool result=false;
477 cv::Mat image1=cv::imread(image1_path);
478 cv::Mat image2=cv::imread(image2_path);
479 vector<Bbox> box1=detect_image(image1);
480 vector<Bbox> box2=detect_image(image2);
481
482 int max_box1=0,max_box2=0;
483 double max_area1=0,max_area2=0;
484 for(int i=0;i<box1.size();++i){
485 double tmp_area1=(box1[i].ymax-box1[i].ymin)*(box1[i].xmax-box1[i].xmin);
486 if(tmp_area1>max_area1){
487 max_box1=i;
488 max_area1=tmp_area1;
489 }
490 }
491 Rect rect1=Rect(box1[max_box1].xmin,box1[max_box1].ymin,box1[max_box1].xmax-box1[max_box1].xmin,box1[max_box1].ymax-box1[max_box1].ymin);
492 Mat face_area1=image1(rect1);
493 vector<vector<float>> landms1=detect_image_landmarks(face_area1);
494 vector<vector<float>> land1={
495 {float(landms1[104][0]),float(landms1[104][1])},
496 {float(landms1[105][0]),float(landms1[105][1])},
497 {float(landms1[46][0]),float(landms1[46][1])},
498 {float(landms1[84][0]),float(landms1[84][1])},
499 {float(landms1[90][0]),float(landms1[90][1])}
500 };
501 Mat align_resize_image1=preprocess_face(face_area1,land1);
502 for(int j=0;j<box2.size();++j){
503 Rect rect2=Rect(box2[max_box2].xmin,box2[max_box2].ymin,box2[max_box2].xmax-box2[max_box2].xmin,box2[max_box2].ymax-box2[max_box2].ymin);
504 Mat face_area2=image2(rect2);
505 vector<vector<float>> landms2=detect_image_landmarks(face_area2);
506 vector<vector<float>> land2={
507 {float(landms2[104][0]),float(landms2[104][1])},
508 {float(landms2[105][0]),float(landms2[105][1])},
509 {float(landms2[46][0]),float(landms2[46][1])},
510 {float(landms2[84][0]),float(landms2[84][1])},
511 {float(landms2[90][0]),float(landms2[90][1])}
512 };
513 Mat align_resize_image2=preprocess_face(face_area2,land2);
514 double samilar_score=get_samilar(align_resize_image1,align_resize_image2);
515 if(samilar_score>face_recongnize_thr){
516 result=true;
517 }
518 }
519 return result;
520 }
521
522 bool FaceRecognize::face_recognize_image(Mat image1,Mat image2){
523 bool result=false;
524 vector<Bbox> box1=detect_image(image1);
525 vector<Bbox> box2=detect_image(image2);
526
527 int max_box1=0,max_box2=0;
528 double max_area1=0,max_area2=0;
529 for(int i=0;i<box1.size();++i){
530 double tmp_area1=(box1[i].ymax-box1[i].ymin)*(box1[i].xmax-box1[i].xmin);
531 if(tmp_area1>max_area1){
532 max_box1=i;
533 max_area1=tmp_area1;
534 }
535 }
536 Rect rect1=Rect(box1[max_box1].xmin,box1[max_box1].ymin,box1[max_box1].xmax-box1[max_box1].xmin,box1[max_box1].ymax-box1[max_box1].ymin);
537 Mat face_area1=image1(rect1);
538 vector<vector<float>> landms1=detect_image_landmarks(face_area1);
539 vector<vector<float>> land1={
540 {float(landms1[104][0]),float(landms1[104][1])},
541 {float(landms1[105][0]),float(landms1[105][1])},
542 {float(landms1[46][0]),float(landms1[46][1])},
543 {float(landms1[84][0]),float(landms1[84][1])},
544 {float(landms1[90][0]),float(landms1[90][1])}
545 };
546 Mat align_resize_image1=preprocess_face(face_area1,land1);
547 for(int j=0;j<box2.size();++j){
548 Rect rect2=Rect(box2[max_box2].xmin,box2[max_box2].ymin,box2[max_box2].xmax-box2[max_box2].xmin,box2[max_box2].ymax-box2[max_box2].ymin);
549 Mat face_area2=image2(rect2);
550 vector<vector<float>> landms2=detect_image_landmarks(face_area2);
551 vector<vector<float>> land2={
552 {float(landms2[104][0]),float(landms2[104][1])},
553 {float(landms2[105][0]),float(landms2[105][1])},
554 {float(landms2[46][0]),float(landms2[46][1])},
555 {float(landms2[84][0]),float(landms2[84][1])},
556 {float(landms2[90][0]),float(landms2[90][1])}
557 };
558 Mat align_resize_image2=preprocess_face(face_area2,land2);
559 double samilar_score=get_samilar(align_resize_image1,align_resize_image2);
560 if(samilar_score>face_recongnize_thr){
561 result=true;
562 }
563 }
564 return result;
565 }
...\ No newline at end of file ...\ No newline at end of file
1 #ifndef FACERECOGNIZE_H
2 #define FACERECOGNIZE_H
3 #include<opencv2/opencv.hpp>
4
5 using namespace std;
6 using namespace cv;
7 struct Bbox{
8 float xmin;
9 float ymin;
10 float xmax;
11 float ymax;
12 float score;
13 float x1;
14 float y1;
15 float x2;
16 float y2;
17 float x3;
18 float y3;
19 float x4;
20 float y4;
21 float x5;
22 float y5;
23 };
24 class FaceRecognize{
25
26 private:
27 //是否使用gpu?
28 bool use_gpu=true;
29
30 //人脸检测
31 vector<float> input_size={640,640};
32 vector<float> variances={0.1,0.2};
33 vector<float> mean_data={104,117,128};
34 float confidence_threshold = 0.5; //人脸检测阈值
35 float keep_top_k = 100;
36 float vis_threshold = 0.5;
37 float nms_threshold = 0.4;
38 float resize_scale = 1.0;
39 bool is_bbox_process=true; //人脸外扩
40
41 //人脸识别
42 double face_recongnize_thr = 0.2; //人脸相似度阈值
43 cv::dnn::Net det_net,landm_net,rec_net;
44
45
46 public:
47 FaceRecognize();
48 FaceRecognize(string face_det_model_path,string face_landm_model_path,string face_rec_model_path){
49 det_net = cv::dnn::readNetFromONNX(face_det_model_path);
50 landm_net = cv::dnn::readNetFromONNX(face_landm_model_path);
51 rec_net = cv::dnn::readNetFromONNX(face_rec_model_path);
52 if(use_gpu){
53 det_net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
54 det_net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
55 landm_net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
56 landm_net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
57 rec_net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
58 rec_net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
59 }
60
61 }
62 //人脸检测部分
63 vector<vector<float>> priorBox(vector<float> image_size);
64 vector<Bbox> decode(vector<vector<float>> loc,vector<vector<float>> score,vector<vector<float>>pre,vector<vector<float>> priors,vector<float> variances);
65 void nms_cpu(std::vector<Bbox> &bboxes, float threshold);
66 vector<vector<float>> mat2vector(Mat mat);
67 vector<Bbox> select_score(vector<Bbox> bboxes,float threshold,float w_r,float h_r);
68 vector<Bbox> bbox_process(vector<Bbox> bboxes,float frame_w,float frame_h);
69 vector<Bbox> detect(string image_path);
70 vector<Bbox> detect_image(Mat image);
71
72
73 //人脸关键点部分
74 vector<vector<float>> detect_landmarks(string image_path);
75 vector<vector<float>> detect_image_landmarks(cv::Mat image);
76
77
78 //人脸识部分
79 cv::Mat meanAxis0(const cv::Mat &src);
80 cv::Mat elementwiseMinus(const cv::Mat &A,const cv::Mat &B);
81 cv::Mat varAxis0(const cv::Mat &src);
82 int MatrixRank(cv::Mat M);
83 cv::Mat similarTransform(cv::Mat src,cv::Mat dst);
84 Mat preprocess_face(Mat image,vector<vector<float>> land);
85 double getMold(const vector<double>& vec);
86 double cos_distance(const vector<double>& base, const vector<double>& target);
87 double get_samilar(Mat image1,Mat image2);
88
89
90 //整体
91 bool face_recognize(string image1_path,string image2_path);
92 bool face_recognize_image(Mat image1,Mat image2);
93 };
94
95
96 #endif
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
No preview for this file type
1 #include"facerecognize.h"
2 #include "ctime"
3
4 int main(){
5 FaceRecognize face_rec=FaceRecognize("/home/situ/qfs/sdk_project/mobile_face_recognize/det_face_retina_torch_1.4_v0.0.2.onnx","/home/situ/qfs/sdk_project/mobile_face_recognize/det_landmarks_106_v0.0.1.onnx","/home/situ/qfs/sdk_project/mobile_face_recognize/ms1mv3_r18.onnx");
6 clock_t start, end;
7 cv::Mat image1=cv::imread("/data/face_recognize/pipeline_test/59297ec0094211ecaf3d00163e514671/310faceImageContent163029410817774.jpg");
8 cv::Mat image2=cv::imread("/data/face_recognize/pipeline_test/59297ec0094211ecaf3d00163e514671/310cardImageContent163029410836583.jpg");
9 cout<<"start"<<endl;
10 start = clock();
11 bool result=face_rec.face_recognize_image(image1,image2);
12 end = clock();
13 double elapsedTime = static_cast<double>(end-start) / CLOCKS_PER_SEC ;
14
15 printf("PROCESSING TIME: %f",elapsedTime);
16
17 }
This file is too large to display.
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!