[comp.sys.amiga] RGB to HSV, and RGB to CMY

dsears@pnet02.cts.com (Doug Sears) (06/10/88)

-------------------
  
kodiak@amiga.UUCP (Robert R. Burns) writes:
>In article <7271@swan.ulowell.edu> dpelland@hawk.ulowell.edu (David Pelland)
writes:
>>In article <8805271453.AA13503@jade.berkeley.edu> BBOURBIN@UMDD.BITNET
(Brett S Bourbin) writes:
>>>Does anyone out there know of a formula for converting a RGB (red green
blue)
>>>color value, into a HSV (hue saturation value) one?
>>
>>H = cos^-1((1/2((R-G)+(R-G)))/(((R-G)^2+(R-B)(G-B))^(1/2)))
>>S = 1 - ((3*(min(RGB)))/I)
>>I = (R+B+G)/3
 
>  Most Amiga stuff I've seen uses the HSV cylinder, w/ black on
>the bottom, white in the middle at the top, and fully saturated colors around
>the outside of the cylinder.  My favorite reference is the 1978 (?) SIGGRAPH
>proceedings (but I don't have them).  I think of HSV as...
 
>H = [0 == 1 == red; .33 == green; .67 == blue]  // that may be the one above?
>S = 1 - min(R, G, B);                           // distance from "grey"
>V = max(R, G, B);                               // non-blackness
 
Not bad for quoting from memory. Actually, it's a hexcone, not a
cylinder, unless there's more than one HSV model.  The article Kodiak was
referring to is probably "Color Gamut Transform Pairs", by Alvy Ray
Smith, SIGGRAPH 78 Proceedings, pp. 12-19 (also reprinted in "Tutorial:
Computer Graphics", 2nd ed, J.C. Beatty & K.S. Booth, eds, pp. 376-383).
They introduced the hexcone model (HSV) and the triangle model (HSL).
Here's their algorithm for the hexcone, RGB to HSV (R, G, B, H, S, and V
all run from 0 to 1):
 
V := max(R, G, B);
 
Let X := min(R, G, B);
 
S := (V - X)/V;   if S=0 return;
 
Let r := (V - R)/(V - X);
    g := (V - G)/(V - X);
    b := (V - B)/(V - X);
 
If R=V then H := (if G=X then 5+b else 1-g);
If G=V then H := (if B=X then 1+r else 3-b);
       else H := (if R=X then 3+g else 5-r);
 
H := H/6;
 
  You have to watch out for when S = 0 (H is undefined).  Another
explanation of the hexcone model is in the September 1984 BYTE, pp.
227-246.  David Pelland's formula looks like the HSL triangle model,
"unbiased case".
 
  Now for a question: any hints on converting RGB to CMY or CMYB
(cyan/magenta/yellow/black: subtractive color) as applied to low-cost
color printers?  C = 1 - R, etc. is too simple. The Neugebauer
equations take into account the properties of real-life colored
inks and variable overlap of dots, but they're real hard to solve
(system of three NONlinear equations).  Has anybody come up with a
practical approach?  I'm afraid I'll have to bypass the printer.device
to make use of this, since it only has the one graphics function,
DumpRPort().

UUCP: {ihnp4!scgvaxd!cadovax, <backbone>}!gryphon!pnet02!dsears
INET: dsears@pnet02.cts.com

doug-merritt@cup.portal.com (06/12/88)

dsears says:
>any hints on converting RGB to CMY or CMYB [...] as applied to low-cost
>color printers?  C = 1 - R, etc. is too simple. The Neugebauer
>equations ... [ are ] real hard to solve (system of three NONlinear equations)
>Has anybody come up with a practical approach? 

One thing to keep in mind with all these color space transformations is
that, for many purposes, you're never going to need more than 4096 colors
on the Amiga. And usually *less* than that in the target color space
(unless the transformation is one-to-one, which is unusual).

For such applications, you can precompute the transformation for each
of the 4096 input RGB values, so it doesn't matter if it's really slow.

As for handling apparently-insoluble nonlinear equations, the most common
trick for *applied* math is to emulate them by a patchwork of more
tractable equations. Graph the nonlinear equation, then use a ruler to
draw straight line segment approximations to it's graph. Use as many
straight lines as necessary to get a good approximation. Now you can
use the equation of each of these resulting linear approximations instead
of the original, and they *can* be solved because they're so simple.

This method is *easily* good enough to build the 4096 value lookup table,
if you use it carefully.

If you're working in a 24 bit color space, then the lookup table would be
too big (2^24 = 16 million), but you can still use the "piecewise linear
approximation" to do the transformations. In this case it may be necessary
to have more of the linear equations than in the 4096 case, if you're
very concerned with accuracy. If you actually use graph paper to find
the approximations, it's very easy to see (and to minimize) the maximum
error, since it's just the maximum distance between a point on the original
nonlinear curve, and the corresponding approximation on the straight line.

If that sounds confusing, grab some graph paper and try it on something
simple like a parabola. It's obvious when you're looking at it.

If you end up with a *lot* of linear equations, each with widely varying
intervals over which they are valid (unusual except for precision
applications), then you may want to use a hash table or a tree for looking
up the appropriate equation.
	Doug
--
      Doug Merritt        ucbvax!sun.com!cup.portal.com!doug-merritt
                      or  ucbvax!eris!doug (doug@eris.berkeley.edu)
                      or  ucbvax!unisoft!certes!doug