Move DCT calculation
This commit is contained in:
+93
-51
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user