# Reverse engineering device RGB data

I'm working with a device that maps certain RGB colors to a 7 bit value (0-127):

I want to reverse the process, i.e. given any RGB triplet, what is the (closest) corresponding color index (0-127)? And I want to do so using the minimum number of parameters.

E.g.: assuming there is some kind of rule behind how these colors are mapped to the 0-127 index, cracking this rule results in a model with zero parameters and 100% accuracy, i.e. the best one.

But perhaps these colors have been thrown out more or less randomly, then the question is how to reconstruct the inverse mapping with these two characteristics:

• it covers most of the color indices (0-127) above (see below)
• it has high accuracy

To be precise: there should be an upper bound on the error made by the reconstructed mapping, so that at least N distinct colors are output for all input RGB values. For instance: approximating all the colors with a single average color is a bad solution, as it fails both points.

Here the same RGB values in CSV format:

0,0,0
37,37,37
143,143,143
253,253,253
255,101,92
255,40,18
110,10,3
34,1,0
255,199,124
255,108,29
110,40,6
48,31,2
255,248,77
255,248,63
108,105,21
32,31,2
148,247,81
83,246,60
30,104,20
25,51,6
69,247,81
9,246,59
2,104,19
0,30,2
67,247,104
9,246,59
2,104,19
0,30,2
64,248,151
4,247,93
1,104,34
0,36,19
57,248,193
0,247,167
0,105,67
0,31,19
63,204,252
0,184,252
0,82,99
0,20,31
73,158,251
0,112,250
0,41,107
0,7,32
79,105,250
0,60,249
0,20,108
0,2,32
146,106,250
91,61,249
23,24,119
8,8,64
255,112,250
255,71,250
109,25,107
33,3,32
255,105,149
255,44,101
110,13,36
44,2,19
255,51,19
173,71,16
142,99,21
80,116,23
1,70,10
0,101,67
0,103,143
0,60,249
0,85,95
10,50,214
143,143,143
43,43,43
255,40,18
200,247,62
186,235,58
107,247,60
3,149,32
0,247,148
0,184,252
0,70,249
56,61,249
134,63,249
194,52,142
83,43,5
255,97,26
151,225,55
122,247,60
9,246,59
9,246,59
87,247,127
0,249,213
92,158,251
40,104,207
145,147,237
218,70,250
255,45,108
255,144,37
199,187,45
158,247,61
150,111,24
74,52,6
16,92,19
0,97,72
23,26,53
13,47,107
126,77,35
188,25,10
233,103,73
229,125,31
255,227,58
171,225,55
116,189,44
35,38,63
229,249,117
136,249,199
164,173,252
154,128,250
81,81,81
135,135,135
228,252,253
181,24,9
69,3,1
6,211,50
1,79,12
199,187,45
79,62,9
195,112,26
93,28,3


Plotting the above values in various ways doesn't suggest anything obvious.

If bits are packed, maybe a Karnaugh map would help, however I am a bit rusty on how to apply the concept to this problem.

Other ways to solve the problem, e.g. by machine learning or dimensionality reduction?

• How is this a statistics/machine learning problem? The figure you show already has the mapping, so there doesn't seem anything to learn.
– Tim
Jun 20 at 14:42
• Perhaps it is more a dimensionality reduction problem: keeping all the 128*3 parameters and inverting the mapping on the fly is certainly one way to solve it; doing what I shown in my answer does basically the same, but sacrificing memory for computing speed. The question is wether there is a simpler (i.e. less parameters) way to express the inverse mapping f(r,g,b) --> [0-127], e.g. f(r,g,b) = a1*r + a2*g + a3*b + ... How is this not a machine learning problem? Jun 20 at 15:10
• So you don't need to reverse but rather want to learn to approximate the mapping? If so, please edit the question.
– Tim
Jun 20 at 15:45
• Also, your criteria are not precise: the solution with the smallest number of parameters is to approximate all the colors with a single average color. It would be a bad but smallest approximation.
– Tim
Jun 20 at 15:53
• If there exist a mathematical mapping, maybe some model exist that can learn it with 100% accuracy. "A single average color" are you serious? :D There are 128 colors, the mapping should output a similar if not the same number of colors. Jun 20 at 16:12

Here's an attempt using brute force, and being by far the worst possible solution in terms of number of parameters.

We choose a bit-resolution to represent every possible RGB triplet, and compute its closest (using euclidean distance) color amongst the 128 given colors. Then store each 0-127 color index in an array, at the position given by the binary representation of the RGB triplet.

With 6-bits/channel resolution, it is possible to cover 118 out of the 128 colors, at the expense of having to store 2^18 indices.

