RGB to Propeller color code conversion routine with LUT
digimorf
Posts: 74
Hi to everybody.
I was working on some graphic demos, and I wanted to try to build a converter from RGB to Propeller color code without using complex math.
I started from the color table of Hydra book, and checked the corresponding rgb value steps along the Hue value.
I saw there are common colors such as blue, magenta, red etc... that correspond to limit rgb vales:
R0 G0 B255, for Blue
R255 G0 B255, for Magenta
R255 G0 B0, for Red
...
These have to correspond to
Hue 0
Hue 3
Hue 5
So I've just calculated the inbetween steps and put into a lookup table.
To get luma I've considered that the color get bright when all components tend to reach 255, and black when they tend to 0
So I have calculated a middle value between each component and remapped to 6 luminosity values.
Maybe it's not so accurate right now, this is a first attempt so it will need to be fixed for sure, but maybe it's a good starting point to develop a fast conversion routine.
In attachment the functions involved, and the VERY basic use of this routine for you to try in your application .This means no graphic but data results on Propeller serial terminal :P
Enjoy!
color_rgb2prop_001 - Archive [Date 2012.03.27 Time 20.31].zip
I was working on some graphic demos, and I wanted to try to build a converter from RGB to Propeller color code without using complex math.
I started from the color table of Hydra book, and checked the corresponding rgb value steps along the Hue value.
I saw there are common colors such as blue, magenta, red etc... that correspond to limit rgb vales:
R0 G0 B255, for Blue
R255 G0 B255, for Magenta
R255 G0 B0, for Red
...
These have to correspond to
Hue 0
Hue 3
Hue 5
So I've just calculated the inbetween steps and put into a lookup table.
To get luma I've considered that the color get bright when all components tend to reach 255, and black when they tend to 0
So I have calculated a middle value between each component and remapped to 6 luminosity values.
Maybe it's not so accurate right now, this is a first attempt so it will need to be fixed for sure, but maybe it's a good starting point to develop a fast conversion routine.
In attachment the functions involved, and the VERY basic use of this routine for you to try in your application .This means no graphic but data results on Propeller serial terminal :P
Enjoy!
color_rgb2prop_001 - Archive [Date 2012.03.27 Time 20.31].zip
Comments
If so, this is an interesting approach.
I'm using a 256 long look-up table to do this with values obtained from a screen capture.
But, maybe this is a better way...
I thought to use this to convert from rgb to propeller color format
so, from R0-255, G0-255, B0-255 I can have Hue << 4 | 8 | luma.
But with some work I think that the inverse way can be obtained...
But, maybe your way could be better and faster...
Oh really ? Great!
For now spin version is just for experiments and tests, but my intention is to optimize this into ASM. Of course the use of Lookup tablescan speed up things, especially for frame buffer based graphics.
I think about real-time dithering, color cycling effects, overlaying etc...
I really hope to achieve a smart and fast way to convert RGB to Hue/luma.
Once you've got the hue (H), it can be scaled to go from 0-15 and rotated mod 16 to align with the Prop's colorburst offset. Saturation (S) needs to be either of three values in the Prop, so a threshold will work there. (For the high saturation setting, the colorburst offset has to be rotated yet again by 8.) And value (V) can be rescaled to cover the Prop's intensity gamut.
The only question, in my mind, is whether Hue and the colorburst offset are linear w.r.t. each other. If not, you will have to convert RGB to YIQ first and use an arctan on the I and Q coordinates to get the colorburst offset.
-Phil
Yes I saw, but many are quite different each other, they use different way to obtain H, S, V
This can be useful, thanks.
I was trying to figure out how the saturation is involved in Propeller single color
Uhm, I wanted to find some way to not use trigonometric functions, that's why I've thought about a lookup table.
- Zero saturation for the handful of gray values.
- Low saturation, where the chroma amplitude is one.
- Supersaturation, which occurs at maximum intensity, where the chroma causes the intensity to overflow and roll over zero (sync level).
It's unlikely that you'd have to resort to this, since I will bet that there's a one-to-one mapping between hue and chroma phase.-Phil
Note: although the math is correct, the heuristics may not be correct for all RGB values.
Also, don't despair this is going to require floating point, square root and arctangent. You are mapping a 24 bit color space down to less than 7 bits. The intent is to get reasonably close for the majority of the values. There are some colors the Propeller simply is not going to be able to create. So it may be sufficient to approximate. IIRC sqrt( U*U + V*V ) can be approximated as max(abs(U),abs(V)) + min(abs(U),abs(V))/2 and for the arctan you are simply deciding which of the 16 hues will be used.
I have been working with Phil's color capture code quite extensively to analize the color I/Q and produce NTSC outouts
I am using 32 instead of 16 in the table to get better approximation to 33 degree rotation !
Perry
Down the bottom are some pictures using various algorithms. You can see the difference between the 'closest color' matches vs Floyd Steinberg. If you give the FS algorithm the actual palette it can work out the lighter yellows by, for example, dithering a dark yellow and a white pixel alternately.
There are also a large number of colors the propeller cannot display, eg all the grays with a little bit of color added. Again, dithering is a good workaround for this.
Sing out if you would like this vb.net code.
Right, looking at a propeller palette, the way saturation is treated in a different way and luma can't be managed as many formulas says.
For example searching the web for formulas, I've found one where the luma is equal to the maximum value between R, G, B, but:
For example, If I have R=255, G=0, B=0 ( a full saturated Red ) in Propeller I should have something like $56 or $57 ( Hue = 5, Luma = max ) , but if you see this color on a tv driver it is a light red instead.
That's why in my example I've took a medium value between the max and the min value in the RGB given range.
Of course the approach depends on the application where the color conversion has to be used, personally I'm working on a different approach without complex formulas and extra cogs to convert a value.