a chroma key can select a range of colors in a image as transprent,it is often used in video composition.I’m finding the arithmetic of chroma key,so if anyone can give me some help,please reply,thanks.
Write a fragment program that does something like:
SUB dest, srcColor, chromaKey;
ABS dest, dest;
SUB dest, toleranceColor;
This will kill a fragment if its color is within some (manhattan) tolerance from the target color.
You can’t really do this using the fixed function pipeline. Instead, you’d have to process the texture data on the CPU before upload, setting the alpha to 0 where the color is similar enough to the key color.
You may get better results if you calculate a “closeness” measurement and move the inverse of that into alpha (with saturation).
Thanks to jwatte,I plan to write a chroma key program using NVIDIA’s CG shading language,but I don’t know the algorithm inside it(such as what parameters it has and how to set it),so anyone can give me some documents about it?
To reduce edge effects, you may want to try the following:
Given a key color k, and a fragment color f…
If |f-k| < epsilon_1, kill it.
If |f-k| > epsilon_2, just use f.
If |f-k| is between the epsilons, let alpha = |f-k|/(epsilon_2-epsilon_1), and find f_2 such that alpha * f_2 + (1-alpha) * k == f. Return f_2, alpha.
This might take some work to map into assembly, but basically the idea is this: if you have a photo of a subject on a k-colored background, for those pixels on the boundary, you want to alpha blend things.
In Cg it’s very easy.
float4 delta = IN.color - CONST.key;
float distance2 = dot( delta, delta );
float weight = saturate( (distance2 - CONST.minDistance) /
(CONST.maxDistance - CONST.minDistance) );
float4 transparent = IN.color;
transparent.w = 0;
OUT.color = lerp( transparent, IN.color, weight );
I’m sure you can infer the appropriate semantics for IN, OUT and CONST. Note that this gives you squared-falloff after the “minDistance” tolerance threshold, out to the “maxDistance” threshold, where no transparency will be added.
I’m do not believe that the linear RGB space would be the color space to check the “distance” between the two colors.
You want the chroma key to kill fragments which have the same color as your chroma color. Perhaps you should check the “distance” of the colors in YCrCb. I believe that a chroma key should kill fragments with similar chrominance regardless of the luminance (Can this be checked by the R2 distrance of the CrCb components?)
My 2 cents…
In chroma keying, you actually get a full color value, luminance included, as the key.
YCbCr is a simple linear combination of RGB, so it’s not really that much more expressive as far as chroma keying goes. You could get the same thing by using a weighted distance function in RGB.
If you really want to kill everything with the same hue, you might want to convert to HSV or similar. Or you could just divide the distance you get by the length of the input color vector, to compensate away brightness.