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