#include #include #include #include //255,50,10 -> [55.6477, 73.3233, 65.9473] struct color { union { uint8_t v[3]; struct { uint8_t r; uint8_t g; uint8_t b; }; struct { int h; int s; int v; }; struct { float L; float A; float B; }; struct { float x; float y; float z; }; }; }; float lab_distance(struct color *c0, struct color *c1) { float sum=0.0f; sum += (c0->L - c1->L) * (c0->L - c1->L); sum += (c0->A - c1->A) * (c0->A - c1->A); sum += (c0->B - c1->B) * (c0->B - c1->B); return sqrtf(sum); } const float xyz_table[256] = { 0.000000f, 0.030353f, 0.060705f, 0.091058f, 0.121411f, 0.151763f, 0.182116f, 0.212469f, 0.242822f, 0.273174f, 0.303527f, 0.334654f, 0.367651f, 0.402472f, 0.439144f, 0.477695f, 0.518152f, 0.560539f, 0.604883f, 0.651209f, 0.699541f, 0.749903f, 0.802319f, 0.856812f, 0.913406f, 0.972122f, 1.032982f, 1.096009f, 1.161224f, 1.228649f, 1.298303f, 1.370208f, 1.444384f, 1.520851f, 1.599629f, 1.680737f, 1.764195f, 1.850022f, 1.938236f, 2.028857f, 2.121901f, 2.217388f, 2.315336f, 2.415763f, 2.518686f, 2.624122f, 2.732089f, 2.842604f, 2.955683f, 3.071344f, 3.189603f, 3.310476f, 3.433981f, 3.560131f, 3.688945f, 3.820436f, 3.954624f, 4.091520f, 4.231141f, 4.373503f, 4.518620f, 4.666508f, 4.817182f, 4.970656f, 5.126946f, 5.286066f, 5.448028f, 5.612849f, 5.780543f, 5.951124f, 6.124607f, 6.301003f, 6.480328f, 6.662595f, 6.847818f, 7.036011f, 7.227186f, 7.421358f, 7.618539f, 7.818743f, 8.021983f, 8.228271f, 8.437622f, 8.650046f, 8.865561f, 9.084172f, 9.305898f, 9.530748f, 9.758737f, 9.989874f, 10.224174f, 10.461649f, 10.702312f, 10.946172f, 11.193243f, 11.443539f, 11.697067f, 11.953843f, 12.213880f, 12.477184f, 12.743770f, 13.013649f, 13.286834f, 13.563335f, 13.843163f, 14.126330f, 14.412848f, 14.702728f, 14.995980f, 15.292616f, 15.592647f, 15.896087f, 16.202940f, 16.513222f, 16.826939f, 17.144112f, 17.464739f, 17.788841f, 18.116423f, 18.447498f, 18.782076f, 19.120165f, 19.461781f, 19.806931f, 20.155624f, 20.507870f, 20.863686f, 21.223072f, 21.586052f, 21.952623f, 22.322798f, 22.696589f, 23.074007f, 23.455065f, 23.839766f, 24.228119f, 24.620140f, 25.015837f, 25.415215f, 25.818291f, 26.225073f, 26.635567f, 27.049786f, 27.467737f, 27.889431f, 28.314880f, 28.744089f, 29.177071f, 29.613832f, 30.054384f, 30.498737f, 30.946899f, 31.398874f, 31.854683f, 32.314323f, 32.777817f, 33.245159f, 33.716366f, 34.191444f, 34.670406f, 35.153271f, 35.640026f, 36.130688f, 36.625271f, 37.123775f, 37.626221f, 38.132610f, 38.642952f, 39.157257f, 39.675529f, 40.197788f, 40.724026f, 41.254269f, 41.788513f, 42.326775f, 42.869057f, 43.415371f, 43.965725f, 44.520126f, 45.078583f, 45.641106f, 46.207706f, 46.778385f, 47.353153f, 47.932022f, 48.514999f, 49.102089f, 49.693306f, 50.288658f, 50.888145f, 51.491779f, 52.099567f, 52.711521f, 53.327648f, 53.947960f, 54.572456f, 55.201149f, 55.834049f, 56.471165f, 57.112492f, 57.758053f, 58.407848f, 59.061890f, 59.720188f, 60.382740f, 61.049568f, 61.720665f, 62.396049f, 63.075722f, 63.759697f, 64.447975f, 65.140572f, 65.837494f, 66.538734f, 67.244324f, 67.954254f, 68.668549f, 69.387192f, 70.110199f, 70.837593f, 71.569359f, 72.305527f, 73.046089f, 73.791054f, 74.540436f, 75.294235f, 76.052460f, 76.815125f, 77.582237f, 78.353790f, 79.129807f, 79.910286f, 80.695236f, 81.484665f, 82.278587f, 83.076996f, 83.879913f, 84.687332f, 85.499268f, 86.315727f, 87.136719f, 87.962234f, 88.792320f, 89.626945f, 90.466133f, 91.309868f, 92.158203f, 93.011093f, 93.868591f, 94.730659f, 95.597351f, 96.468628f, 97.344543f, 98.225060f, 99.110222f, 100.000000f }; void rgb2lab (struct color *rgb, struct color *lab) { float v[3]; float x,y,z; const float c = 16.0f/ 116.0f; v[0] = xyz_table[rgb->v[0]]; v[1] = xyz_table[rgb->v[1]]; v[2] = xyz_table[rgb->v[2]]; x = (v[0] * 0.4124f + v[1] * 0.3576f + v[2] * 0.1805f) / 95.047f ; y = (v[0] * 0.2126f + v[1] * 0.7152f + v[2] * 0.0722f) / 100.0f ; z = (v[0] * 0.0193f + v[1] * 0.1192f + v[2] * 0.9505f) / 108.883f ; x = (x>0.008856f)? cbrtf(x) : (x * 7.787f) + c; y = (y>0.008856f)? cbrtf(y) : (y * 7.787f) + c; z = (z>0.008856f)? cbrtf(z) : (z * 7.787f) + c; lab->L = (116.0f * y-16.0f); lab->A = (500.0f * (x-y)); lab->B = (200.0f * (y-z)); } static inline int fround(float flt) { return (int) floor(flt+0.5f); } int main(int argc, char **argv) { struct color lab1={0}; struct color rgb1={0}; uint8_t p0,p1; uint16_t c = 0; printf("#include \n"); printf("const int8_t lab_table[196608] = {\n"); for (int i=0; i<65536; i++, c++) { p0 = ((char*)&c)[0]; p1 = ((char*)&c)[1]; /* map RGB565 to RGB888 */ rgb1.r = (uint8_t) (p0>>3) * 255/31; rgb1.g = (uint8_t) (((p0&0x07)<<3) | (p1>>5)) * 255/63; rgb1.b = (uint8_t) (p1&0x1F) * 255/31; rgb2lab(&rgb1, &lab1); printf("%d, %d, %d, ", fround(lab1.L), fround(lab1.A), fround(lab1.B)); if ((i+1)%9==0) { printf("\n"); } } printf("};\n"); return 0; }