Finished updating tables.

With new RGB565<->RGB888 scaling. This included redoing the LAB/YUV/XYZ
tables. I translated the table gen code to python also and added
comments as to where the math came from.

And yes, I tested and compared the tables to make sure they weren't
borken. The tables are slightly different... but, if look at the
progression of values loosely you'll see the triplets are very close to
each other when doing a compare. This is to be expected given I used a
slightly better scaling algo.
This commit is contained in:
Kwabena W. Agyeman 2016-02-16 19:37:19 -05:00
parent 6699ea4d0e
commit 88f37014f1
8 changed files with 32886 additions and 14796 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,34 @@
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
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.856813f,
0.913406f, 0.972122f, 1.032982f, 1.096009f, 1.161225f, 1.228649f, 1.298303f, 1.370208f,
1.444384f, 1.520851f, 1.599629f, 1.680738f, 1.764195f, 1.850022f, 1.938236f, 2.028856f,
2.121901f, 2.217388f, 2.315337f, 2.415763f, 2.518686f, 2.624122f, 2.732089f, 2.842604f,
2.955683f, 3.071344f, 3.189603f, 3.310477f, 3.433981f, 3.560131f, 3.688945f, 3.820437f,
3.954624f, 4.091520f, 4.231141f, 4.373503f, 4.518620f, 4.666509f, 4.817182f, 4.970657f,
5.126946f, 5.286065f, 5.448028f, 5.612849f, 5.780543f, 5.951124f, 6.124605f, 6.301002f,
6.480327f, 6.662594f, 6.847817f, 7.036010f, 7.227185f, 7.421357f, 7.618538f, 7.818742f,
8.021982f, 8.228271f, 8.437621f, 8.650046f, 8.865559f, 9.084171f, 9.305896f, 9.530747f,
9.758735f, 9.989873f, 10.224173f, 10.461648f, 10.702310f, 10.946171f, 11.193243f, 11.443537f,
11.697067f, 11.953843f, 12.213877f, 12.477182f, 12.743768f, 13.013648f, 13.286832f, 13.563333f,
13.843162f, 14.126329f, 14.412847f, 14.702727f, 14.995979f, 15.292615f, 15.592646f, 15.896084f,
16.202938f, 16.513219f, 16.826940f, 17.144110f, 17.464740f, 17.788842f, 18.116424f, 18.447499f,
18.782077f, 19.120168f, 19.461783f, 19.806932f, 20.155625f, 20.507874f, 20.863687f, 21.223076f,
21.586050f, 21.952620f, 22.322796f, 22.696587f, 23.074005f, 23.455058f, 23.839757f, 24.228112f,
24.620133f, 25.015828f, 25.415209f, 25.818285f, 26.225066f, 26.635560f, 27.049779f, 27.467731f,
27.889426f, 28.314874f, 28.744084f, 29.177065f, 29.613827f, 30.054379f, 30.498731f, 30.946892f,
31.398871f, 31.854678f, 32.314321f, 32.777810f, 33.245154f, 33.716362f, 34.191442f, 34.670406f,
35.153260f, 35.640014f, 36.130678f, 36.625260f, 37.123768f, 37.626212f, 38.132601f, 38.642943f,
39.157248f, 39.675523f, 40.197778f, 40.724021f, 41.254261f, 41.788507f, 42.326767f, 42.869050f,
43.415364f, 43.965717f, 44.520119f, 45.078578f, 45.641102f, 46.207700f, 46.778380f, 47.353150f,
47.932018f, 48.514994f, 49.102085f, 49.693300f, 50.288646f, 50.888132f, 51.491767f, 52.099557f,
52.711513f, 53.327640f, 53.947949f, 54.572446f, 55.201140f, 55.834039f, 56.471151f, 57.112483f,
57.758044f, 58.407842f, 59.061884f, 59.720179f, 60.382734f, 61.049557f, 61.720656f, 62.396039f,
63.075714f, 63.759687f, 64.447968f, 65.140564f, 65.837482f, 66.538730f, 67.244316f, 67.954247f,
68.668531f, 69.387176f, 70.110189f, 70.837578f, 71.569350f, 72.305513f, 73.046074f, 73.791041f,
74.540421f, 75.294222f, 76.052450f, 76.815115f, 77.582222f, 78.353779f, 79.129794f, 79.910274f,
80.695226f, 81.484657f, 82.278575f, 83.076988f, 83.879901f, 84.687323f, 85.499261f, 86.315721f,
87.136712f, 87.962240f, 88.792312f, 89.626935f, 90.466117f, 91.309865f, 92.158186f, 93.011086f,
93.868573f, 94.730654f, 95.597335f, 96.468625f, 97.344529f, 98.225055f, 99.110210f, 100.000000f
};

File diff suppressed because it is too large Load Diff

