From 6c2c697a5838e94cf02bebf01425711058bcac53 Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Sat, 30 Jun 2018 14:17:13 +0200 Subject: [PATCH] Initial Commit Had to recreate repo because it was corrupted. FML. --- .gitignore | 48 +++ Descriptor.h | 406 ++++++++++++++++++++++++++ DescriptorManager.cpp | 142 +++++++++ DescriptorManager.h | 38 +++ Enumstrings.h | 27 ++ ReadMe.txt | 16 + SmallImageDescriptors.sln | 28 ++ SmallImageDescriptors.vcxproj | 172 +++++++++++ SmallImageDescriptors.vcxproj.filters | 39 +++ main.cpp | 50 ++++ style.css | 20 ++ targetver.h | 8 + 12 files changed, 994 insertions(+) create mode 100644 .gitignore create mode 100644 Descriptor.h create mode 100644 DescriptorManager.cpp create mode 100644 DescriptorManager.h create mode 100644 Enumstrings.h create mode 100644 ReadMe.txt create mode 100644 SmallImageDescriptors.sln create mode 100644 SmallImageDescriptors.vcxproj create mode 100644 SmallImageDescriptors.vcxproj.filters create mode 100644 main.cpp create mode 100644 style.css create mode 100644 targetver.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e5577f --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +data/ + +Debug/ + +x64/ + +meta/ + +web/ + +*.php + +*.png + +\.htaccess + +*.db + +include/ diff --git a/Descriptor.h b/Descriptor.h new file mode 100644 index 0000000..44e0012 --- /dev/null +++ b/Descriptor.h @@ -0,0 +1,406 @@ +#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 Descriptor { +public: + virtual bitset<64> feature(Image* img) = 0; + + //Interpret the bitsets as integers and calculate their distance. + virtual unsigned long long distance(bitset<64> a, bitset<64> b) { + return abs(((long long)a.to_ullong() - (long long)b.to_ullong())); + }; + virtual string ToString() = 0; + virtual fs::path ToPath() { + return fs::path(this->ToString()); + } + + //should return true if a > b + virtual bool bigger(bitset<64> a, bitset<64> b) { + return true; + } + + double* CalculateDCT(Image* img) { + double pi = 3.14159265359; + img->type(GrayscaleType); + img->filterType(LanczosFilter); //fast! + img->resize(Geometry(8, 8)); //64 pixels + ssize_t n = 8; + ssize_t m = 8; + Pixels view(*img); + int numpixels = (int)(n*m); + int chan = (int)img->channels(); //should be 1, just intensity + const Quantum *p = view.getConst(0, 0, n, m); //entire image + bitset<64> retval(0); + int N = n*m; + Image* newimg = new Image(Geometry(n, m), Color("white")); + newimg->type(GrayscaleType); + Pixels conview(*newimg); + Quantum *c = conview.get(0, 0, n, m); //entire converted image + + double converted[64]; + double* q = converted; + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + double sum = 0; + int k = (j*m) + i; + const Quantum *p_s = view.getConst(0, 0, n, m); //entire image + for (ssize_t x = 0; x < m; x++) { + for (ssize_t y = 0; y < n; y++) { + int n = (x*m) + y; + double pixel = ((double)p_s[0] / QuantumRange); //rescaled from 0 to 1 + //cout << "pixel: " << pixel << endl; + sum += pixel * std::cos((pi / N)*(n + 0.5)*k); + p_s = p_s + chan; + } + } + q[0] = sum; + /*if (p[0] != 0) + retval |= bitset<64>(1); //XOR + retval <<= 1;*/ + q = q++; + p = p + chan; + + } + } + for (int i = 0; i < 64; i++) { + c[0] = converted[i] * 255.0; + c++; + } + newimg->write("Out.png"); + return converted; + } +}; + +//Average color of the image. +//the least significant 24 bits of the feature represent +//the color intensity of the average color in RGB +//with 8 bits per color. +class averageColor : public Descriptor { +public: + bitset<64> feature(Image* img) { + ssize_t n = img->columns(); + ssize_t m = img->rows(); + Pixels view(*img); + const Quantum *p = view.getConst(0, 0, n, m); //entire image + unsigned long long red = 0, green = 0, blue = 0; + float numpixels = (float)(n*m); + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + //LTR scanning + red += p[0]; + green += p[1]; + blue += p[2]; + p = p + 3; + } + } + //get the color values.. implicit cast to int + int r = ((red/numpixels) / QuantumRange) * 255; + int g = ((green/numpixels) / QuantumRange) * 255; + int b = ((blue/numpixels) / QuantumRange) * 255; + //now store all this into a bitset.. assuming 8 bits per color, if everything went correctly.. which we should check.. probably.. + bitset<64> retval(r); + retval <<= 8; + retval |= bitset<64>(g); + retval <<= 8; + retval |= bitset<64>(b); + return retval; + } + unsigned long long distance(bitset<64> a, bitset<64> b) { + //do some bit shifting magic to get ints back + int red_a = (a >> 16).to_ulong(); + int green_a = (a << (64-16) >> (64-8)).to_ulong(); + int blue_a = (a << (64-8) >> (64-8)).to_ulong(); + int red_b = (b >> 16).to_ulong(); + int green_b = (b << (64 - 16) >> (64 - 8)).to_ulong(); + int blue_b = (b << (64 - 8) >> (64 - 8)).to_ulong(); + return abs(red_a - red_b) + abs(green_a - green_b) + abs(blue_a - blue_b); + }; + string ToString() { + return "averageColor"; + } +}; + +//Counts the total number of colors +//and stores it in bit representation. +//Upper limit 16777216 +//Only uses least significant 24 bits +class numColors : public Descriptor { +public: + bitset<64> feature(Image* img) { + return bitset<64>(img->totalColors()-1); + } + string ToString() { + return "numColors"; + } +}; + +//Median descriptor. See relevant literature. +//Stores a map of the image (LTR scanned) with 1 iff +//higher than median and 0 otherwise. +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 + ssize_t n = 8; + ssize_t m = 8; + Pixels view(*img); + 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 + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + //LTR scanning + intensities[index] = p[0]; + p = p + chan; + index++; + } + } + //Calculate median: + sort(intensities, intensities + numpixels); + //We know where the median is going to be: + intensity = (float)(intensities[31] + intensities[32]) / 2; + bitset<64> retval(0); + const Quantum *q = view.getConst(0, 0, n, m); //entire image + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + retval <<= 1; + if (q[0] > intensity) + retval |= bitset<64>(1); + q = q + img->channels(); + } + } + return retval; + } + + //biterror + unsigned long long distance(bitset<64> a, bitset<64> b) { + int biterror = 0; + for (int i = 0; i < 64; i++) { + if (a[i] != b[i]) biterror++; + } + return biterror; + } + string ToString() { + return "median"; + } +}; + +//Sobel descriptor +//Calculates average intensity of the image with +//sobel convolution applied in both directions +class sobel : public Descriptor { +public: + bitset<64> feature(Image* img) { + //TODO: Some preprocessing for this? + //img->reduceNoise(4.0); + img->type(GrayscaleType); + + //Apply sobel convolution + img->convolve(3, sobelX); + img->convolve(3, sobelY); + + ssize_t n = img->rows(); + ssize_t m = img->columns(); + + Pixels view(*img); + const Quantum *p = view.getConst(0, 0, m, n); //entire image + unsigned long long intensity = 0; + int chan = (int)img->channels(); + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + //LTR scanning + intensity += p[0]; + //cout << p[0] << " "; + p = p + chan; + } + //cout << endl; + } + int scaledIntensity = ((float)(intensity / (n*m)) / QuantumRange) * 255; + return bitset<64>(scaledIntensity); + } + string ToString() { + return "sobel"; + } +private: + const double sobelX[9] = { 1, 0, -1, 2, 0, -2, 1, 0, -1 }; + const double sobelY[9] = { 1, 2, 1, 0, 0, 0, -1, -2, -1 }; +}; + +//Peason code +//Creates a map of the 8*8 image which has 1 +//iff the pixel is higher than the next pixel, +//0 otherwise +class pearson : public Descriptor { +public: + bitset<64> feature(Image* img) { + img->type(GrayscaleType); + img->filterType(LanczosFilter); //fast! + img->resize(Geometry(8, 8)); //64 pixels + ssize_t n = 8; + ssize_t m = 8; + Pixels view(*img); + int intensity = 0; + int numpixels = (int)(n*m); + int chan = (int)img->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 + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + //LTR scanning + //NOTE: Scanning order might be quite relevant for this descriptor + int cur = p[0]; + if(prev < cur) retval |= bitset<64>(1); //XOR + prev = cur; + + p = p + chan; + retval <<= 1; + } + } + return retval; + } + unsigned long long distance(bitset<64> a, bitset<64> b) { + int biterror = 0; + for (int i = 0; i < 64; i++) { + if (a[i] != b[i]) biterror++; + } + return biterror; + }; + string ToString() { + return "pearson"; + } +}; + +//Uses an adaptive thresholding algorithm on an 8*8 +//images. Re-calculates the threshold for each 2*2 +//neighbourhood and stores it in a LTR map +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 + ssize_t n = 8; + ssize_t m = 8; + Pixels view(*img); + int numpixels = (int)(n*m); + int chan = (int)img->channels(); + const Quantum *p = view.getConst(0, 0, n, m); //entire image + bitset<64> retval(0); + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + //LTR scanning + //cout << p[0] << " "; + if(p[0] != 0) + retval |= bitset<64>(1); //XOR + retval <<= 1; + p = p + chan; + + } + //cout << endl; + } + //cout << "----" << endl << endl; + return retval; + } + unsigned long long distance(bitset<64> a, bitset<64> b) { + int biterror = 0; + for (int i = 0; i < 64; i++) { + if (a[i] != b[i]) biterror++; + } + return biterror; + }; + string ToString() { + return "threshold"; + } +}; + +//Uses an adaptive thresholding algorithm on an 8*8 +//images. Re-calculates the threshold for each 2*2 +//neighbourhood and stores it in a LTR map +class DCTPearson: public Descriptor { +public: + bitset<64> feature(Image* img) { + img->type(GrayscaleType); + img->filterType(LanczosFilter); //fast! + img->resize(Geometry(8, 8)); //64 pixels + ssize_t n = 8; + ssize_t m = 8; + Pixels view(*img); + int numpixels = (int)(n*m); + int chan = (int)img->channels(); //should be 1, just intensity + const Quantum *p = view.getConst(0, 0, n, m); //entire image + bitset<64> retval(0); + int N = n*m; + /*Image* converted = new Image(Geometry(n, m), Color("white")); + Pixels conview(*converted); + const Quantum *q = conview.getConst(0, 0, n, m); //entire converted image*/ + + double* converted = CalculateDCT(img); + /*double* q = converted; + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + double sum = 0; + int k = (j*m) + i; + const Quantum *p_s = view.getConst(0, 0, n, m); //entire image + for (ssize_t x = 0; x < m; x++) { + for (ssize_t y = 0; y < n; y++) { + int n = (x*m) + y; + double pixel = ((double)p_s[0] / QuantumRange); //rescaled from 0 to 1 + //cout << "pixel: " << pixel << endl; + sum += pixel * std::cos((pi/N)*(n+0.5)*k); + p_s = p_s + chan; + } + } + q[0] = sum; + q = q++; + p = p + chan; + + } + //cout << endl; + }*/ + double prev = 0; + for (int i = 0; i < 64; i++) { + if (converted[i] > prev) { + retval |= bitset<64>(1); //XOR + //cout << "1"; + } + //else cout << "0"; + retval <<= 1; + prev = converted[i]; + } + //cout << "----" << endl << endl; + return retval; + } + unsigned long long distance(bitset<64> a, bitset<64> b) { + int biterror = 0; + for (int i = 0; i < 64; i++) { + if (a[i] != b[i]) biterror++; + } + return biterror; + }; + string ToString() { + return "Discrete Cosine Transform"; + } +private: + double pi = 3.14159265359; +}; \ No newline at end of file diff --git a/DescriptorManager.cpp b/DescriptorManager.cpp new file mode 100644 index 0000000..6c7cec8 --- /dev/null +++ b/DescriptorManager.cpp @@ -0,0 +1,142 @@ +#include "DescriptorManager.h" + +//Default constructor, don't use this +DescriptorManager::DescriptorManager() { + img_path = "data"; //default value +} + +//Sets image path and defines the image descriptors. +DescriptorManager::DescriptorManager(const fs::path & image_path) { + img_path = image_path; + + //Manual definitions.. SAD! + descriptor_types[6] = new DCTPearson(); + descriptor_types[5] = new threshold(); + descriptor_types[4] = new pearson(); + descriptor_types[3] = new sobel(); + descriptor_types[2] = new median(); + descriptor_types[1] = new numColors(); + descriptor_types[0] = new averageColor(); +} + +//No need to call destructor.. yet? +DescriptorManager::~DescriptorManager() { + //Do some clean-up? + //Realistically, when this gets destroyed the application is done anyway. +} + + +//Loads all images and determines the feature vectors +bool DescriptorManager::loadDescriptors() { + 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; + for (int i = 0; i < numDescriptors; i++) { + //cout << "waddup " << i << endl; + //folder to store descriptors; create if not exists + fs::path descriptorBase("meta" / descriptor_types[i]->ToPath()); + if (!fs::is_directory(descriptorBase)) + if (fs::create_directory(descriptorBase)) {} + //cout << descriptorBase << " created." << endl; + + //foreach image + for (fs::directory_iterator itr(img_path); itr != end_itr; ++itr) { + fs::path featurePath(descriptorBase / itr->path().stem()); + //string image_name = featurePath.filename().generic_string(); + 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[i][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(); + } + } + } + //cout << "ma qualle ide!" << endl; + /*for (map::iterator it = images.begin(); it != images.end(); ++it) { + cout << "sup?" << endl; + delete it->second; //free willy + }*/ + return true; +} + +//essentially insertion sort into a map +void DescriptorManager::similarImages(string image_name, int method, int numImages) { + bitset<64> target; + if (descriptors[method].count(image_name)) { //if image exists in map + target = descriptors[method][image_name]; + } + else { + Image* image = new Image; + image->read(image_name); //assuming http url + target = descriptor_types[method]->feature(image); + } //TODO: Add support for uploaded images + + //first we need all distances to this image.. and insert them in a sorted way + multiset > distances; //multiset is probably not needed, but who knows.. + for (map>::iterator it = descriptors[method].begin(); it != descriptors[method].end(); ++it) { + //cout << "ho " << endl; + unsigned long long d = descriptor_types[method]->distance(target, it->second); + pair p(d, it->first); + distances.insert(p); //pairs are compared by their first element.. + } + + int i = 0; + for (std::multiset>::iterator it = distances.begin(); it != distances.end() && i < numImages; ++it) { + //cout << "hey " << endl; + if (true || it->second != image_name) { + cout << it->second << endl; + i++; + } + } + + +} + +//outputs the gathered data to iostream +//can be called directly or is called by its overload +//assumes a < numDescriptors +void DescriptorManager::outputMap(int a) { + if (a != 6) return; + cout << "Outputting map " << descriptor_types[a]->ToString() << endl; + map> a_map = descriptors[a]; + if (a_map.begin() == a_map.end()) { + cout << "------------------------" << endl << "No data found" << endl << endl; + } + + for (map>::iterator it = a_map.begin(); it != a_map.end(); ++it) { + cout << it->first << " => " << it->second << " (" << it->second.to_ullong() << ")" << endl; + } +} + +//calls its buddy function to output all data to iostream +void DescriptorManager::outputMap() { + for (int i = 0; i < numDescriptors; i++) { + outputMap(i); + } +} \ No newline at end of file diff --git a/DescriptorManager.h b/DescriptorManager.h new file mode 100644 index 0000000..cc6b842 --- /dev/null +++ b/DescriptorManager.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "Descriptor.h" + +using namespace std; +using namespace Magick; + +//ENUM_STRING(descriptorss, (totalColors)(averageColor)(numDescriptors)) + +namespace fs = boost::filesystem; + +//Manager class for +class DescriptorManager { +public: + DescriptorManager(); + DescriptorManager(const fs::path & image_path); + ~DescriptorManager(); + bool loadDescriptors(); + void similarImages(string image_name, int method, int numImages); + void outputMap(int a); + void outputMap(); +private: + static const int numDescriptors = 7; //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]; +}; + diff --git a/Enumstrings.h b/Enumstrings.h new file mode 100644 index 0000000..c03fec0 --- /dev/null +++ b/Enumstrings.h @@ -0,0 +1,27 @@ +// Have enum names be convertible to strings +// From https://stackoverflow.com/a/5094430 +// by James McNellis +// with slight adjustments +// Retrieved 14-10-2017 +#include + +#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem) \ + case elem : return BOOST_PP_STRINGIZE(elem); + +#define ENUM_STRING(name, enumerators) \ + enum name { \ + BOOST_PP_SEQ_ENUM(enumerators) \ + }; \ + \ + inline const char* ToString(name v) \ + { \ + switch (v) \ + { \ + BOOST_PP_SEQ_FOR_EACH( \ + X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE, \ + name, \ + enumerators \ + ) \ + default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \ + } \ + } \ No newline at end of file diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..2968576 --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,16 @@ +JPEG descriptors - DCT +Color Layout Descriptor CLD - related to jpeg/mpeg... +Different scanning methods.. Zigzag scanning? Might matter! +Median descriptor -> Pearson code? up/down -> Local average +Color Histogram information ... Binning.. derived code +Invariance - some SIFT derived descriptor? +Combined descriptors + +Experiments + -Clear goals! -> finding near copies. dont expect too much. + -Big test! automated + -Finding near copies + -Transformations per image (scaling, cropping, text, rotation, noise, contrast, brightness, JPEG compression) + -Combinations of transformations + -Modify images -> test for invariance + -Keyword matching unlikely to work diff --git a/SmallImageDescriptors.sln b/SmallImageDescriptors.sln new file mode 100644 index 0000000..0f6ab72 --- /dev/null +++ b/SmallImageDescriptors.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SmallImageDescriptors", "SmallImageDescriptors.vcxproj", "{757D5AAF-32EE-484D-AD0D-B80A212A8870}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Debug|x64.ActiveCfg = Debug|x64 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Debug|x64.Build.0 = Debug|x64 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Debug|x86.ActiveCfg = Debug|Win32 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Debug|x86.Build.0 = Debug|Win32 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Release|x64.ActiveCfg = Release|x64 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Release|x64.Build.0 = Release|x64 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Release|x86.ActiveCfg = Release|Win32 + {757D5AAF-32EE-484D-AD0D-B80A212A8870}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/SmallImageDescriptors.vcxproj b/SmallImageDescriptors.vcxproj new file mode 100644 index 0000000..8d7fd72 --- /dev/null +++ b/SmallImageDescriptors.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {757D5AAF-32EE-484D-AD0D-B80A212A8870} + Win32Proj + SmallImageDescriptors + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + $(SolutionDir)\include;$(IncludePath) + $(SolutionDir)\lib;$(LibraryPath) + + + false + + + false + $(SolutionDir)\include;C:\Program Files\boost;$(IncludePath) + $(SolutionDir)\lib;C:\Program Files\boost\libs;C:\Program Files\boost\stage\lib64;$(LibraryPath) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + CORE_RL_Magick++_.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + CORE_RL_Magick++_.lib;%(AdditionalDependencies) + + + copy "$(TargetPath)" "$(SolutionDir)" + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SmallImageDescriptors.vcxproj.filters b/SmallImageDescriptors.vcxproj.filters new file mode 100644 index 0000000..efc2e5a --- /dev/null +++ b/SmallImageDescriptors.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a79f204 --- /dev/null +++ b/main.cpp @@ -0,0 +1,50 @@ +/*#include +#include +#include +#include + +#include +#include */ + +#include "DescriptorManager.h" +#include +#include +using namespace std; +using namespace Magick; + +//Methods: +//5 threshold +//4 pearson +//3 sobel +//2 median +//1 numColors +//0 averageColor + + +int main(int argc, char **argv) { + string imagename = "im71.jpg"; + int method = 2; + int count = 100; + if (argc > 2) { + method = atoi(argv[2]); + imagename = argv[1]; + } + if (argc > 3) { + count = atoi(argv[3]); + } + + else { + cout << "Usage: " << endl << argv[0] << " [fileName] [methodIndex]" << endl; + cout << "Continuing.." << endl; + } + InitializeMagick(*argv); + DescriptorManager* manager = new DescriptorManager("data"); + //cout << "Loading descriptiors.."; + manager->loadDescriptors(); + //cout << "done!" << endl << "Calculating distances.." << endl; + manager->similarImages(imagename, method, count); + //cout << "done!" << endl << "Outputting map.." << endl; + //manager->outputMap(); + + return 0; +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..a89a50d --- /dev/null +++ b/style.css @@ -0,0 +1,20 @@ +body,html { + margin:0px; + padding: 10px; + background: #e5e5f4; +} + +h1, h2, h3, h4 { + color: #2d4f99; +} + +#queryImage { + float:right; + position:fixed; + right:0px; +} + +#results { + float:left; + list-style-type: none; +} \ No newline at end of file diff --git a/targetver.h b/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include