コード例 #1
0
        /// <summary>
        /// Convert from RGB to YCbCr color space (Rec 601-1 specification).
        /// </summary>
        ///
        /// <param name="rgb">Source color in <b>RGB</b> color space.</param>
        /// <param name="ycbcr">Destination color in <b>YCbCr</b> color space.</param>
        ///
        public static void FromRGB(RGB rgb, YCbCr ycbcr)
        {
            double r = (double)rgb.Red / 255;
            double g = (double)rgb.Green / 255;
            double b = (double)rgb.Blue / 255;

            ycbcr.Y  = 0.2989 * r + 0.5866 * g + 0.1145 * b;
            ycbcr.Cb = -0.1687 * r - 0.3313 * g + 0.5000 * b;
            ycbcr.Cr = 0.5000 * r - 0.4184 * g - 0.0816 * b;
        }
コード例 #2
0
        /// <summary>
        /// Convert from YCbCr to RGB color space.
        /// </summary>
        ///
        /// <param name="ycbcr">Source color in <b>YCbCr</b> color space.</param>
        /// <param name="rgb">Destination color in <b>RGB</b> color spacs.</param>
        ///
        public static void ToRGB(YCbCr ycbcr, RGB rgb)
        {
            // don't warry about zeros. compiler will remove them
            double r = Math.Max(0.0, Math.Min(1.0, ycbcr.Y + 0.0000 * ycbcr.Cb + 1.4022 * ycbcr.Cr));
            double g = Math.Max(0.0, Math.Min(1.0, ycbcr.Y - 0.3456 * ycbcr.Cb - 0.7145 * ycbcr.Cr));
            double b = Math.Max(0.0, Math.Min(1.0, ycbcr.Y + 1.7710 * ycbcr.Cb + 0.0000 * ycbcr.Cr));

            rgb.Red   = (byte)(r * 255);
            rgb.Green = (byte)(g * 255);
            rgb.Blue  = (byte)(b * 255);
        }
コード例 #3
0
        /// <summary>
        /// Color filtering in YCbCr color space.
        /// </summary>
        public static unsafe Bitmap YCbCrFilter(Bitmap image, Rectangle rect, DoubleRange Y, DoubleRange Cb, DoubleRange Cr)
        {
            Bitmap     dest        = new Bitmap(image.Width, image.Height, PixelFormat.Format8bppIndexed);
            BitmapData source      = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat);
            BitmapData destination = dest.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, dest.PixelFormat);
            int        startX      = rect.Left;
            int        startY      = rect.Top;
            int        stopX       = rect.Right;
            int        stopY       = rect.Bottom;

            // get pixel size
            int pixelSize = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
            int srcOffset = source.Stride - rect.Width * pixelSize;
            int dstOffset = destination.Stride - rect.Width;

            RGB   rgb   = new RGB();
            YCbCr ycbcr = new YCbCr();

            // do the job
            byte *src = (byte *)source.Scan0 + startY * source.Stride + startX * pixelSize;
            byte *dst = (byte *)destination.Scan0 + startY * destination.Stride + startX;

            // for each row
            for (int y = startY; y < stopY; y++)
            {
                // for each pixel
                for (int x = startX; x < stopX; x++, src += pixelSize, dst++)
                {
                    rgb.Red   = src[RGB.R];
                    rgb.Green = src[RGB.G];
                    rgb.Blue  = src[RGB.B];

                    // convert to YCbCr
                    ycbcr = YCbCr.FromRGB(rgb);

                    // check YCbCr values
                    if (Y.IsInside(ycbcr.Y) & Cb.IsInside(ycbcr.Cb) && Cr.IsInside(ycbcr.Cr))
                    {
                        *dst = 0;
                    }
                    else
                    {
                        *dst = 255;
                    }
                }

                src += srcOffset;
                dst += dstOffset;
            }

            int width  = image.Width;
            int height = image.Height;
            int stride = destination.Stride;

            // remove upper part
            for (int y = 0; y < startY; y++)
            {
                dst = (byte *)destination.Scan0.ToPointer() + y * stride;
                SystemTools.SetUnmanagedMemory(dst, 255, stride);
            }

            // remove lower part
            for (int y = stopY; y < height; y++)
            {
                dst = (byte *)destination.Scan0.ToPointer() + y * stride;
                SystemTools.SetUnmanagedMemory(dst, 255, stride);
            }

            for (int y = startY; y < stopY; y++)
            {
                // remove left part
                dst = (byte *)destination.Scan0.ToPointer() + y * stride;
                SystemTools.SetUnmanagedMemory(dst, 255, startX);

                // remove right part
                dst += stopX;
                SystemTools.SetUnmanagedMemory(dst, 255, stride - stopX);
            }

            image.UnlockBits(source);
            dest.UnlockBits(destination);

            return(dest);
        }