300W数据集测试MTCNN的landmark效果代码

来源:互联网 发布:ubuntu安装python2.7 编辑:程序博客网 时间:2024/06/05 07:33

300W数据集测试MTCNN的landmark效果,用提取其中afw数据集337张图片的预测关键点并写入到txt中,再用测试程序和标注landmark做对比。

处理得到的预测landmark格式如下:
1051618982(图片名)
1(landmark个数)
543 267 643 268 594 322 542 359 643 360
111076519
2
1095 624 1161 635 1125 668 1084 696 1146 706
1172 764 1238 767 1211 806 1168 830 1233 833
1130084326

程序如下:

#include "network.h"#include "mtcnn.h"#include <time.h>#include <fstream>#include <opencv2/opencv.hpp>#pragma comment(lib, "libopenblas.dll.a")using namespace cv;std::vector<std::string> split(std::string& str, std::string& pattern);void str2int(int &int_temp, const string &string_temp);int main(){//因为执行目录被设置到openblas/x64下了,保证dll能正常载入,这时候图片路径就相对要提上去2级//Mat im = imread("../../test10.jpg");int i = 0;string img_dir = "E:/face_alignment/data/300W_test_5points/afw/";string name, s="_";ifstream infile;ofstream outfile;infile.open("E:/face_alignment/data/300W_test_5points/afw_mtcnn_test_V2_2.txt");outfile.open("E:/face_alignment/data/300W_test_5points/MTCNN_V2_2_test/afw_test.txt");while (infile){infile >> name;vector<string> result = split(name, s);cout << i << endl;i++;//cout << "name: " << result[0] << " s: " << result[1] << endl;string shot_name = result[0];int decide;str2int(decide, result[1]);if (decide == 1){string image_name = name + ".jpg";outfile << shot_name  << endl;string image_name_dir = img_dir + image_name;cout << image_name_dir << endl;Mat im = imread(image_name_dir);vector<vector<Point2f>> key_points;mtcnn find(im.cols, im.rows);vector<Rect> objs = find.detectObject(im, key_points);//outfile << objs.size() << endl;for (int i = 0; i < objs.size(); ++i){rectangle(im, objs[i], Scalar(0, 255), 2);//outfile << objs[i].x << " " << objs[i].y << " " << objs[i].width << " " << objs[i].height << endl;}//cout << "num of key_points: " << key_points.size() << endl;outfile << key_points.size() << endl;for (int i = 0; i < key_points.size(); i++){for (int j = 0; j < key_points[i].size(); j++){cv::circle(im, key_points[i][j], 1, cv::Scalar(255, 255, 0), 2);outfile << key_points[i][j].x << " " << key_points[i][j].y << " ";}outfile << endl;}string outdir = "E:/face_alignment/data/300W_test_5points/MTCNN_V2_2_test/afw/";string out_image = outdir + shot_name + ".jpg";imwrite(out_image, im);//imshow("demo", im);//waitKey(0);}}infile.close();outfile.close();return 0;}//字符串分割函数   std::vector<std::string> split(std::string& str, std::string& pattern){std::string::size_type pos;std::vector<std::string> result;//str += pattern;//扩展字符串以方便操作     int size = str.size();pos = str.find(pattern, 0);if (pos<size) {std::string s1 = str.substr(0, pos);std::string s2 = str.substr(pos + 1, size - 1);result.push_back(s1);result.push_back(s2);}return result;}void str2int(int &int_temp, const string &string_temp){stringstream stream(string_temp);stream >> int_temp;}

用我们自己得到的预测txt,与作者提供的标注pts文件进行计算。  算5个landmark的欧式距离之和,除以左上角和右下角欧式距离,除以5。