At 3-bits/channel resolution, it is possible to cover 108 out of the 128 colors, storing only 2^9 values, which seems a reasonable compromise:

rgb333ToColor = [
0, 47, 51, 46, 46, 69, 69, 45, 23, 39, 51, 42, 50, 69, 69, 45, 64, 123,
102, 38, 66, 69, 69, 79, 22, 30, 34, 68, 66, 66, 41, 41, 76, 76, 34,
66, 66, 66, 41, 41, 76, 122, 122, 122, 77, 33, 37, 37, 122, 122, 122,
29, 77, 33, 90, 37, 21, 21, 21, 29, 77, 33, 90, 90, 7, 55, 51, 50, 50,
69, 69, 80, 15, 1, 112, 50, 50, 69, 69, 80, 19, 71, 112, 104, 66, 92,
92, 80, 18, 18, 34, 68, 66, 92, 92, 41, 18, 76, 76, 66, 66, 92, 92, 40,
76, 122, 122, 24, 28, 32, 36, 36, 122, 122, 122, 24, 28, 32, 32, 36,
21, 21, 21, 24, 28, 32, 32, 90, 121, 59, 112, 54, 54, 50, 80, 80, 83,
71, 112, 54, 54, 69, 80, 80, 125, 125, 117, 117, 117, 92, 80, 80, 63,
63, 117, 117, 118, 92, 44, 44, 63, 63, 63, 118, 118, 92, 40, 40, 111,
111, 111, 24, 28, 32, 40, 36, 17, 17, 20, 24, 28, 32, 36, 36, 17, 17,
20, 24, 28, 32, 32, 36, 6, 58, 58, 54, 54, 54, 49, 49, 10, 58, 54, 54,
54, 49, 49, 49, 10, 105, 117, 117, 54, 49, 49, 49, 14, 14, 117, 118,
118, 118, 44, 44, 14, 14, 111, 118, 118, 2, 91, 91, 111, 111, 111, 118,
2, 2, 91, 91, 111, 111, 75, 89, 89, 114, 114, 36, 75, 75, 75, 89, 89,
114, 114, 114, 6, 58, 58, 54, 54, 82, 81, 81, 10, 58, 54, 54, 82, 82,
81, 81, 61, 105, 105, 54, 82, 82, 81, 81, 62, 99, 99, 118, 118, 2, 48,
48, 99, 99, 99, 118, 2, 2, 93, 93, 111, 111, 111, 2, 2, 2, 93, 115, 85,
85, 85, 16, 114, 114, 114, 115, 98, 98, 16, 16, 114, 114, 114, 114,
120, 120, 106, 82, 82, 82, 94, 94, 120, 106, 106, 82, 82, 82, 94, 94,
61, 61, 61, 82, 82, 82, 94, 94, 126, 126, 126, 118, 2, 2, 116, 116,
126, 126, 97, 2, 2, 2, 93, 116, 97, 97, 97, 2, 2, 2, 115, 115, 110,
110, 110, 16, 113, 114, 114, 115, 74, 74, 73, 16, 113, 114, 114, 119,
106, 106, 57, 57, 82, 82, 94, 94, 106, 106, 57, 95, 82, 82, 94, 94, 60,
84, 107, 82, 82, 82, 94, 94, 126, 108, 107, 107, 56, 56, 52, 52, 108,
108, 107, 107, 56, 56, 52, 52, 97, 97, 97, 8, 8, 8, 115, 115, 97, 97,
73, 113, 113, 8, 119, 119, 73, 73, 73, 113, 113, 113, 119, 119, 5, 5,
57, 57, 95, 95, 53, 53, 5, 5, 57, 95, 95, 95, 53, 53, 60, 84, 4, 95,
56, 56, 53, 53, 84, 9, 4, 4, 56, 56, 52, 52, 96, 96, 96, 4, 56, 56, 52,
52, 96, 96, 109, 8, 8, 8, 52, 52, 109, 109, 109, 8, 8, 8, 3, 3, 13, 13,
12, 113, 113, 113, 3, 3
]


then for finding the corresponding color-index, we normalize the RGB triplet to the range (0,0,0)-(7,7,7) and lookup at index 64*R+8*G+B which of the 128 colors it corresponds to.

This is not a learning model, and it doesn't try to explain how the colors were initially encoded (assuming there was a logic in it).

While this answer may seem a bit off topic here, I believe the original question is not, as there are many methods ranging from machine learning to dimensionality reduction to compression that can be used to approach the problem.

However it may serve as an example of a solution.