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):
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:
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?
Converting colours to MD
Moderator: BigEvilCorporation
-
- Very interested
- Posts: 2443
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
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
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 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:
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
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
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
Also, take a look at this thread and this
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
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
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
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
Also, take a look at this thread and this