Converting colours to MD

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
Zontar
Very interested
Posts: 55
Joined: Fri Oct 21, 2011 8:58 pm

Converting colours to MD

Post by Zontar » Sat Nov 08, 2014 8:23 pm

I'm not quite sure I'm mapping colours properly from RRGGBB to Sega BGR.

The image I'm starting with is a 4bpp image, only sixteen colours. Here is the image (converted from 4bpp BMP to PNG, same colours though):

Image

So what I'm doing to convert colours is taking the upper nibble of each component. So 5b3839 (BBGGRR) would become 0x0533, for example. This gives an image that is close to the original, but still bright in some areas and darker than others:

Image

This could just be technical limitations of the hardware, but I would like to make sure first. Is taking the upper nibble of each component the correct way to convert a 24-bit colour to Sega format? Or is there another part I'm missing?

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Sat Nov 08, 2014 11:42 pm

24bitRGBvalue / (255 / 7) = MDvalue
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Nov 09, 2014 3:40 am

I'd suggest rounding the values as well. There's 2 between each level, and if you just truncate the value, something that is closer to 2 will still be 0.

r57shell
Very interested
Posts: 478
Joined: Sun Dec 23, 2012 1:30 pm
Location: Russia
Contact:

Post by r57shell » Sun Nov 09, 2014 2:15 pm

Color conversion = find closest from available.
So, there are several questions
1) what is available
2) what is closest
3) how to find

1) What is available.
I'll introduce two approach.

Simplest.

In this "method" we will deal with components separately.
For each component R, G, B make linear interpolation from black = #00 to white = #FF.

We have to interpolate 0x0 .. 0xE -> 0x00 .. 0xFF. Simplest way to do it, is interpolate both from 0 to 1:
md color = t*0xE
32 bit color = t*0xFF
so, md -> 32 bit = md/0xE*0xFF (round)
32 bit -> md = 32bit/0xFF*0xE (round)

If you don't wanna round, you may use following formulas:
32bit = (md*0xFF+0x7F)/0xE (truncate = round down)
md = (32bit*0xE+7)/0xFF (truncate = round down)

Method using measured values.

According to this:

Code: Select all

0  2  4  6  8  A  C  E
0  9 16 22 27 32 38 47
Taking in to account that eye is selecting white point from max value among all light.
So in same way as in previous method, we interpolate 0 .. 47 -> 0 .. 1
measured = t*47
then 32bit = lookup_measured(md)/47*0xFF.
md = lookup_md(32bit*47/0xFF) (pick closest one)

Now, in end of this part: 32bit generated from md color - is what available.
MD color generated from 32bit - is just some kind of back conversion, see next sections :D

2) What is closest.

Noone knows, what is closest. Many people doing research in human perception, there are a lot of models of human perception. There are many different color spaces, such as Lab, YUV, YCbCr, sRGB...
You can use any of color space, to find out what color is closest to particular one.

Maybe I'm wrong, if I'm wrong -> correct me :D

Anyway, when you're looking for closest one, you need to define measure, how close one color, to another. Formulas to convert into MD colors in previous section are using following measure (distance):
|R1-R2|+|G1-G2|+|B1-B2| where |x| = abs(x);
It's simplest one. You can use components separately here because for all G and B, you can get all R.
When you using Lab space for example, you'll convert md -> RGB->Lab and then you'll have all 512 different colors in Lab space.
And if you look at available Lab colors, you may check that for fixed for different fixed a,b can be different available L.
I don't know how to describe it better.
pick some available color from Lab, then try to look what other available colors has same a,b components, and check L components of them.
Now pick another available color with differen a,b, and try to look what other available colors has same a,b components as selected this time. Check L components of them: in most cases you'll get different set.

How to measure distance between colors: open question. You may use something simpe like previous distance function or this one:
(R1-R2)^2+(G1-G2)^2+(B1-B2)^2
or something else. Also you can google other color comparison methods.

Hmm, imagine dark room with red ball on floor: if someone ask you: what color of ball? you can easily answer: it's red. But if you make photo, and pick color of pixel of ball, then fill with it rectange, show it to someone, and ask him: what color of that rectangle? He can easily say: brown.

3) How to find.

In simplest case, when you can deal with components separately, you just do it: brute force along all cases (only 14 of them), and pick component.
When you can't separate components, then actually, you can use brute force too, it may take a while, but it's still fast: only 512 of colors. If you want to do it faster, you can use some space/devision techniques, like octree or something else, but honestly, I think it's overkill :) Do what you want.

If you need color conversion in real time, then you can make approximation of conversion functions by polynoms for example, or in other way. Or lookup tables, or... I don't know, don't ask :D

Also, take a look at this thread and this :D
Image

Post Reply