59
util/gen_rgb2lab.py Normal file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://en.wikipedia.org/wiki/SRGB (The reverse transformation)
def lin(c):
return 100 * ((c/12.92) if (c<=0.04045) else pow((c+0.055)/1.055, 2.4))
import sys
sys.stdout.write("#include <stdint.h>\n")
sys.stdout.write("const int8_t lab_table[196608] = {\n") # 65536 * 3
for i in range(65536):
r = ((((i >> 3) & 31) * 255) + 15.5) // 31
g = (((((i & 7) << 3) | (i >> 13)) * 255) + 31.5) // 63
b = ((((i >> 8) & 31) * 255) + 15.5) // 31
# https://en.wikipedia.org/wiki/SRGB (The reverse transformation)
r_lin = lin(r / 255.0)
g_lin = lin(g / 255.0)
b_lin = lin(b / 255.0)
x = (r_lin * 0.4124) + (g_lin * 0.3576) + (b_lin * 0.1805);
y = (r_lin * 0.2126) + (g_lin * 0.7152) + (b_lin * 0.0722);
z = (r_lin * 0.0193) + (g_lin * 0.1192) + (b_lin * 0.9505);
# https://en.wikipedia.org/wiki/Lab_color_space (CIELAB-CIEXYZ conversions)
def f(t):
return pow(t, (1/3.0)) if (t>0.008856) else ((7.787037*t)+0.137931)
x = f(x / 095.047)
y = f(y / 100.000)
z = f(z / 108.883)
l = int(round(116 * y)) - 16;
a = int(round(500 * (x-y)));
b = int(round(200 * (y-z)));
sys.stdout.write(" %4d, %4d, %4d" % (l, a, b))
if (i + 1) % 4:
sys.stdout.write(", ")
elif i != 65535:
sys.stdout.write(",\n")
else:
sys.stdout.write("\n};\n")
sys.stdout.write("const float xyz_table[256] = {\n")
for i in range(256):
if not (i % 8):
sys.stdout.write(" ")
sys.stdout.write("%9.6ff" % lin(i / 255.0))
if (i + 1) % 8:
sys.stdout.write(", ")
elif i != 255:
sys.stdout.write(",\n")
else:
sys.stdout.write("\n};\n")

25
util/gen_rgb2yuv.py Normal file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
sys.stdout.write("#include <stdint.h>\n")
sys.stdout.write("const int8_t yuv_table[196608] = {\n") # 65536 * 3
for i in range(65536):
r = ((((i >> 3) & 31) * 255) + 15.5) // 31
g = (((((i & 7) << 3) | (i >> 13)) * 255) + 31.5) // 63
b = ((((i >> 8) & 31) * 255) + 15.5) // 31
# https://en.wikipedia.org/wiki/YCbCr (ITU-R BT.601 conversion)
y = int((r * +0.299000) + (g * +0.587000) + (b * +0.114000)) - 128;
u = int((r * -0.168736) + (g * -0.331264) + (b * +0.500000));
v = int((r * +0.500000) + (g * -0.418688) + (b * -0.081312));
sys.stdout.write(" %4d, %4d, %4d" % (y, u, v))
if (i + 1) % 4:
sys.stdout.write(", ")
elif i != 65535:
sys.stdout.write(",\n")
else:
sys.stdout.write("\n};\n")

View File

@ -1,132 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
//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 <stdint.h>\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;
}

View File

@ -1,40 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv)
{
int r, g, b;
int y, u, v;
uint8_t p0, p1;
uint16_t c = 0;
printf("#include <stdint.h>\n");
printf("const int8_t yuv_table[196608] = {\n");
for (int i=0; i<65536; i++, c++) {
p0 = ((char*)&c)[0];
p1 = ((char*)&c)[1];
// Convert RGB565 to RGB888
r = (p0>>3) * 255/31;
g = (((p0&0x07)<<3) | (p1>>5)) * 255/63;
b = (p1&0x1F) * 255/31;
// Convert RGB888 to YUV
// ITU-R 601 coefficients
// Note this will generate signed YUV values
y = r * +0.29900f + g * +0.58700f + b * +0.11400f-128;
u = r * -0.16874f + g * -0.33126f + b * +0.50000f;
v = r * +0.50000f + g * -0.41869f + b * -0.08131f;
printf("%d, %d, %d, ", y, u, v);
if ((i+1)%9==0) {
printf("\n");
}
}
printf("};\n");
return 0;
}

View File

@ -1,28 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv)
{
printf("#include <stdint.h>\n");
printf("const float xyz_table[256] = {\n ");
for (int i=0; i<256; i++) {
float t = i/255.0f;
if (t > 0.04045f) {
t = powf(((t+0.055f) / 1.055f), 2.4f);
} else {
t/= 12.92f;
}
t*=100.0f;
printf("%.6ff, ", t);
if (i==255) {
printf("\n");
} else if ((i+1)%8==0) {
printf("\n ");
}
}
printf("};\n");
return 0;
}