-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
2,800 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
#include "Checker.h" | ||
|
||
|
||
int getSetNum (string const & line) | ||
{ | ||
return boost::lexical_cast<int>(line.substr(0,line.find_first_of('_'))); | ||
} | ||
|
||
int getImgNum (string const & line) | ||
{ | ||
return boost::lexical_cast<int>(line.substr(line.find_first_of('_')+1,1)); | ||
} | ||
|
||
void readSet (vector<int> & v, ifstream & input, int const setN, string & s) | ||
{ | ||
v.clear(); | ||
v.push_back(getImgNum(s)); | ||
input >> s; | ||
while (getSetNum(s) == setN && input.good()) | ||
{ | ||
v.push_back(getImgNum(s)); | ||
input >> s; | ||
} | ||
} | ||
|
||
bool contains (vector<int> const & v, int const k) | ||
{ | ||
return (std::find(v.begin(), v.end(), k) != v.end()); | ||
} | ||
|
||
float compareResults (vector<int> const & my, vector<int> const & corr) | ||
{ | ||
if (corr.empty()) | ||
return (nImagesInSet-my.size())/nImagesInSet; | ||
float mark = 0.0; | ||
bool inMy = false, inCorr = false; | ||
for (int i=0; i!=nImagesInSet; ++i) | ||
{ | ||
inMy = contains(my, i+1); | ||
inCorr = contains(corr, i+1); | ||
if ((inMy && inCorr) || (!inMy && !inCorr)) | ||
mark += 1/(float)nImagesInSet; | ||
} | ||
return mark; | ||
} | ||
|
||
void printIntVector (ofstream & out, vector<int> const & v) { | ||
if (v.empty()) | ||
{ | ||
out << " none\n"; | ||
return; | ||
} | ||
for (unsigned int i=0; i!=v.size(); ++i) | ||
out << " " << v[i]; | ||
out << "\n"; | ||
} | ||
|
||
map<int, vector<int> > const & readOutput (string const & fileName) | ||
{ | ||
map<int, vector<int> > * odds = new map<int, vector<int> >(); //map: setNumber: vector of odd images | ||
|
||
ifstream file(fileName.c_str(), ifstream::in); | ||
if (!file.is_open()) | ||
{ | ||
cerr << "Cannot open "<< fileName <<"\n"; | ||
return *odds; | ||
} | ||
|
||
string line = ""; | ||
while (file.good()) | ||
{ | ||
file >> line; | ||
int setNum = getSetNum(line); | ||
map<int, vector<int> >::iterator it = odds->find(setNum); | ||
if (it == odds->end()) | ||
{ | ||
odds->insert(std::pair<int, vector<int> > (setNum, vector<int>(1, getImgNum(line)))); | ||
continue; | ||
} | ||
it->second.push_back(getImgNum(line)); | ||
} | ||
file.close(); | ||
return *odds; | ||
} | ||
|
||
vector<int> const & getNextSet (int const setNum, map<int, vector<int> > const & odds) | ||
{ | ||
map<int, vector<int> >::const_iterator it = odds.find(setNum); | ||
if (it != odds.end()) | ||
return it->second; | ||
|
||
return *(new vector<int>()); | ||
} | ||
|
||
float checkMultithreaded (string const & myResult, string const & learning) | ||
{ | ||
ofstream cmpLog("compare_log.txt", ofstream::trunc); | ||
if (!cmpLog.is_open()) | ||
{ | ||
cerr << "Cannot create compare_log file.\n"; | ||
return 0; | ||
} | ||
|
||
map<int, vector<int> > myOdds = readOutput(myResult); | ||
map<int, vector<int> > trueOdds = readOutput(learning); | ||
|
||
int currentSetN = StartSet; | ||
int n_wrong = 0; | ||
float mark = 0; | ||
|
||
Stitcher stitcher; | ||
|
||
while (currentSetN < FinishSet) | ||
{ | ||
vector<int> v1 = getNextSet(currentSetN, myOdds); | ||
vector<int> v2 = getNextSet(currentSetN, trueOdds); | ||
float tmpMark = compareResults(v1, v2); | ||
if (tmpMark != 1.0) | ||
{ | ||
cmpLog << currentSetN << "\nmy odds:"; | ||
printIntVector(cmpLog, v1); | ||
cmpLog << "true odds:"; | ||
printIntVector(cmpLog, v2); | ||
|
||
int tmp; | ||
printMat_(cmpLog, stitcher.calcSetStitch2(currentSetN, &tmp)); | ||
//Stitcher::printStitchMatrix(cmpLog, stitcher.calcSetStitch2(currentSetN)); | ||
|
||
n_wrong += 1; | ||
|
||
} | ||
mark += tmpMark; | ||
currentSetN += 1; | ||
} | ||
cmpLog << n_wrong << " classified wrong."; | ||
cmpLog.close(); | ||
return (currentSetN-StartSet>0) ? mark/(currentSetN-StartSet) : mark; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#ifndef CHECKER_H | ||
#define CHECKER_H | ||
|
||
#include <algorithm> //for min | ||
#include <cstring> | ||
#include <fstream> | ||
#include <boost/lexical_cast.hpp> | ||
#include <vector> | ||
#include <iostream> | ||
#include <map> | ||
|
||
#include "Parameters.h" | ||
#include "Stitcher.h" | ||
#include "PrintMat.h" | ||
|
||
using std::string; | ||
using std::ifstream; | ||
using std::ofstream; | ||
using std::vector; | ||
using std::cerr; | ||
using std::map; | ||
|
||
//float checkResult (string const & myResult, string const & learning); | ||
|
||
float checkMultithreaded (string const & myResult, string const & learning); | ||
|
||
#endif // CHECKER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
#include "Classifier.h" | ||
|
||
int Classifier::currentSet_ = StartSet; | ||
pthread_mutex_t Classifier::mutex_ = PTHREAD_MUTEX_INITIALIZER; | ||
string Classifier::outputName = "output.txt"; | ||
ofstream Classifier::output(Classifier::outputName.c_str(), ofstream::trunc); | ||
|
||
//проверяем наличие значения х в векторе векторов v, ecли да, то сохраняем индекс векторов, в которых есть | ||
bool Classifier::existsVV(int const x, vvi & v, vvi::iterator * t) | ||
{ | ||
for (vvi::iterator i = v.begin(); i!=v.end(); ++i) | ||
for (vector<int>::iterator j = i->begin(); j!=i->end(); ++j) | ||
if (*j == x) | ||
{ | ||
if (t != 0) | ||
*t = i; | ||
return true; | ||
} | ||
|
||
/*for (unsigned int i=0; i != v.size(); ++i) | ||
for (unsigned int j=0; j != v[i].size(); ++j) | ||
if (v[i][j] == x) | ||
{ | ||
if (t != 0) | ||
*t = i; | ||
return true; | ||
}*/ | ||
return false; | ||
} | ||
|
||
void Classifier::append (int const i, vvi & sets, Mat_<float> const & m, map<int, vector<int> > & matches, vector<float> const & passValue) | ||
{ | ||
// вектор всех сетов, в которых лежат матчи i | ||
vector<vvi::iterator> correspondingSets; | ||
vvi::iterator t; | ||
for (unsigned int j = 0; j!= matches[i].size(); ++j) | ||
{ | ||
// check if i's matches are already in sets | ||
if (existsVV(matches[i][j], sets, &t)) | ||
{ | ||
//check if match values correspond to passValues | ||
if (m(i, matches[i][j]) > passValue[i] && m(i, matches[i][j]) > passValue[matches[i][j]]) | ||
{ | ||
if (std::find(correspondingSets.begin(), correspondingSets.end(), t) == correspondingSets.end()) | ||
correspondingSets.push_back(t); | ||
} | ||
} | ||
} | ||
if (correspondingSets.empty()) | ||
{ | ||
// init a new set | ||
sets.push_back(vector<int>(1, i)); | ||
//(*(sets.end()-1)).push_back(i); | ||
//sets[sets.size()-1].push_back(i); | ||
return;// false; | ||
} | ||
if (correspondingSets.size()==1) | ||
{ | ||
correspondingSets[0]->push_back(i); | ||
return;// true; | ||
} | ||
// merge all corresponding sets | ||
sets.push_back(vector<int>()); | ||
//int index = sets.size()-1; | ||
for (vector<vvi::iterator>::iterator it = correspondingSets.begin(); it != correspondingSets.end(); ++it) | ||
{ | ||
for (vector<int>::iterator k=(*it)->begin(); k!=(*it)->end(); ++k) | ||
{ | ||
(*sets.rbegin()).push_back(*k); | ||
//sets[sets.size()-1].push_back(*k); | ||
} | ||
sets.erase(*it); | ||
} | ||
(*sets.rbegin()).push_back(i); | ||
//return true; | ||
} | ||
|
||
bool Classifier::findOddImages (Mat_<float> const & m, const int setNumber) | ||
{ | ||
// img:vector of matching images | ||
map<int, vector<int> > matches; | ||
vector<float> passValue; | ||
for (int i = 0; i!=nImagesInSet; ++i) | ||
{ | ||
matches.insert(std::pair<int, vector<int> >(i, vector<int>())); | ||
float passVal = 0; | ||
for (int j=0; j!=nImagesInSet; ++j) | ||
if (m(i, j) > passVal) | ||
passVal = m(i, j); | ||
passVal *= matchLimit; | ||
passValue.push_back(passVal); | ||
if (passVal == 0) continue; | ||
for (int j=0; j!=nImagesInSet; ++j) | ||
if (i != j && m(i, j) > passVal) | ||
matches[i].push_back(j); | ||
} | ||
|
||
int elementWithMaxPassValue = 0; | ||
for (unsigned int i=1; i!=matches.size(); ++i) | ||
if (passValue[elementWithMaxPassValue] < passValue[i]) | ||
elementWithMaxPassValue = i; | ||
|
||
if (passValue[elementWithMaxPassValue] == 0) | ||
return false; | ||
|
||
vvi sets; | ||
sets.push_back(matches[elementWithMaxPassValue]); | ||
(*sets.rbegin()).push_back(elementWithMaxPassValue); | ||
|
||
for (unsigned int i=0; i<matches.size(); ++i) | ||
{ | ||
// смотрим, лежит ли i в каком-нибудь сете | ||
if (!existsVV(i, sets)) | ||
{// если нет, то можно ли добавить ее к существующему сету | ||
append(i, sets, m, matches, passValue); | ||
} | ||
} | ||
|
||
// выбираем самый большой сет, остальные - лишние | ||
vvi::iterator maxSet = sets.begin(); | ||
for (vvi::iterator it = sets.begin(); it!=sets.end(); ++it) | ||
{ | ||
if ((*it).size() > (*maxSet).size()) | ||
maxSet = it; | ||
} | ||
|
||
//если никто ни с кем не группировался | ||
if ((*maxSet).size()==1) | ||
return true; // false | ||
|
||
if ((*maxSet).size()==(unsigned int)nImagesInSet) | ||
return true; | ||
|
||
// если maxSet.size < половины фоток - значит, он лишний | ||
if ((*maxSet).size() < 1+nImagesInSet/2) | ||
{ | ||
pthread_mutex_lock(&mutex_); | ||
if (!output.is_open()) | ||
output.open(Classifier::outputName.c_str(), ofstream::app); | ||
|
||
for (vector<int>::iterator it = (*maxSet).begin(); it!=(*maxSet).end(); ++it) | ||
output << setNumber << "_" << (*it)+1 << ".jpg\n"; | ||
|
||
output.close(); | ||
pthread_mutex_unlock(&mutex_); | ||
|
||
return true; | ||
} | ||
|
||
pthread_mutex_lock(&mutex_); | ||
if (!output.is_open()) | ||
output.open(Classifier::outputName.c_str(), ofstream::app); | ||
|
||
for (vvi::iterator iter = sets.begin(); iter != sets.end(); ++iter) | ||
{ | ||
if (iter == maxSet) | ||
continue; | ||
for (vector<int>::iterator it = (*iter).begin(); it!=(*iter).end(); ++it) | ||
output << setNumber << "_" << (*it)+1 << ".jpg\n"; | ||
|
||
} | ||
|
||
output.close(); | ||
pthread_mutex_unlock(&mutex_); | ||
|
||
return true; | ||
} | ||
|
||
void Classifier::classify () | ||
{ | ||
int from = -1; | ||
int nSets = -1; | ||
while (true) | ||
{ | ||
pthread_mutex_lock(&mutex_); | ||
if (currentSet_ < FinishSet) | ||
{ | ||
from = currentSet_; | ||
nSets = std::min(nSetsPerThread, FinishSet-from); | ||
currentSet_ += nSets; | ||
} | ||
pthread_mutex_unlock(&mutex_); | ||
|
||
if (from == -1) | ||
break; | ||
|
||
for (int i=from; i!=from+nSets; ++i) | ||
{ | ||
std::cerr << i << " set\n"; | ||
int nMismatched = 0; | ||
Mat_<float> m = stitcher.calcSetStitch2(i, &nMismatched); | ||
if (Print) printMat_(std::cerr, m); | ||
findOddImages(m, i); | ||
|
||
/*if (nMismatched > 2) | ||
{ | ||
m = matcher.calcSetMatch(i); | ||
findOddImages(m, i); | ||
} | ||
else | ||
if (!findOddImages(m, i)) | ||
{ | ||
m = matcher.calcSetMatch(i); | ||
findOddImages(m, i); | ||
} | ||
if (Print) printMat_(std::cerr, m);*/ | ||
} | ||
from = -1; | ||
} | ||
} |
Oops, something went wrong.