1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#include <cstdio>
#include <cstdlib>
#include <stdint.h>
#include <cmath>
#define RED_OFFSET 0
#define GREEN_OFFSET 1
#define BLUE_OFFSET 2
enum SIGNATURE {
RGBMEAN, RGBVAR, RGBSKU, RGBKER, RGBVEC,
RMEAN, RVAR, RSKU, RKER, RVEC,
GMEAN, GVAR, GSKU, GKER, GVEC,
BMEAN, BVAR, BSKU, BKER, BVEC
};
void computeSignature(uint8_t *RGBimage, int width, int height, int useEntropy, double *signature);
int main(){
int i;
uint8_t data[3000000];
double signature[20];
for ( i = 0; i < 3000000; i += 3) {
data[i] = i;
data[i + 1] = i % 127;
data[i + 2] = i * 2;
}
ALTcomputeSignature(data, 1000, 1000, 0, signature);
ALTcomputeSignature(data, 1000, 1000, 1, signature);
printf("DONE\n");
}
double x_log2_x(uint64_t x){
return (x==0) ? 0 : (double)x*log2((double)x); //use log(x)/log(2.) if this doesnt work
}
void computeSignature(uint8_t *RGBimage, int width, int height, int useEntropy, double *signature) {
size_t i;
size_t size = width*height;
uint8_t *grayImage = (uint8_t*) malloc(size*sizeof(uint8_t));
uint8_t *data;
uint64_t redHistogram[256], greenHistogram[256], blueHistogram[256], grayHistogram[256];
double redEntropy[256], greenEntropy[256], blueEntropy[256], grayEntropy[256];
for(i=0; i<20; i++) signature[i] = 0;
for(i = 0, data = RGBimage; i < size; i++, data += 3)
grayImage[i] = (uint8_t) ((double)(data[RED_OFFSET] + data[GREEN_OFFSET] + data[BLUE_OFFSET]) / 3);
for (i = 0, data = RGBimage; i < size; i++, data += 3){
grayHistogram[ grayImage[i] ]++;
redHistogram[ data[ RED_OFFSET ] ]++;
greenHistogram[ data[ GREEN_OFFSET ] ]++;
blueHistogram[ data[ BLUE_OFFSET ] ]++;
}
if (useEntropy) {
for (i = 0; i < 256; i++){
grayEntropy[i] = x_log2_x(grayHistogram[i]);
redEntropy[i] = x_log2_x(redHistogram[i]);
greenEntropy[i] = x_log2_x(greenHistogram[i]);
blueEntropy[i] = x_log2_x(blueHistogram[i]);
}
for (i = 0, data = RGBimage; i < size; i++, data += 3) {
signature[RGBMEAN] += grayEntropy[grayImage[i]];
signature[RMEAN] += redEntropy[data[RED_OFFSET]];
signature[GMEAN] += greenEntropy[data[GREEN_OFFSET]];
signature[BMEAN] += blueEntropy[data[RED_OFFSET]];
}
signature[RGBMEAN] /= size;
signature[RMEAN] /= size;
signature[GMEAN] /= size;
signature[BMEAN] /= size;
for (i = 0, data = RGBimage; i < size; i++, data += 3) {
signature[RGBVAR] += pow(grayEntropy[grayImage[i]] - signature[RGBMEAN], 2.);
signature[RVAR] += pow(redEntropy[data[RED_OFFSET]] - signature[RMEAN], 2.);
signature[GVAR] += pow(greenEntropy[data[GREEN_OFFSET]] - signature[GMEAN], 2.);
signature[BVAR] += pow(blueEntropy[data[RED_OFFSET]] - signature[BMEAN], 2.);
signature[RGBSKU] += pow(grayEntropy[grayImage[i]] - signature[RGBMEAN], 3.);
signature[RSKU] += pow(redEntropy[data[RED_OFFSET]] - signature[RMEAN], 3.);
signature[GSKU] += pow(greenEntropy[data[GREEN_OFFSET]] - signature[GMEAN], 3.);
signature[BSKU] += pow(blueEntropy[data[RED_OFFSET]] - signature[BMEAN], 3.);
signature[RGBKER] += pow(grayEntropy[grayImage[i]] - signature[RGBMEAN], 4.);
signature[RKER] += pow(redEntropy[data[RED_OFFSET]] - signature[RMEAN], 4.);
signature[GKER] += pow(greenEntropy[data[GREEN_OFFSET]] - signature[GMEAN], 4.);
signature[BKER] += pow(blueEntropy[data[RED_OFFSET]] - signature[BMEAN], 4.);
}
for (i = 0; i < 256; i++) {
signature[RGBVEC] += pow(grayEntropy[i], 2.);
signature[RVEC] += pow(redEntropy[i], 2.);
signature[GVEC] += pow(greenEntropy[i], 2.);
signature[BVEC] += pow(blueEntropy[i], 2.);
}
}else{
for (i = 0, data = RGBimage; i < size; i++, data += 3) {
signature[RGBMEAN] += grayImage[i];
signature[RMEAN] += data[RED_OFFSET];
signature[GMEAN] += data[GREEN_OFFSET];
signature[BMEAN] += data[RED_OFFSET];
}
signature[RGBMEAN] /= size;
signature[RMEAN] /= size;
signature[GMEAN] /= size;
signature[BMEAN] /= size;
for (i = 0, data = RGBimage; i < size; i++, data += 3) {
signature[RGBVAR] += pow(grayImage[i] - signature[RGBMEAN], 2.);
signature[RVAR] += pow(data[RED_OFFSET] - signature[RMEAN], 2.);
signature[GVAR] += pow(data[GREEN_OFFSET] - signature[GMEAN], 2.);
signature[BVAR] += pow(data[RED_OFFSET] - signature[BMEAN], 2.);
signature[RGBSKU] += pow(grayImage[i] - signature[RGBMEAN], 3.);
signature[RSKU] += pow(data[RED_OFFSET] - signature[RMEAN], 3.);
signature[GSKU] += pow(data[GREEN_OFFSET] - signature[GMEAN], 3.);
signature[BSKU] += pow(data[RED_OFFSET] - signature[BMEAN], 3.);
signature[RGBKER] += pow(grayImage[i] - signature[RGBMEAN], 4.);
signature[RKER] += pow(data[RED_OFFSET] - signature[RMEAN], 4.);
signature[GKER] += pow(data[GREEN_OFFSET] - signature[GMEAN], 4.);
signature[BKER] += pow(data[RED_OFFSET] - signature[BMEAN], 4.);
}
for (i = 0; i < 256; i++) {
signature[RGBVEC] += pow(grayHistogram[i], 2.);
signature[RVEC] += pow(redHistogram[i], 2.);
signature[GVEC] += pow(greenHistogram[i], 2.);
signature[BVEC] += pow(blueHistogram[i], 2.);
}
}
signature[RGBVAR] /= size;
signature[RVAR] /= size;
signature[GVAR] /= size;
signature[BVAR] /= size;
signature[RGBSKU] /= (size * pow(sqrt(signature[RGBVAR]), 3.));
signature[RSKU] /= (size * pow(sqrt(signature[RVAR]), 3.));
signature[GSKU] /= (size * pow(sqrt(signature[GVAR]), 3.));
signature[BSKU] /= (size * pow(sqrt(signature[BVAR]), 3.));
signature[RGBKER] /= (size * pow(sqrt(signature[RGBVAR]), 4.));
signature[RKER] /= (size * pow(sqrt(signature[RVAR]), 4.));
signature[GKER] /= (size * pow(sqrt(signature[GVAR]), 4.));
signature[BKER] /= (size * pow(sqrt(signature[BVAR]), 4.));
signature[RGBVEC] = sqrt(signature[RGBVEC]) / (256.0);
signature[RVEC] = sqrt(signature[RVEC]) / (256.0);
signature[GVEC] = sqrt(signature[GVEC]) / (256.0);
signature[BVEC] = sqrt(signature[BVEC]) / (256.0);
free(grayImage);
}
|