diff --git a/Descriptor.h b/Descriptor.h index ff8b5cd..06e38ba 100644 --- a/Descriptor.h +++ b/Descriptor.h @@ -76,6 +76,7 @@ public: c[0] = converted[i] * 255.0; c++; } + delete newimg; //newimg->write("Out.png"); //for debugging purposes return converted; } @@ -151,19 +152,20 @@ public: class median : public Descriptor { public: bitset<64> feature(Image* img) { - img->type(GrayscaleType); - img->filterType(LanczosFilter); //fast resizing, should have minimal impact on accuracy - img->resize(Geometry(8, 8, 0, 0)); //64 pixels + Image* local_image = new Image(*img); + local_image->type(GrayscaleType); + local_image->filterType(LanczosFilter); //fast resizing, should have minimal impact on accuracy + local_image->resize(Geometry(8, 8, 0, 0)); //64 pixels ssize_t n = 8; ssize_t m = 8; - Pixels view(*img); + Pixels view(*local_image); float intensity = 0; int numpixels = (int)(n*m); const Quantum *p = view.getConst(0, 0, n, m); //entire image int* intensities = new int[numpixels]; int index = 0; - int chan = (int)img->channels(); //should be 1, for a grayscale img + int chan = (int)local_image->channels(); //should be 1, for a grayscale img for (ssize_t j = 0; j < m; j++) { for (ssize_t i = 0; i < n; i++) { //LTR scanning @@ -183,9 +185,11 @@ public: retval <<= 1; if (q[0] > intensity) retval |= bitset<64>(1); - q = q + img->channels(); + q = q + local_image->channels(); } } + delete local_image; + delete intensities; return retval; } @@ -208,21 +212,22 @@ public: class sobel : public Descriptor { public: bitset<64> feature(Image* img) { + Image* local_image = new Image(*img); //TODO: Some preprocessing for this? //img->reduceNoise(4.0); - img->type(GrayscaleType); + local_image->type(GrayscaleType); //Apply sobel convolution - img->convolve(3, sobelX); - img->convolve(3, sobelY); + local_image->convolve(3, sobelX); + local_image->convolve(3, sobelY); - ssize_t n = img->rows(); - ssize_t m = img->columns(); + ssize_t n = local_image->rows(); + ssize_t m = local_image->columns(); - Pixels view(*img); + Pixels view(*local_image); const Quantum *p = view.getConst(0, 0, m, n); //entire image unsigned long long intensity = 0; - int chan = (int)img->channels(); + int chan = (int)local_image->channels(); for (ssize_t j = 0; j < m; j++) { for (ssize_t i = 0; i < n; i++) { //LTR scanning @@ -233,6 +238,7 @@ public: //cout << endl; } int scaledIntensity = ((float)(intensity / (n*m)) / QuantumRange) * 255; + delete local_image; return bitset<64>(scaledIntensity); } string ToString() { @@ -250,15 +256,16 @@ private: class pearson : public Descriptor { public: bitset<64> feature(Image* img) { - img->type(GrayscaleType); - img->filterType(LanczosFilter); //fast! - img->resize(Geometry(8, 8)); //64 pixels + Image* local_image = new Image(*img); + local_image->type(GrayscaleType); + local_image->filterType(LanczosFilter); //fast! + local_image->resize(Geometry(8, 8)); //64 pixels ssize_t n = 8; ssize_t m = 8; - Pixels view(*img); + Pixels view(*local_image); int intensity = 0; int numpixels = (int)(n*m); - int chan = (int)img->channels(); + int chan = (int)local_image->channels(); const Quantum *p = view.getConst(0, 0, n, m); //entire image bitset<64> retval(0); int prev = p[0]; //so we always start with a 0 @@ -274,6 +281,7 @@ public: retval <<= 1; } } + delete local_image; return retval; } unsigned long long distance(bitset<64> a, bitset<64> b) { @@ -294,15 +302,16 @@ public: class threshold : public Descriptor { public: bitset<64> feature(Image* img) { - img->type(GrayscaleType); - img->filterType(LanczosFilter); //fast! - img->resize(Geometry(8, 8)); //64 pixels - img->adaptiveThreshold(2, 2); //Thresholding in a moving 2*2 neighborhood + Image* local_image = new Image(*img); + local_image->type(GrayscaleType); + local_image->filterType(LanczosFilter); //fast! + local_image->resize(Geometry(8, 8)); //64 pixels + local_image->adaptiveThreshold(2, 2); //Thresholding in a moving 2*2 neighborhood ssize_t n = 8; ssize_t m = 8; - Pixels view(*img); + Pixels view(*local_image); int numpixels = (int)(n*m); - int chan = (int)img->channels(); + int chan = (int)local_image->channels(); const Quantum *p = view.getConst(0, 0, n, m); //entire image bitset<64> retval(0); for (ssize_t j = 0; j < m; j++) { @@ -318,6 +327,7 @@ public: //cout << endl; } //cout << "----" << endl << endl; + delete local_image; return retval; } unsigned long long distance(bitset<64> a, bitset<64> b) { @@ -338,7 +348,8 @@ public: class DCTPearson: public Descriptor { public: bitset<64> feature(Image* img) { - double* converted = CalculateDCT(img); + Image* local_image = new Image(*img); + double* converted = CalculateDCT(local_image); double prev = 0; bitset<64> retval(0); @@ -349,6 +360,7 @@ public: retval <<= 1; prev = converted[i]; } + delete local_image; return retval; } unsigned long long distance(bitset<64> a, bitset<64> b) { @@ -366,7 +378,8 @@ public: class DCTMedian : public Descriptor { public: bitset<64> feature(Image* img) { - double* converted = CalculateDCT(img); + Image* local_image = new Image(*img); + double* converted = CalculateDCT(local_image); double bullshit[64]; for (ssize_t i = 0; i < 64; i++) { bullshit[i] = converted[i]; @@ -380,6 +393,7 @@ public: if (converted[i] > median) retval |= bitset<64>(1); } + delete local_image; return retval; } unsigned long long distance(bitset<64> a, bitset<64> b) { diff --git a/DescriptorManager.cpp b/DescriptorManager.cpp index d3da795..fc1c510 100644 --- a/DescriptorManager.cpp +++ b/DescriptorManager.cpp @@ -45,8 +45,14 @@ void DescriptorManager::Init() { } fs::ifstream ifs; fs::ofstream ofs; + int cnt = std::count_if( + fs::directory_iterator(img_path), + fs::directory_iterator(), + static_cast(fs::is_regular_file)); //foreach image in directory (non-recursive) + int filecount = 0; for (fs::directory_iterator itr(img_path); itr != fs::directory_iterator(); ++itr) { + cout << "\r" << "Progress: " << filecount++*100/cnt << "% - (" << filecount << "/" << cnt << ")" << flush; if (!itr->path().has_extension()) continue; //skip directories and such string image_name = itr->path().filename().generic_string(); Image* image = new Image; @@ -57,6 +63,7 @@ void DescriptorManager::Init() { fs::path descriptorBase("meta" / descriptor_types[i]->ToPath()); if (!fs::is_directory(descriptorBase)) fs::create_directory(descriptorBase); + //cout << "Starting with descriptor " << i << " on location " << descriptorBase.generic_string() << endl; fs::path featurePath(descriptorBase / itr->path().stem()); bitset<64>* b1; @@ -68,7 +75,7 @@ void DescriptorManager::Init() { b1 = new bitset<64>(n); } else { //not on disk, calculate it - b1 = &descriptor_types[i]->feature(image); + b1 = new bitset<64>(descriptor_types[i]->feature(image)); unsigned long long n = b1->to_ullong(); ofs.open(featurePath, fs::fstream::binary); ofs.write(reinterpret_cast(&n), sizeof(n)); @@ -103,13 +110,13 @@ void DescriptorManager::Init() { fs::path featurePath(descriptorBase / itr->path().stem()); //cout << featurePath << endl; string image_name = itr->path().filename().generic_string(); - bitset<64>* b1; + bitset<64>* b1 = NULL; if (!fs::exists(featurePath)) { //feature not yet calculated //descriptor_types[i]->distance(b1, b1); //descriptors[i][image_name] = b1; - b1 = &descriptor_types[j]->feature(mutated); + b1 = new bitset<64>(descriptor_types[j]->feature(mutated)); unsigned long long n = b1->to_ullong(); - cout << "Writing " << *b1 << "(" << n << ")" << " to " << featurePath << endl; + //cout << "Writing " << *b1 << "(" << n << ")" << " to " << featurePath << endl; 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(); @@ -123,6 +130,7 @@ void DescriptorManager::Init() { } mutatedFeatures[j][i][image_name] = *b1; + if(b1) delete b1; } delete mutated; } @@ -158,7 +166,7 @@ void DescriptorManager::rankMutations(string image_name, int method) { else { return; } - cout << "Finding hits for " << image_name << " which has feature-number " << target.to_ullong() << endl; + //cout << "Finding hits for " << image_name << " which has feature-number " << target.to_ullong() << endl; multiset > local_distance = distances; //get our local copy of the distances. for (int i = 0; i < numMutations; i++) { bitset<64> b1 = mutatedFeatures[method][i][image_name]; @@ -167,13 +175,13 @@ void DescriptorManager::rankMutations(string image_name, int method) { local_distance.insert(p); } - cout << "..." << endl; + //cout << "..." << endl; for (int i = 0; i < numMutations; i++) { int j = 0; for (std::multiset>::iterator it = local_distance.begin(); it != local_distance.end(); ++it) { //cout << "hey " << endl; if (it->second == mutators[i]->ToString()) { - cout << "Hit. On the " << j << "th position: " << endl; + cout << j << "th position: "; cout << "(" << it->first << ", " << it->second << ")" << endl; } j++; @@ -181,6 +189,16 @@ void DescriptorManager::rankMutations(string image_name, int method) { } } +void DescriptorManager::runExperiments() { + for (int i = 0; i < numDescriptors; i++) { + for (map>::iterator it = features[i].begin(); it != features[i].end(); ++it) { + cout << "=== " << descriptor_types[i]->ToString() << ": " << it->first << " ===" << endl; + rankImages(it->first, i); + rankMutations(it->first, i); + } + } +} + //outputs the gathered data to iostream //can be called directly or is called by its overload //assumes a < numDescriptors diff --git a/DescriptorManager.h b/DescriptorManager.h index a6093b2..f0673ba 100644 --- a/DescriptorManager.h +++ b/DescriptorManager.h @@ -29,6 +29,7 @@ public: void Init(); void rankImages(string image_name, int method); void rankMutations(string image_name, int method); + void runExperiments(); void outputMap(int a); void outputMap(); void DescriptorManager::outputRank(string imagename, int method); diff --git a/main.cpp b/main.cpp index a2f89ff..85a3dc1 100644 --- a/main.cpp +++ b/main.cpp @@ -40,11 +40,14 @@ int main(int argc, char **argv) { } InitializeMagick(*argv); DescriptorManager* manager = new DescriptorManager("data"); + cout << "Intializing..." << endl; manager->Init(); - manager->rankImages(imagename, method); - manager->rankMutations(imagename, method); + cout << "done!" << endl; + manager->runExperiments(); + //manager->rankImages(imagename, method); + //manager->rankMutations(imagename, method); //manager->outputMap(method); - manager->outputRank(imagename, method); + //manager->outputRank(imagename, method); //cout << "Loading descriptiors.."; //manager->loadDescriptors(); //manager->createMutations();