RGB和YCbCr颜色空间之间的转换及优化算法

RGB转换为YCbCr

这个公式来自:Genesis Microchip. gm6010/gm6015 Programming Guide[M]. California US: Genesis Microchip Company, 2002:85-90

|Y |    |16 |          |65.738   129.057  25.06 | |R| |Cb| = |128| +  (1/256) * |-37.945  -74.494  112.43| *|G| |Cr|    |128|          |112.439  -94.154  -18.28| |B|

即:

Y   = 0.257*R+0.564*G+0.098*B+16 Cb = -0.148*R-0.291*G+0.439*B+128 Cr  = 0.439*R-0.368*G-0.071*B+128

YCbCr转换为RGB

这个公式来自:Genesis Microchip. gm6015 Preliminary Data Sheet[M]. California US: Genesis Microchip Company, 2001:33-34

|R|                   |298.082  0               408.58 |   |Y   -16  | |G| = (1/256) * |298.082  -100.291 -208.12  | * |Cb-128 | |B|                   |298.082  516.411   0           |    |Cr -128 |

即:

R = 1.164*(Y-16)+1.596*(Cr-128) G = 1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128) B = 1.164*(Y-16)+2.017*(Cb-128)

Y:明亮度(Luminance或Luma),也就是灰阶值。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。

U&V:色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和CB来表示。

Cb:反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。 Cr:反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。

RGB转为YCbCr的代码:
public static void ToYCbCr(byte* From, byte* To, int Length = 1)
        {
            if (Length < 1) return;
            byte* End = From + Length * 3;
            int Red, Green, Blue;
            // int Y, Cb, Cr;
            while (From != End)
            {
                Blue = *From; Green = *(From + 1); Red = *(From + 2);
                // 无需判断是否存在溢出,因为测试过整个RGB空间的所有颜色值,无颜色存在溢出
                *To = (byte)((YCbCrYRI * Red + YCbCrYGI * Green + YCbCrYBI * Blue + HalfShiftValue) >> Shift);     
                *(To + 1) = (byte)( 128 + ( (YCbCrCbRI * Red + YCbCrCbGI * Green + YCbCrCbBI * Blue + HalfShiftValue) >> Shift));
                *(To + 2) = (byte) (128+( (YCbCrCrRI * Red + YCbCrCrGI * Green + YCbCrCrBI * Blue + HalfShiftValue) >> Shift));
               // *To = (byte)Y;          // 不要把直接计算的代码放在这里,会降低速度,
                //*(To + 1) = (byte)Cb;
                //*(To + 2) = (byte)Cr;
                From += 3;
                To += 3;
            }
        }

  YCbCr转为RGB空间的代码:

复制代码
        public static void ToRGB(byte* From, byte* To, int Length = 1)
        {
            if (Length < 1) return;
            byte* End = From + Length * 3;
            int Red, Green, Blue;
            int Y, Cb, Cr;
            while (From != End)
            {
                Y = *From; Cb = *(From + 1)-128; Cr = *(From + 2)-128;
                Red = Y + ((RGBRCrI * Cr + HalfShiftValue) >> Shift);
                Green = Y + ((RGBGCbI * Cb + RGBGCrI * Cr+ HalfShiftValue) >> Shift);
                Blue = Y + ((RGBBCbI * Cb + HalfShiftValue) >> Shift);
                if (Red > 255) Red = 255; else if (Red < 0) Red = 0;
                if (Green > 255) Green = 255; else if (Green < 0) Green = 0;    // 编译后应该比三目运算符的效率高
                if (Blue > 255) Blue = 255; else if (Blue < 0) Blue = 0;
                *To = (byte)Blue;                                               // 由于不是一一对应的,需要判断是否越界
                *(To + 1) = (byte)Green;
                *(To + 2) = (byte)Red;
                From += 3;
                To += 3;
            }
        }

参考http://www.cnblogs.com/Imageshop/archive/2013/02/14/2911309.html

展开阅读全文

没有更多推荐了,返回首页