From 49cb8fa194671ee4e479c73f402177b9f908bb38 Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Mon, 18 Mar 2019 16:45:15 +0100 Subject: [PATCH] Move DCT calculation --- Descriptor.h | 144 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 51 deletions(-) diff --git a/Descriptor.h b/Descriptor.h index d3538d0..b8efce2 100644 --- a/Descriptor.h +++ b/Descriptor.h @@ -40,50 +40,50 @@ public: //Helper functions //TODO: Move these somewhere else. Maybe a friend-class? - double* CalculateDCT(Image* img) { - double pi = 3.14159265359; - img->type(GrayscaleType); - img->sample(Geometry("8x8!")); //64 pixels - ssize_t n = 8; - ssize_t m = 8; - Pixels view(*img); - 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* CalculateDCT(Image* img) { + // double pi = 3.14159265359; + // img->type(GrayscaleType); + // img->sample(Geometry("8x8!")); //64 pixels + // ssize_t n = 8; + // ssize_t m = 8; + // Pixels view(*img); + // 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 - static 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 to [0..1] - sum += pixel * std::cos((pi / N)*(n + 0.5)*k); - p_s = p_s + chan; - } - } - q[0] = sum; - q = q++; - p = p + chan; - } - } - for (int i = 0; i < 64; i++) { - c[0] = converted[i] * 255.0; - c++; - } - delete newimg; - //newimg->write("Out.png"); //for debugging purposes - return converted; - } + // static 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 to [0..1] + // sum += pixel * std::cos((pi / N)*(n + 0.5)*k); + // p_s = p_s + chan; + // } + // } + // q[0] = sum; + // q = q++; + // p = p + chan; + // } + // } + // for (int i = 0; i < 64; i++) { + // c[0] = converted[i] * 255.0; + // c++; + // } + // delete newimg; + // //newimg->write("Out.png"); //for debugging purposes + // return converted; + // } }; //Average color of the image. @@ -314,17 +314,13 @@ public: 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; delete local_image; return retval; } @@ -340,10 +336,50 @@ public: } }; +//subclass of descriptor which has a DCT converstion function +//to be subclassed by all descriptors that use DCT. +class DCTDescriptor : public Descriptor { +public: + double* CalculateDCT(Image* pimg) { + //make a local copy of the image and convert to 8x8 grayscale: + Image* img = new Image(*pimg); + double pi = 3.14159265359; + img->type(GrayscaleType); + img->sample(Geometry("8x8!")); //64 pixels + ssize_t n = 8; + ssize_t m = 8; + int N = n*m; + + //make pointers and views of the image + Pixels view(*img); + int chan = (int)img->channels(); //should be 1, just intensity + double* converted = new double[64]; + + for (ssize_t j = 0; j < m; j++) { + for (ssize_t i = 0; i < n; i++) { + double sum = 0; + const Quantum *p_s = view.getConst(0, 0, n, m); //entire image + int k = (i*m) + j; + for (ssize_t x = 0; x < m; x++) { + for (ssize_t y = 0; y < n; y++) { + int n = (y*m) + x; + double pixel = (((double)p_s[0] / QuantumRange)-0.5)*255; //rescaled to [-127..128] + sum += pixel * std::cos((pi / N)*(n + 0.5)*k); + p_s = p_s + chan; //next pixel + } + } + converted[k] = sum; + } + } + return converted; + } +}; + + //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 { +class DCTPearson : public DCTDescriptor { public: bitset<64> feature(Image* img) { Image* local_image = new Image(*img); @@ -374,15 +410,21 @@ public: void preview(Image* img){ Image* dct = new Image(*img); Image* local_image = new Image(*img); - - //double* converted = CalculateDCsT(dct); + double* converted = CalculateDCT(dct); + cout << "---" << endl; + for (int i = 0; i < 64; i++) { + cout << setw(11) << converted[i] << " | "; + if ( i % 8 == 7) cout << endl; + } + cout << "---" << endl; + //Write transformed image local_image->type(GrayscaleType); local_image->sample(Geometry("8x8!")); //64 pixels local_image->write("DCTPearson.png"); } }; -class DCTMedian : public Descriptor { +class DCTMedian : public DCTDescriptor { public: bitset<64> feature(Image* img) { Image* local_image = new Image(*img);