From 34ba693e1c2460777e445a2b531302886f4dc71d Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Sun, 5 Aug 2018 15:36:53 +0200 Subject: [PATCH] Adds mutations --- DescriptorManager.cpp | 77 +++++++++++++++++++++++++++ DescriptorManager.h | 8 ++- Mutation.h | 39 ++++++++++++++ SmallImageDescriptors.vcxproj | 1 + SmallImageDescriptors.vcxproj.filters | 3 ++ main.cpp | 3 +- 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 Mutation.h diff --git a/DescriptorManager.cpp b/DescriptorManager.cpp index add05d6..4e912b7 100644 --- a/DescriptorManager.cpp +++ b/DescriptorManager.cpp @@ -18,6 +18,8 @@ DescriptorManager::DescriptorManager(const fs::path & image_path) { descriptor_types[2] = new median(); descriptor_types[1] = new numColors(); descriptor_types[0] = new averageColor(); + + mutators[0] = new Grayscale(); } //No need to call destructor.. yet? @@ -44,6 +46,7 @@ bool DescriptorManager::loadDescriptors() { //foreach image for (fs::directory_iterator itr(img_path); itr != end_itr; ++itr) { + if (!itr->path().has_extension()) continue; fs::path featurePath(descriptorBase / itr->path().stem()); //string image_name = featurePath.filename().generic_string(); string image_name = itr->path().filename().generic_string(); @@ -86,6 +89,80 @@ bool DescriptorManager::loadDescriptors() { return true; } +//Loads all images and makes and stores the mutations +bool DescriptorManager::createMutations() { + if (!fs::exists(img_path)) return false; + fs::directory_iterator end_itr; //last file in dir + map images; //image cache + fs::ifstream ifs; + fs::ofstream ofs; + + //foreach mutation + for (int i = 0; i < numMutations; i++) { + fs::path mutationBase(img_path / mutators[i]->ToPath()); + fs::path descriptorBase("meta" / descriptor_types[i]->ToPath()); + if (!fs::is_directory(mutationBase)) + if (fs::create_directory(mutationBase)) {} + + //foreach image + int z = 0; + for (fs::directory_iterator itr(img_path); itr != end_itr; ++itr) { + fs::path mutPath(mutationBase / itr->path().filename().generic_string()); + if (z++ > 50) break; //for quick execution + //if (fs::exists(mutPath)) continue; //already exists + if (!itr->path().has_extension()) continue; //skip directories + + Image* image = new Image(itr->path().string()); + Image* mutated = mutators[i]->getMutated(image); + mutated->write(mutPath.generic_string()); + + //now calculate all the features for the mutated images as well + //foreach descriptor + for (int j = 0; j < numDescriptors; j++) { + //folder to store descriptors; create if not exists + fs::path descriptorBase("meta" / descriptor_types[j]->ToPath() / mutators[i]->ToPath()); + if (!fs::is_directory(descriptorBase)) + if (fs::create_directory(descriptorBase)) {} + fs::path featurePath(descriptorBase / itr->path().stem()); + cout << featurePath << endl; + string image_name = itr->path().filename().generic_string(); + if (fs::exists(featurePath)) { //feature already calculated + ifs.open(featurePath, fs::fstream::binary); //in binary mode + unsigned long long n; + ifs.read(reinterpret_cast(&n), sizeof(n)); + ifs.close(); + bitset<64> b1(n); + //descriptors[j][image_name] = b1; + } + else { //feature not yet calculated + Image* image; //only load image from disk if not loaded before + if (images.count(image_name)) { //if image exists in map + image = images[image_name]; + } + else { + image = new Image; + image->read(itr->path().string()); + images[image_name] = image; + } + //cout << "Calculating " << image_name << endl; + bitset<64> b1 = descriptor_types[i]->feature(image); + //descriptor_types[i]->distance(b1, b1); + //descriptors[i][image_name] = b1; + + unsigned long long n = b1.to_ullong(); + ofs.open(featurePath, fs::fstream::binary); //in binary mode; only open file after calculations have been done + ofs.write(reinterpret_cast(&n), sizeof(n)); + ofs.close(); + } + } + delete mutated; + delete image; + } + + } + return true; +} + //essentially insertion sort into a map void DescriptorManager::similarImages(string image_name, int method, int numImages) { bitset<64> target; diff --git a/DescriptorManager.h b/DescriptorManager.h index 3bd80df..f564443 100644 --- a/DescriptorManager.h +++ b/DescriptorManager.h @@ -11,6 +11,7 @@ #include #include #include "Descriptor.h" +#include "Mutation.h" using namespace std; using namespace Magick; @@ -26,13 +27,18 @@ public: DescriptorManager(const fs::path & image_path); ~DescriptorManager(); bool loadDescriptors(); + bool createMutations(); void similarImages(string image_name, int method, int numImages); void outputMap(int a); void outputMap(); private: - static const int numDescriptors = 8; //TODO: automagically update this? + static const int numDescriptors = 8; + static const int numMutations = 1; + //TODO: automagically update this? + map> descriptors[numDescriptors]; //array of maps that will hold the descriptors fs::path img_path; //where the images are Descriptor* descriptor_types[numDescriptors]; + Mutation* mutators[numMutations]; }; diff --git a/Mutation.h b/Mutation.h new file mode 100644 index 0000000..acc9837 --- /dev/null +++ b/Mutation.h @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include + +#include //in which we store our feature vectors +#include //for sorting + +using namespace std; +using namespace Magick; + +namespace fs = boost::filesystem; + +//Virtual base class +//Holds definitions for all common functions of descriptors, +//but should be overloaded by a child class +class Mutation { +public: + //virtual void mutate(Image* img) = 0; + virtual Image* getMutated(Image* img) = 0; + + virtual string ToString() = 0; + virtual fs::path ToPath() { + return fs::path(this->ToString()); + } +}; + +//Just the way dogs see +class Grayscale : public Mutation { +public: + Image* getMutated(Image* img) { + Image* mut = new Image(*img); + mut->type(GrayscaleType); + return mut; + } + string ToString() { + return "Grayscale"; + } +}; \ No newline at end of file diff --git a/SmallImageDescriptors.vcxproj b/SmallImageDescriptors.vcxproj index 8d7fd72..141ff02 100644 --- a/SmallImageDescriptors.vcxproj +++ b/SmallImageDescriptors.vcxproj @@ -161,6 +161,7 @@ + diff --git a/SmallImageDescriptors.vcxproj.filters b/SmallImageDescriptors.vcxproj.filters index efc2e5a..e7052f9 100644 --- a/SmallImageDescriptors.vcxproj.filters +++ b/SmallImageDescriptors.vcxproj.filters @@ -27,6 +27,9 @@ Header Files + + Header Files + diff --git a/main.cpp b/main.cpp index a79f204..6e3f28f 100644 --- a/main.cpp +++ b/main.cpp @@ -41,8 +41,9 @@ int main(int argc, char **argv) { DescriptorManager* manager = new DescriptorManager("data"); //cout << "Loading descriptiors.."; manager->loadDescriptors(); + manager->createMutations(); //cout << "done!" << endl << "Calculating distances.." << endl; - manager->similarImages(imagename, method, count); + //manager->similarImages(imagename, method, count); //cout << "done!" << endl << "Outputting map.." << endl; //manager->outputMap();