#include <iostream>  #include <stdlib.h>  #include <fstream>  #include <sstream>  #include <string>  #include <vector>  #include <opencv2/opencv.hpp>    using namespace cv;using namespace std;std::vector<std::string> split(std::string& str, std::string& pattern);void str2int(int &int_temp, const string &string_temp);float computer_error(vector<float> pts_gt, vector<vector<float>> pts_pre);int main(){int count = 0, pos = 0;float acc, thread=0.1;string name_list, s = "_";string pts_dir = "E:/face_alignment/data/300W_test_5points/afw/";ifstream infile_list, infile_pre;infile_list.open("E:/face_alignment/data/300W_test_5points/afw_mtcnn_test_V1.txt");infile_pre.open("E:/face_alignment/data/300W_test_5points/MTCNN_V1_test/afw_test.txt");infile_list >> name_list;while (infile_pre){string name_pre;int num_pre;vector<vector<float> > pts_pre;infile_pre >> name_pre;infile_pre >> num_pre;pts_pre.resize(num_pre);for (int i = 0; i < num_pre; i++){pts_pre[i].resize(10);}for (int j = 0; j < num_pre; j++){infile_pre >> pts_pre[j][0] >> pts_pre[j][1] >> pts_pre[j][2] >> pts_pre[j][3] >> pts_pre[j][4] >> pts_pre[j][5] >> pts_pre[j][6] >> pts_pre[j][7] >> pts_pre[j][8] >> pts_pre[j][9];}//for (int i = 0; i < num_pre; i++)//{//for (int j = 0; j < 10; j++)//{//cout << pts_pre[i][j] << " ";//}//cout << endl;//}// read gt filewhile (infile_list){vector<string> result = split(name_list, s);string name_gt = result[0];if (name_gt.compare(name_pre) == 0){count++;cout << count << endl;vector<float> pts_gt;pts_gt.resize(10);string pts_dir_name = pts_dir + name_list + ".pts";ifstream infile_pts;infile_pts.open(pts_dir_name);string ss;int yy;infile_pts >> ss >> yy;infile_pts >> ss >> yy;infile_pts >> ss;for (int i = 0; i < 5; i++){infile_pts >> pts_gt[i*2] >> pts_gt[i*2+1];}infile_pts.close();float error = computer_error(pts_gt, pts_pre);error = error / 5.0;if (error <= thread)pos++;cout << error << " " << endl;infile_list >> name_list;//cout << name_list << endl;}elsebreak;}}acc = float(pos) / float(count);cout << "accury: " << acc << endl;infile_list.close();infile_pre.close();}// computer alinment lossfloat computer_error(vector<float> pts_gt, vector<vector<float>> pts_pre){if (pts_pre.size() == 0)return 10;float RMSE, d_outer, align_loss;d_outer = sqrt((pts_gt[0] - pts_gt[8])*(pts_gt[0] - pts_gt[8]) + (pts_gt[1] - pts_gt[9])*(pts_gt[1] - pts_gt[9]));for (int i = 0; i < pts_pre.size(); i++){RMSE = 0;for (int j = 0; j < 5; j++){RMSE += sqrt((pts_gt[2 * j] - pts_pre[i][2 * j])*(pts_gt[2 * j] - pts_pre[i][2 * j]) + (pts_gt[2 * j + 1] - pts_pre[i][2 * j + 1])*(pts_gt[2 * j + 1] - pts_pre[i][2 * j + 1]));}RMSE = RMSE / d_outer;if (i == 0){align_loss = RMSE;}else{if (align_loss > RMSE)align_loss = RMSE;}}return align_loss;}//字符串分割函数   std::vector<std::string> split(std::string& str, std::string& pattern){std::string::size_type pos;std::vector<std::string> result;//str += pattern;//扩展字符串以方便操作     int size = str.size();pos = str.find(pattern, 0);if (pos<size) {std::string s1 = str.substr(0, pos);std::string s2 = str.substr(pos + 1, size - 1);result.push_back(s1);result.push_back(s2);}return result;}void str2int(int &int_temp, const string &string_temp){stringstream stream(string_temp);stream >> int_temp;}