Optimization updates
This commit is contained in:
+68
-9
@@ -58,11 +58,12 @@ DescriptorManager::DescriptorManager(const fs::path & image_path) {
|
||||
//Returns a pointer to the image mutated by the given method.
|
||||
//Either gets it from disk, or calculates it directly.
|
||||
Image* DescriptorManager::GetMutated(Image* image, string image_name, int method) {
|
||||
return mutators[method]->getMutated(image);
|
||||
fs::path mutPath(img_path / mutators[method]->ToPath() / image_name);
|
||||
Image* mutated;
|
||||
if (!fs::exists(mutPath)) { //only mutate if nothing on disk
|
||||
mutated = mutators[method]->getMutated(image);
|
||||
mutated->write(mutPath.generic_string());
|
||||
//mutated->write(mutPath.generic_string());
|
||||
}
|
||||
else {
|
||||
mutated = new Image;
|
||||
@@ -78,7 +79,7 @@ void DescriptorManager::LoadFeatures(string image_path, string image_name) {
|
||||
if (features[i].count(image_name) > 0) {
|
||||
continue;
|
||||
}
|
||||
current_image = new Image(image_path);
|
||||
if(!current_image) current_image = new Image(image_path);
|
||||
fs::path featurePath("meta" / descriptor_types[i]->ToPath() / image_name);
|
||||
|
||||
uint64_t b1;
|
||||
@@ -152,10 +153,39 @@ void DescriptorManager::Init() {
|
||||
}
|
||||
}
|
||||
|
||||
//Check which of the features we loaded from disk
|
||||
//skips checking all images we already have.
|
||||
//If only one part is missing, we mark the image for recalculation
|
||||
void DescriptorManager::CompareFeatures() {
|
||||
vector<pair<string, uint64_t>> features_vector;
|
||||
vector<pair<string, uint64_t>> mutatedFeatures_vector[numMutations];
|
||||
for (fs::directory_iterator itr(img_path); itr != fs::directory_iterator(); ++itr) {
|
||||
if (!itr->path().has_extension()) continue; //skip directories and such
|
||||
string image_name = itr->path().filename().generic_string();
|
||||
{ //Progress bar
|
||||
filecount++;
|
||||
cout << setw(60) << setfill('*') << "\r" << string(60, ' ') << flush;
|
||||
cout << setfill('*') << setw(60) << right<< "\rChecking which images we already have: " << filecount*100/numImages << "% - (" << filecount << "/" << numImages << "): " << image_name << flush;
|
||||
}
|
||||
|
||||
for (int method = 0; method < numDescriptors; i++) {
|
||||
bool load = false;
|
||||
if (features[method].count(image_name) == 0) {
|
||||
load = true;
|
||||
}
|
||||
for (int mutation = 0; !load && mutation < numMutations; mutation++) {
|
||||
if (mutatedFeatures[method][mutation].count(image_name) == 0) {
|
||||
load = true;
|
||||
}
|
||||
}
|
||||
if (load) images.push_back(itr->path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Saves feature map to disk.
|
||||
void DescriptorManager::SaveToDisk() {
|
||||
{ //Boost serialization
|
||||
{ //TODO: make backups first.
|
||||
ofstream f("features.map", ios::binary);
|
||||
ar::binary_oarchive oa(f);
|
||||
oa << features;
|
||||
@@ -254,12 +284,41 @@ void DescriptorManager::runExperiments() {
|
||||
}
|
||||
|
||||
//Test post please ignore
|
||||
void DescriptorManager::test() {
|
||||
const uint64_t n = 1000000000;
|
||||
//string insert = "constant"; //assuming string value doesn't matter.
|
||||
int method = 2;
|
||||
void DescriptorManager::test(int method) {
|
||||
//for (int method = 0; method < numDescriptors; method++) { //paralellized
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
//foreach image
|
||||
for (map<string, uint64_t>::iterator img = features[method].begin(); img != features[method].end(); ++img) {
|
||||
uint64_t targets[numMutations];
|
||||
uint64_t better_counts[numMutations];
|
||||
for (int i = 0; i < numMutations; i++) {
|
||||
targets[i] = descriptor_types[method]->distance(img->second, mutatedFeatures[method][i][img->first]);
|
||||
better_counts[i] = 0;
|
||||
}
|
||||
for (map<string, uint64_t>::iterator it = features[method].begin(); it != features[method].end(); ++it) {
|
||||
uint64_t distance = descriptor_types[method]->distance(img->second, it->second);
|
||||
for (int i = 0; i < numMutations; i++)
|
||||
{
|
||||
if(distance >= targets[i]) better_counts[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
//mu.lock();
|
||||
cout << "It took me " << time_span.count() << " seconds to rank one image with " << numImages << " images." << endl;
|
||||
//mu.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*{
|
||||
|
||||
const uint64_t n = 1000000000;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
int target_distance = 5;
|
||||
uint64_t better_count = 0;
|
||||
@@ -273,7 +332,7 @@ void DescriptorManager::test() {
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
cout << "It took me " << time_span.count() << " seconds to sort " << n << " big numbers." << endl;
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
@@ -324,4 +383,4 @@ void DescriptorManager::generatePreviews(string imagename) {
|
||||
for (int i = 0; i < numDescriptors; i++) {
|
||||
descriptor_types[i]->preview(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -6,6 +6,7 @@
|
||||
#include <climits>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
@@ -43,12 +44,13 @@ public:
|
||||
void LoadMutationFeatures(string image_path, string image_name, int mutation);
|
||||
Image* GetMutated(Image* image, string image_name, int method);
|
||||
void Init();
|
||||
void CompareFeatures()
|
||||
void SaveToDisk();
|
||||
void LoadFromDisk();
|
||||
void rankImages(string image_name, int method);
|
||||
multiset<pair<uint64_t, string>> rankMutations(string image_name, int method);
|
||||
void runExperiments();
|
||||
void test();
|
||||
void test(int method);
|
||||
void generatePreviews(string imagename);
|
||||
void outputMap(int a);
|
||||
void outputMap();
|
||||
@@ -56,16 +58,19 @@ public:
|
||||
private:
|
||||
fs::path img_path;
|
||||
int numImages;
|
||||
|
||||
static const int numDescriptors = 8;
|
||||
static const int numMutations = 8;
|
||||
Descriptor* descriptor_types[numDescriptors];
|
||||
Mutation* mutators[numMutations];
|
||||
|
||||
//mutex mu; //for threading and suchlikes
|
||||
Image* current_image = NULL; //for caching purposes
|
||||
//TODO: Are maps the best container for us? Logarithmic random access is bad, but otherwise it might be fine?
|
||||
map<string, uint64_t> features[numDescriptors]; //array of maps that will hold the descriptors
|
||||
map<string, uint64_t> mutatedFeatures[numDescriptors][numMutations];
|
||||
vector<pair<string, uint64_t>> features_vector;
|
||||
vector<pair<string, uint64_t>> mutatedFeatures_vector[numMutations];
|
||||
vector<fs::Path> images;
|
||||
multiset<pair<uint64_t, string> > distances; //multiset that stores the distances
|
||||
};
|
||||
|
||||
|
||||
@@ -26,21 +26,20 @@ int main(int argc, char **argv) {
|
||||
cout << "Continuing.." << endl;
|
||||
}
|
||||
InitializeMagick(*argv);
|
||||
DescriptorManager* manager = new DescriptorManager("test");
|
||||
DescriptorManager* manager = new DescriptorManager("data");
|
||||
manager->Init();/*
|
||||
manager->rankImages(imagename, method);
|
||||
manager->outputRank(imagename, method);
|
||||
manager->outputMap(method);*/
|
||||
cout << endl;
|
||||
|
||||
cout << "Starting first compute thread.." << endl;
|
||||
thread first(&DescriptorManager::test, manager);
|
||||
cout << "Starting second computer thread.." << endl;
|
||||
thread second(&DescriptorManager::test, manager);
|
||||
first.join();
|
||||
|
||||
second.join();
|
||||
cout << "we done." << endl;
|
||||
const int thread_count = 8;
|
||||
thread* thrds[thread_count];
|
||||
for (int i =0; i < thread_count; i++) {
|
||||
thrds[i] = new thread(&DescriptorManager::test, manager, i);
|
||||
}
|
||||
for (int i =0; i < thread_count; i++) {
|
||||
thrds[i]->join();
|
||||
}
|
||||
//manager->test();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user