// FaceSampling_1.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <io.h>
#include <fstream>
#include <locale.h>
#include <stdlib.h>
#include <cstdlib>
#include <string.h>
#include <direct.h>
#include <windows.h>
#include "FaceAlign.h"
#define LANDMARK_SIZE 68
using namespace std;
using namespace cv;
struct faceInfo
{
string fileName;
vector<Point> Pts;
double posDiff;
};
void getFiles(string path, vector<string>& files)
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))//if it's a directory,then iterate.Or add it to the list
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
getFiles(p.assign(path).append("\\").append(fileinfo.name), files);//recursive
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
void getFilesNorecurs(string path, vector<string>& files)//push all the files under the path into the "files" vector
{
//文件句柄
long hFile = 0;// the return type of _findfirst is long
//文件信息
struct _finddata_t fileinfo;//_finddata_t is a struct to store the file info
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)//Find all the files under this folder.If failed,return -1.
{
do
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));//assign is substitute
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
void cooReduct(vector<Point> &landmarkPointVector)
{
int tmpDisBase_x = landmarkPointVector[27].x;
int tmpDisBase_y = landmarkPointVector[27].y;
for (size_t i = 0; i < landmarkPointVector.size(); i++)
{
landmarkPointVector[i].x = landmarkPointVector[i].x - tmpDisBase_x;
landmarkPointVector[i].y = landmarkPointVector[i].y - tmpDisBase_y;
}
//still I think we should set Point[27] to (0,0)
//landmarkPointVector[27].x = 0;
//landmarkPointVector[27].y = 0;
}
void avgLandmarkFaceGet(vector<vector<Point>> seriesLandmarkFace, vector<Point> &avgLandmarkFace)
{
Point tmpPoint(0, 0);
for (size_t i = 0; i < LANDMARK_SIZE; i++)
{
avgLandmarkFace.push_back(tmpPoint);
}
for (size_t i = 0; i < seriesLandmarkFace.size(); i++)
{
for (size_t j = 0; j < seriesLandmarkFace[i].size(); j++)
{
avgLandmarkFace[j].x += seriesLandmarkFace[i][j].x;
avgLandmarkFace[j].y += seriesLandmarkFace[i][j].y;
}
}
for (size_t i = 0; i < avgLandmarkFace.size(); i++)
{
avgLandmarkFace[i].x = int(avgLandmarkFace[i].x / int(seriesLandmarkFace.size()));
avgLandmarkFace[i].y = avgLandmarkFace[i].y / int(seriesLandmarkFace.size());
}
}
int m_pow(int numOne)
{
return numOne * numOne;
}
double diffCal(vector<Point> pt1, vector<Point> pt2)
{
//size_t x_tmp, y_tmp;
double ans = 0;
for (size_t i = 0; i <LANDMARK_SIZE; i++)
{
//tmpAllNum = 0;
int x_tmp = m_pow((pt1[i].x - pt2[i].x));
int y_tmp = m_pow((pt1[i].y - pt2[i].y));
ans += sqrt((x_tmp + y_tmp) * 1.00);
//varianceVector[i] = tmpAllNum;
}
ans = ans / LANDMARK_SIZE;
return ans;
}
void posDiff_cal_n(vector<faceInfo> &seriesFace)
{
}
void posDiff_cal(vector<faceInfo> &seriesFace)
{
size_t ss = seriesFace.size();
for (size_t i = 0; i < ss; i++)
{
if (i == 0)
continue;
seriesFace[i].posDiff = diffCal(seriesFace[i].Pts, seriesFace[i - 1].Pts);
}
}
bool cmpVec(faceInfo a, faceInfo b)
{
return a.posDiff > b.posDiff;
}
void sortbyDis(vector<faceInfo> &seriesFace)
{
sort(seriesFace.begin(), seriesFace.end(), cmpVec);
}
vector<string> &split_s(const string &str, char delim, vector<string> &elems, bool skip_empty = true) {
istringstream iss(str);
for (string item; getline(iss, item, delim); )
if (skip_empty && item.empty()) continue;
else elems.push_back(item);
return elems;
}
LPCWSTR stringToLPCWSTR(std::string orig)
{
size_t origsize = orig.length() + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
return wcstring;
}
int main()
{
string model_txtfile = "data1.txt";
string model_datfile = "data2.dat";
//string local_file = "D:\\11111";
string local_file = "D:\\8.10test\\opt\\workspace\\0717-0720\\0719\\3k\\yantian_pic";
string target_file = "D:\\22222";
Mat frame;
vector<Mat> vecFace;
FaceAlign faceAlign;
vector<string> dirname;
vector<string> folderName;
vector<vector<string>> file_vec;
vector<Rect> faceRec;
vector<vector<Point>> facePts;
vector<Point> avgLandmarkFace;
vector<string> haveFace;
vector<faceInfo> Piclist;
string series_id;
string con_or_stop;
//char* tmpid;
getFilesNorecurs(local_file, dirname);
for (size_t i = 0; i < dirname.size(); i++)
{
string tmpstr = dirname[i];
if (tmpstr[tmpstr.size() - 1] == '.')
continue;
cout << dirname[i] << endl;
folderName.push_back(dirname[i]);
}
for (size_t i = 0; i < folderName.size(); i++)
{
vector<string> files;
files.clear();
getFiles(folderName[i], files);
file_vec.push_back(files);
}
const char *model_t = model_txtfile.c_str();
const char *model_d = model_datfile.c_str();
if (!(faceAlign.LoadModel(model_t, model_d)))
{
cout << "Can not load the model." << endl;
//system("PAUSE");
return 0;
}
/*for (size_t i = 0; i < folderName.size(); i++)
{
vector<string> files;
files.clear();
getFiles(folderName[i], files);
file_vec.push_back(files);
}*/
vector<vector<string>>::iterator f_trav;
size_t folder_num = 0;
string source_path;
string target_path;
for (f_trav = file_vec.begin(); f_trav != file_vec.end(); f_trav++)
{
source_path = folderName[folder_num];
vector<string> res;
split_s(source_path, '\\', res);
target_path = target_file + '\\' + res[res.size() - 1];//son folder name
if (_access(target_path.c_str(), 0) == -1)
{
cout << "folder doesn't exit" << endl;
_mkdir(target_path.c_str());
}
else
{
cout << "folder exited" << endl;
}
cout << target_path << endl;
//char* des = (char*)target_path.c_str();
//system("PAUSE");
cout << (*f_trav).size() << endl;
//system("PAUSE");
vector<string> pic_list = *f_trav;
faceRec.clear();
facePts.clear();
haveFace.clear();
Piclist.clear();
con_or_stop = "jiaoban";
for (size_t i = 0; i < pic_list.size(); i++)//add pics of the same person to a vector
{
//cout << pic_list[i] << endl;
if (strcmp(pic_list[i].substr(pic_list[i].size() - 4, pic_list[i].size() - 1).c_str(), ".jpg"))
{
continue;
}
series_id = pic_list[i].substr(pic_list[i].size() - 15, 5);
/* only the pics with the same id belong to the same series.
Then u put the pics into a tmp vector.**********************
When it's over.Process it.********************************/
if (strcmp(series_id.c_str(), con_or_stop.c_str()) == 0)
{
//cout << "The Same Sequence" << endl;
frame = cv::imread(pic_list[i], 1);
if (frame.empty())
{
cout << "can not load image" << endl;
system("PAUSE");
return 0;
}
if (!(faceAlign.AlignFace(frame, vecFace)))//vec face is a vector of mat
{
cout << "Alignment Face is not success." << endl;
system("PAUSE");
return 0;
}
size_t x1 = faceAlign.m_faceRect.size();//"1" means only one face in this pic
size_t x2 = faceAlign.m_finalPts.size();//"1" means only one series of landmarks
//cout << x1 << " " << x2 << endl;
if (x1 != 1 && x2 != 1)
continue;
//for (size_t i = 0; i<faceAlign.m_faceRect.size(); i++)
//faceRec.push_back(faceAlign.m_faceRect[i]);
haveFace.push_back(pic_list[i]);
for (size_t i = 0; i<faceAlign.m_faceRect.size(); i++)
faceRec.push_back(faceAlign.m_faceRect[i]);
vector<vector<Point>>::iterator mt;
for (mt = faceAlign.m_finalPts.begin(); mt != faceAlign.m_finalPts.end(); mt++)
facePts.push_back(*mt);
}
else
{
string record = con_or_stop;
con_or_stop = series_id;
cout << "diffffffffffffffffff" << endl;
//for (size_t i = 0; i < series_id.size(); i++)
//con_or_stop[i] = series_id[i];
cout << con_or_stop << endl;
size_t xx = faceRec.size();
size_t yy = facePts.size();
size_t zz = haveFace.size();
if (xx != yy || yy != zz)
{
cout << "Errors occur while getting landmarks" << endl;
system("PAUSE");
return 0;
}
if (xx == 0 || yy == 0 || zz == 0)
{
cout << "No Face Detected" << endl;
//system("PAUSE");
continue;
}
cout << record << " start to process the vec" << endl;
//system("PAUSE");
for (size_t trackingLandmarksCount = 0; trackingLandmarksCount < yy; trackingLandmarksCount++)
{
cooReduct(facePts[trackingLandmarksCount]);
}
for (size_t i = 0; i < yy; i++)
{
faceInfo tmp;
tmp.fileName = haveFace[i];
tmp.Pts.clear();
tmp.Pts.assign(facePts[i].begin(), facePts[i].end());
tmp.posDiff = 0;
Piclist.push_back(tmp);
}
cout << "Piclist size:" << " " <<Piclist.size() << endl;
posDiff_cal(Piclist);
sortbyDis(Piclist);
for (size_t i = 0; i < Piclist.size() / 5; i++)
{
//cout << Piclist[i].fileName << endl;
string src = Piclist[i].fileName;
cv::Mat tmpface = cv::imread(Piclist[i].fileName);
source_path = Piclist[i].fileName;
vector<string> res;
res.clear();
split_s(source_path, '\\', res);
string tar = target_path;
tar = tar + '\\' + res[res.size() - 1];
cout << tar << endl;
cv::imwrite(tar, tmpface);
//system("PAUSE");
}
faceRec.clear();
facePts.clear();
haveFace.clear();
Piclist.clear();
//system("PAUSE");
}
//cout << pic_list[i] << endl;
//namedWindow("mine", 1);
//imshow("mine", frame);
//waitKey(1);
//system("PAUSE");
}
system("PAUSE");
}
system("PAUSE");
return 0;
}