Commit 7249ab0a authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #129 from avdmitry/datasets_enh_adience

datasets module: enhancements
parents 9a0cc980 f04f1911
...@@ -10,7 +10,7 @@ _`"HMDB: A Large Human Motion Database"`: http://serre-lab.clps.brown.edu/resour ...@@ -10,7 +10,7 @@ _`"HMDB: A Large Human Motion Database"`: http://serre-lab.clps.brown.edu/resour
1. From link above download dataset files: hmdb51_org.rar & test_train_splits.rar. 1. From link above download dataset files: hmdb51_org.rar & test_train_splits.rar.
2. Unpack them. 2. Unpack them. Unpack all archives from directory: hmdb51_org/ and remove them.
3. To load data run: ./opencv/build/bin/example_datasets_ar_hmdb -p=/home/user/path_to_unpacked_folders/ 3. To load data run: ./opencv/build/bin/example_datasets_ar_hmdb -p=/home/user/path_to_unpacked_folders/
...@@ -25,7 +25,7 @@ To run this benchmark execute: ...@@ -25,7 +25,7 @@ To run this benchmark execute:
./opencv/build/bin/example_datasets_ar_hmdb_benchmark -p=/home/user/path_to_unpacked_folders/ ./opencv/build/bin/example_datasets_ar_hmdb_benchmark -p=/home/user/path_to_unpacked_folders/
(precomputed features should be unpacked in the same folder: /home/user/path_to_unpacked_folders/hmdb51_org_stips/) (precomputed features should be unpacked in the same folder: /home/user/path_to_unpacked_folders/hmdb51_org_stips/. Also unpack all archives from directory: hmdb51_org_stips/ and remove them.)
**References:** **References:**
......
...@@ -56,8 +56,9 @@ namespace datasets ...@@ -56,8 +56,9 @@ namespace datasets
struct AR_hmdbObj : public Object struct AR_hmdbObj : public Object
{ {
int id;
std::string name; std::string name;
std::vector<std::string> videoNames; std::string videoName;
}; };
class CV_EXPORTS AR_hmdb : public Dataset class CV_EXPORTS AR_hmdb : public Dataset
......
...@@ -74,15 +74,14 @@ int main(int argc, char *argv[]) ...@@ -74,15 +74,14 @@ int main(int argc, char *argv[])
// And its size. // And its size.
int numSplits = dataset->getNumSplits(); int numSplits = dataset->getNumSplits();
printf("splits number: %u\n", numSplits); printf("splits number: %u\n", numSplits);
printf("train 1 size: %u\n", (unsigned int)dataset->getTrain(1).size());
printf("test 1 size: %u\n", (unsigned int)dataset->getTest(1).size());
AR_hmdbObj *example = static_cast<AR_hmdbObj *>(dataset->getTrain(1)[0].get()); AR_hmdbObj *example = static_cast<AR_hmdbObj *>(dataset->getTrain(1)[0].get());
printf("name: %s\n", example->name.c_str()); printf("first image:\n");
vector<string> &videoNames = example->videoNames; printf("action id: %u\n", example->id);
printf("size: %u\n", (unsigned int)videoNames.size()); printf("action: %s\n", example->name.c_str());
for (vector<string>::iterator it=videoNames.begin(); it!=videoNames.end(); ++it) printf("file: %s\n", example->videoName.c_str());
{
printf("%s\n", (*it).c_str());
}
return 0; return 0;
} }
...@@ -58,23 +58,6 @@ using namespace cv::datasets; ...@@ -58,23 +58,6 @@ using namespace cv::datasets;
using namespace cv::flann; using namespace cv::flann;
using namespace cv::ml; using namespace cv::ml;
unsigned int getNumFiles(vector< Ptr<Object> > &curr);
unsigned int getNumFiles(vector< Ptr<Object> > &curr)
{
unsigned int numFiles = 0;
for (unsigned int i=0; i<curr.size(); ++i)
{
AR_hmdbObj *example = static_cast<AR_hmdbObj *>(curr[i].get());
vector<string> &videoNames = example->videoNames;
for (vector<string>::iterator it=videoNames.begin(); it!=videoNames.end(); ++it)
{
numFiles++;
}
}
return numFiles;
}
void fillData(const string &path, vector< Ptr<Object> > &curr, Index &flann_index, Mat1f &data, Mat1i &labels); void fillData(const string &path, vector< Ptr<Object> > &curr, Index &flann_index, Mat1f &data, Mat1i &labels);
void fillData(const string &path, vector< Ptr<Object> > &curr, Index &flann_index, Mat1f &data, Mat1i &labels) void fillData(const string &path, vector< Ptr<Object> > &curr, Index &flann_index, Mat1f &data, Mat1i &labels)
{ {
...@@ -87,36 +70,31 @@ void fillData(const string &path, vector< Ptr<Object> > &curr, Index &flann_inde ...@@ -87,36 +70,31 @@ void fillData(const string &path, vector< Ptr<Object> > &curr, Index &flann_inde
for (unsigned int i=0; i<curr.size(); ++i) for (unsigned int i=0; i<curr.size(); ++i)
{ {
AR_hmdbObj *example = static_cast<AR_hmdbObj *>(curr[i].get()); AR_hmdbObj *example = static_cast<AR_hmdbObj *>(curr[i].get());
vector<string> &videoNames = example->videoNames; string featuresFullPath = path + "hmdb51_org_stips/" + example->name + "/" + example->videoName + ".txt";
for (vector<string>::iterator it=videoNames.begin(); it!=videoNames.end(); ++it)
ifstream infile(featuresFullPath.c_str());
string line;
// skip header
for (unsigned int j=0; j<3; ++j)
{ {
string featuresFile = *it + ".txt"; getline(infile, line);
string featuresFullPath = path + "hmdb51_org_stips/" + example->name + "/" + featuresFile; }
while (getline(infile, line))
{
// 7 skip, hog+hof: 72+90 read
vector<string> elems;
split(line, elems, '\t');
ifstream infile(featuresFullPath.c_str()); for (unsigned int j=0; j<descriptorNum; ++j)
string line;
// skip header
for (unsigned int j=0; j<3; ++j)
{ {
getline(infile, line); sample(0, j) = (float)atof(elems[j+7].c_str());
} }
while (getline(infile, line))
{
// 7 skip, hog+hof: 72+90 read
vector<string> elems;
split(line, elems, '\t');
for (unsigned int j=0; j<descriptorNum; ++j) flann_index.knnSearch(sample, nresps, dists, 1, SearchParams());
{ data(numFiles, nresps(0, 0)) ++;
sample(0, j) = (float)atof(elems[j+7].c_str());
}
flann_index.knnSearch(sample, nresps, dists, 1, SearchParams());
data(numFiles, nresps(0, 0)) ++;
}
labels(numFiles, 0) = i;
numFiles++;
} }
labels(numFiles, 0) = example->id;
numFiles++;
} }
} }
...@@ -148,43 +126,35 @@ int main(int argc, char *argv[]) ...@@ -148,43 +126,35 @@ int main(int argc, char *argv[])
vector<double> res; vector<double> res;
for (int currSplit=0; currSplit<numSplits; ++currSplit) for (int currSplit=0; currSplit<numSplits; ++currSplit)
{ {
Mat1f samples(sampleNum, descriptorNum); Mat1f samples(sampleNum, descriptorNum);
unsigned int currSample = 0; unsigned int currSample = 0;
vector< Ptr<Object> > &curr = dataset->getTrain(currSplit); vector< Ptr<Object> > &curr = dataset->getTrain(currSplit);
unsigned int numTrainFiles = getNumFiles(curr);
unsigned int numFeatures = 0; unsigned int numFeatures = 0;
for (unsigned int i=0; i<curr.size(); ++i) for (unsigned int i=0; i<curr.size(); ++i)
{ {
AR_hmdbObj *example = static_cast<AR_hmdbObj *>(curr[i].get()); AR_hmdbObj *example = static_cast<AR_hmdbObj *>(curr[i].get());
vector<string> &videoNames = example->videoNames; string featuresFullPath = path + "hmdb51_org_stips/" + example->name + "/" + example->videoName + ".txt";
for (vector<string>::iterator it=videoNames.begin(); it!=videoNames.end(); ++it) ifstream infile(featuresFullPath.c_str());
string line;
// skip header
for (unsigned int j=0; j<3; ++j)
{ {
string featuresFile = *it + ".txt"; getline(infile, line);
string featuresFullPath = path + "hmdb51_org_stips/" + example->name + "/" + featuresFile; }
while (getline(infile, line))
ifstream infile(featuresFullPath.c_str()); {
string line; numFeatures++;
// skip header if (currSample < sampleNum)
for (unsigned int j=0; j<3; ++j)
{
getline(infile, line);
}
while (getline(infile, line))
{ {
numFeatures++; // 7 skip, hog+hof: 72+90 read
if (currSample < sampleNum) vector<string> elems;
{ split(line, elems, '\t');
// 7 skip, hog+hof: 72+90 read
vector<string> elems;
split(line, elems, '\t');
for (unsigned int j=0; j<descriptorNum; ++j) for (unsigned int j=0; j<descriptorNum; ++j)
{ {
samples(currSample, j) = (float)atof(elems[j+7].c_str()); samples(currSample, j) = (float)atof(elems[j+7].c_str());
}
currSample++;
} }
currSample++;
} }
} }
} }
...@@ -202,6 +172,7 @@ int main(int argc, char *argv[]) ...@@ -202,6 +172,7 @@ int main(int argc, char *argv[])
printf("resulted clusters number: %u\n", resultClusters); printf("resulted clusters number: %u\n", resultClusters);
unsigned int numTrainFiles = curr.size();
Mat1f trainData(numTrainFiles, resultClusters); Mat1f trainData(numTrainFiles, resultClusters);
Mat1i trainLabels(numTrainFiles, 1); Mat1i trainLabels(numTrainFiles, 1);
...@@ -232,7 +203,7 @@ int main(int argc, char *argv[]) ...@@ -232,7 +203,7 @@ int main(int argc, char *argv[])
// prepare to predict // prepare to predict
curr = dataset->getTest(currSplit); curr = dataset->getTest(currSplit);
unsigned int numTestFiles = getNumFiles(curr); unsigned int numTestFiles = curr.size();
Mat1f testData(numTestFiles, resultClusters); Mat1f testData(numTestFiles, resultClusters);
Mat1i testLabels(numTestFiles, 1); // ground true Mat1i testLabels(numTestFiles, 1); // ground true
...@@ -262,7 +233,6 @@ int main(int argc, char *argv[]) ...@@ -262,7 +233,6 @@ int main(int argc, char *argv[])
double accuracy = 1.0*correct/numTestFiles; double accuracy = 1.0*correct/numTestFiles;
printf("correctly recognized actions: %f\n", accuracy); printf("correctly recognized actions: %f\n", accuracy);
res.push_back(accuracy); res.push_back(accuracy);
} }
double accuracy = 0.0; double accuracy = 0.0;
......
...@@ -97,8 +97,8 @@ int main(int argc, char *argv[]) ...@@ -97,8 +97,8 @@ int main(int argc, char *argv[])
printf("y: %u\n", example->y); printf("y: %u\n", example->y);
printf("dx: %u\n", example->dx); printf("dx: %u\n", example->dx);
printf("dy: %u\n", example->dy); printf("dy: %u\n", example->dy);
printf("tilt_ang: %u\n", example->tilt_ang); printf("tilt_ang: %d\n", example->tilt_ang);
printf("fiducial_yaw_angle: %u\n", example->fiducial_yaw_angle); printf("fiducial_yaw_angle: %d\n", example->fiducial_yaw_angle);
printf("fiducial_score: %u\n", example->fiducial_score); printf("fiducial_score: %u\n", example->fiducial_score);
return 0; return 0;
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#include "opencv2/datasets/ar_hmdb.hpp" #include "opencv2/datasets/ar_hmdb.hpp"
#include "opencv2/datasets/util.hpp" #include "opencv2/datasets/util.hpp"
#include <map>
namespace cv namespace cv
{ {
namespace datasets namespace datasets
...@@ -63,26 +65,9 @@ private: ...@@ -63,26 +65,9 @@ private:
void loadDataset(const string &path); void loadDataset(const string &path);
void loadAction(const string &fileName, vector<string> &train_, vector<string> &test_); map<string, int> actionsId;
}; };
void AR_hmdbImp::loadAction(const string &fileName, vector<string> &train_, vector<string> &test_)
{
ifstream infile(fileName.c_str());
string video, label;
while (infile >> video >> label)
{
if ("1"==label)
{
train_.push_back(video);
} else
if ("2"==label)
{
test_.push_back(video);
}
}
}
/*AR_hmdbImp::AR_hmdbImp(const string &path, int number) /*AR_hmdbImp::AR_hmdbImp(const string &path, int number)
{ {
loadDataset(path, number); loadDataset(path, number);
...@@ -120,18 +105,40 @@ void AR_hmdbImp::loadDatasetSplit(const string &path, int number) ...@@ -120,18 +105,40 @@ void AR_hmdbImp::loadDatasetSplit(const string &path, int number)
getDirList(pathDataset, fileNames); getDirList(pathDataset, fileNames);
for (vector<string>::iterator it=fileNames.begin(); it!=fileNames.end(); ++it) for (vector<string>::iterator it=fileNames.begin(); it!=fileNames.end(); ++it)
{ {
Ptr<AR_hmdbObj> currTrain(new AR_hmdbObj); string &action = *it;
Ptr<AR_hmdbObj> currTest(new AR_hmdbObj); map<string, int>::iterator itId = actionsId.find(action);
currTrain->name = *it; int id;
currTest->name = *it; if (itId == actionsId.end())
{
train.back().push_back(currTrain); actionsId.insert(make_pair(action, actionsId.size()));
test.back().push_back(currTest); id = actionsId.size();
} else
{
id = (*itId).second;
}
char tmp[2]; char tmp[2];
sprintf(tmp, "%u", number+1); sprintf(tmp, "%u", number+1);
string fileName(pathSplit + currTrain->name + "_test_split" + tmp + ".txt"); string fileName(pathSplit + action + "_test_split" + tmp + ".txt");
loadAction(fileName, currTrain->videoNames, currTest->videoNames);
ifstream infile(fileName.c_str());
string video, label;
while (infile >> video >> label)
{
Ptr<AR_hmdbObj> curr(new AR_hmdbObj);
curr->id = id;
curr->name = action;
curr->videoName = video;
if ("1"==label)
{
train.back().push_back(curr);
} else
if ("2"==label)
{
test.back().push_back(curr);
}
}
} }
} }
......
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
#include "opencv2/datasets/fr_adience.hpp" #include "opencv2/datasets/fr_adience.hpp"
#include "opencv2/datasets/util.hpp" #include "opencv2/datasets/util.hpp"
#include <map>
#include <set>
namespace cv namespace cv
{ {
namespace datasets namespace datasets
...@@ -63,6 +66,9 @@ private: ...@@ -63,6 +66,9 @@ private:
void loadFile(const string &filename, vector< Ptr<FR_adienceObj> > &out); void loadFile(const string &filename, vector< Ptr<FR_adienceObj> > &out);
void cv5ToSplits(vector< Ptr<FR_adienceObj> > fileList[5]); void cv5ToSplits(vector< Ptr<FR_adienceObj> > fileList[5]);
map< string, vector<string> > realNames;
set<string> missing;
}; };
/*FR_adienceImp::FR_adienceImp(const string &path) /*FR_adienceImp::FR_adienceImp(const string &path)
...@@ -79,15 +85,38 @@ void FR_adienceImp::loadFile(const string &filename, vector< Ptr<FR_adienceObj> ...@@ -79,15 +85,38 @@ void FR_adienceImp::loadFile(const string &filename, vector< Ptr<FR_adienceObj>
{ {
string line; string line;
ifstream infile(filename.c_str()); ifstream infile(filename.c_str());
getline(infile, line); // skip header
while (getline(infile, line)) while (getline(infile, line))
{ {
Ptr<FR_adienceObj> curr(new FR_adienceObj);
vector<string> elems; vector<string> elems;
split(line, elems, ','); split(line, elems, ',');
curr->user_id = elems[0]; string user_id = elems[0];
curr->original_image = elems[1]; string original_image = elems[1];
// convert original_image to real image name
bool isChanged = false;
vector<string> &currImgs = realNames[user_id];
for (vector<string>::iterator it=currImgs.begin(); it!=currImgs.end(); ++it)
{
string &name = *it;
size_t origImgLen = original_image.length();
if (name.length()>origImgLen && name.substr(name.length()-origImgLen) == original_image)
{
original_image = name;
isChanged = true;
break;
}
}
if (!isChanged)
{
missing.insert(user_id+"/"+original_image);
continue;
}
Ptr<FR_adienceObj> curr(new FR_adienceObj);
curr->user_id = user_id;
curr->original_image = original_image;
curr->face_id = atoi(elems[2].c_str()); curr->face_id = atoi(elems[2].c_str());
curr->age = elems[3]; curr->age = elems[3];
if (elems[4]=="m") if (elems[4]=="m")
...@@ -142,6 +171,26 @@ void FR_adienceImp::cv5ToSplits(vector< Ptr<FR_adienceObj> > fileList[5]) ...@@ -142,6 +171,26 @@ void FR_adienceImp::cv5ToSplits(vector< Ptr<FR_adienceObj> > fileList[5])
void FR_adienceImp::loadDataset(const string &path) void FR_adienceImp::loadDataset(const string &path)
{ {
// collect real image names
unsigned int num = 0;
vector<string> userNames;
getDirList(path+"faces/", userNames);
for (vector<string>::iterator itU=userNames.begin(); itU!=userNames.end(); ++itU)
{
vector<string> fileNames;
getDirList(path+"faces/"+*itU+"/", fileNames);
for (vector<string>::iterator it=fileNames.begin(); it!=fileNames.end(); ++it)
{
string &name = *it;
if (name.length()>3 && name.substr(name.length()-4) == ".jpg")
{
realNames[*itU].push_back(name);
num++;
}
}
}
//printf("total images number: %u\n", num);
vector< Ptr<FR_adienceObj> > fileList[5]; vector< Ptr<FR_adienceObj> > fileList[5];
for (unsigned int i=0; i<5; ++i) for (unsigned int i=0; i<5; ++i)
{ {
...@@ -163,6 +212,13 @@ void FR_adienceImp::loadDataset(const string &path) ...@@ -163,6 +212,13 @@ void FR_adienceImp::loadDataset(const string &path)
loadFile(filename, fileList[i]); loadFile(filename, fileList[i]);
} }
cv5ToSplits(fileList); cv5ToSplits(fileList);
/*for (set<string>::iterator it=missing.begin(); it!=missing.end(); ++it)
{
printf("missing image: %s\n", (*it).c_str());
}*/
realNames.clear();
missing.clear();
} }
Ptr<FR_adience> FR_adience::create() Ptr<FR_adience> FR_adience::create()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment