Move DCT calculation

This commit is contained in:
2019-03-18 16:45:15 +01:00
parent b314edb83f
commit 49cb8fa194
+93 -51
View File
@@ -40,50 +40,50 @@ public:
//Helper functions //Helper functions
//TODO: Move these somewhere else. Maybe a friend-class? //TODO: Move these somewhere else. Maybe a friend-class?
double* CalculateDCT(Image* img) { // double* CalculateDCT(Image* img) {
double pi = 3.14159265359; // double pi = 3.14159265359;
img->type(GrayscaleType); // img->type(GrayscaleType);
img->sample(Geometry("8x8!")); //64 pixels // img->sample(Geometry("8x8!")); //64 pixels
ssize_t n = 8; // ssize_t n = 8;
ssize_t m = 8; // ssize_t m = 8;
Pixels view(*img); // Pixels view(*img);
int chan = (int)img->channels(); //should be 1, just intensity // int chan = (int)img->channels(); //should be 1, just intensity
const Quantum *p = view.getConst(0, 0, n, m); //entire image // const Quantum *p = view.getConst(0, 0, n, m); //entire image
bitset<64> retval(0); // bitset<64> retval(0);
int N = n*m; // int N = n*m;
Image* newimg = new Image(Geometry(n, m), Color("white")); // Image* newimg = new Image(Geometry(n, m), Color("white"));
newimg->type(GrayscaleType); // newimg->type(GrayscaleType);
Pixels conview(*newimg); // Pixels conview(*newimg);
Quantum *c = conview.get(0, 0, n, m); //entire converted image // Quantum *c = conview.get(0, 0, n, m); //entire converted image
static double converted[64]; // static double converted[64];
double* q = converted; // double* q = converted;
for (ssize_t j = 0; j < m; j++) { // for (ssize_t j = 0; j < m; j++) {
for (ssize_t i = 0; i < n; i++) { // for (ssize_t i = 0; i < n; i++) {
double sum = 0; // double sum = 0;
int k = (j*m) + i; // int k = (j*m) + i;
const Quantum *p_s = view.getConst(0, 0, n, m); //entire image // const Quantum *p_s = view.getConst(0, 0, n, m); //entire image
for (ssize_t x = 0; x < m; x++) { // for (ssize_t x = 0; x < m; x++) {
for (ssize_t y = 0; y < n; y++) { // for (ssize_t y = 0; y < n; y++) {
int n = (x*m) + y; // int n = (x*m) + y;
double pixel = ((double)p_s[0] / QuantumRange); //rescaled to [0..1] // double pixel = ((double)p_s[0] / QuantumRange); //rescaled to [0..1]
sum += pixel * std::cos((pi / N)*(n + 0.5)*k); // sum += pixel * std::cos((pi / N)*(n + 0.5)*k);
p_s = p_s + chan; // p_s = p_s + chan;
} // }
} // }
q[0] = sum; // q[0] = sum;
q = q++; // q = q++;
p = p + chan; // p = p + chan;
} // }
} // }
for (int i = 0; i < 64; i++) { // for (int i = 0; i < 64; i++) {
c[0] = converted[i] * 255.0; // c[0] = converted[i] * 255.0;
c++; // c++;
} // }
delete newimg; // delete newimg;
//newimg->write("Out.png"); //for debugging purposes // //newimg->write("Out.png"); //for debugging purposes
return converted; // return converted;
} // }
}; };
//Average color of the image. //Average color of the image.
@@ -314,17 +314,13 @@ public:
bitset<64> retval(0); bitset<64> retval(0);
for (ssize_t j = 0; j < m; j++) { for (ssize_t j = 0; j < m; j++) {
for (ssize_t i = 0; i < n; i++) { for (ssize_t i = 0; i < n; i++) {
//LTR scanning
//cout << p[0] << " ";
if(p[0] != 0) if(p[0] != 0)
retval |= bitset<64>(1); //XOR retval |= bitset<64>(1); //XOR
retval <<= 1; retval <<= 1;
p = p + chan; p = p + chan;
} }
//cout << endl;
} }
//cout << "----" << endl << endl;
delete local_image; delete local_image;
return retval; 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 //Uses an adaptive thresholding algorithm on an 8*8
//images. Re-calculates the threshold for each 2*2 //images. Re-calculates the threshold for each 2*2
//neighbourhood and stores it in a LTR map //neighbourhood and stores it in a LTR map
class DCTPearson : public Descriptor { class DCTPearson : public DCTDescriptor {
public: public:
bitset<64> feature(Image* img) { bitset<64> feature(Image* img) {
Image* local_image = new Image(*img); Image* local_image = new Image(*img);
@@ -374,15 +410,21 @@ public:
void preview(Image* img){ void preview(Image* img){
Image* dct = new Image(*img); Image* dct = new Image(*img);
Image* local_image = new Image(*img); Image* local_image = new Image(*img);
double* converted = CalculateDCT(dct);
//double* converted = CalculateDCsT(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->type(GrayscaleType);
local_image->sample(Geometry("8x8!")); //64 pixels local_image->sample(Geometry("8x8!")); //64 pixels
local_image->write("DCTPearson.png"); local_image->write("DCTPearson.png");
} }
}; };
class DCTMedian : public Descriptor { class DCTMedian : public DCTDescriptor {
public: public:
bitset<64> feature(Image* img) { bitset<64> feature(Image* img) {
Image* local_image = new Image(*img); Image* local_image = new Image(*img);