public static YCbCr FromRGB(RGB rgb) { YCbCr yCbCr = new YCbCr(); FromRGB(rgb, yCbCr); return(yCbCr); }
/// <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> /// /// <returns>Returns <see cref="YCbCr"/> instance, which represents converted color value.</returns> /// public static YCbCr FromRGB(RGB rgb) { var ycbcr = new YCbCr( ); FromRGB(rgb, ycbcr); return(ycbcr); }
public void SetColor(byte r, byte g, byte b) { RGB rgbcolor = new RGB(r,g,b); this.color = YCbCr.FromRGB(rgbcolor); this.colorFilter.Cb = new AForge.Range(this.color.Cb - 0.02f, this.color.Cb + 0.02f); this.colorFilter.Cr = new AForge.Range(this.color.Cr - 0.02f, this.color.Cr + 0.02f); this.colorFilter.Y = new AForge.Range(this.color.Y - 0.05f, this.color.Y + 0.05f); this.applyFilters = true; }
public static void FromRGB(RGB rgb, YCbCr ycbcr) { double num = ((double)rgb.Red) / 255.0; double num2 = ((double)rgb.Green) / 255.0; double num3 = ((double)rgb.Blue) / 255.0; ycbcr.Y = ((0.2989 * num) + (0.5866 * num2)) + (0.1145 * num3); //image transform equation to get y component ycbcr.Cb = ((-0.1687 * num) - (0.3313 * num2)) + (0.5 * num3); //image transform equation to get Cb component ycbcr.Cr = ((0.5 * num) - (0.4184 * num2)) - (0.0816 * num3); //image transform equation to get Cr component }
/// <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 RGB2YCbCr(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; }
public static void FromRGB(RGB rgb, YCbCr ycbcr) { float num = (float)(int)rgb.Red / 255f; float num2 = (float)(int)rgb.Green / 255f; float num3 = (float)(int)rgb.Blue / 255f; ycbcr.Y = (float)(0.2989 * (double)num + 0.5866 * (double)num2 + 0.1145 * (double)num3); ycbcr.Cb = (float)(-0.1687 * (double)num - 0.3313 * (double)num2 + 0.5 * (double)num3); ycbcr.Cr = (float)(0.5 * (double)num - 0.4184 * (double)num2 - 0.0816 * (double)num3); }
public static void FromRGB(RGB rgb, YCbCr ycbcr) { double num = ((double)rgb.Red) / 255.0; double num2 = ((double)rgb.Green) / 255.0; double num3 = ((double)rgb.Blue) / 255.0; ycbcr.Y = ((0.2989 * num) + (0.5866 * num2)) + (0.1145 * num3); ycbcr.Cb = ((-0.1687 * num) - (0.3313 * num2)) + (0.5 * num3); ycbcr.Cr = ((0.5 * num) - (0.4184 * num2)) - (0.0816 * num3); }
/// <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) { float r = (float)rgb.Red / 255; float g = (float)rgb.Green / 255; float b = (float)rgb.Blue / 255; ycbcr.Y = (float)(0.2989 * r + 0.5866 * g + 0.1145 * b); ycbcr.Cb = (float)(-0.1687 * r - 0.3313 * g + 0.5000 * b); ycbcr.Cr = (float)(0.5000 * r - 0.4184 * g - 0.0816 * b); }
public static void ToRGB(YCbCr ycbcr, RGB rgb) { double num = Math.Max(0.0, Math.Min((double)1.0, (double)((ycbcr.Y + (0.0 * ycbcr.Cb)) + (1.4022 * ycbcr.Cr)))); double num2 = Math.Max(0.0, Math.Min((double)1.0, (double)((ycbcr.Y - (0.3456 * ycbcr.Cb)) - (0.7145 * ycbcr.Cr)))); double num3 = Math.Max(0.0, Math.Min((double)1.0, (double)((ycbcr.Y + (1.771 * ycbcr.Cb)) + (0.0 * ycbcr.Cr)))); rgb.Red = (byte)(num * 255.0); rgb.Green = (byte)(num2 * 255.0); rgb.Blue = (byte)(num3 * 255.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 YCbCr2RGB(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); }
public static void ToRGB(YCbCr ycbcr, RGB rgb) { float num = System.Math.Max(0f, System.Math.Min(1f, (float)((double)ycbcr.Y + 0.0 * (double)ycbcr.Cb + 1.4022 * (double)ycbcr.Cr))); float num2 = System.Math.Max(0f, System.Math.Min(1f, (float)((double)ycbcr.Y - 0.3456 * (double)ycbcr.Cb - 0.7145 * (double)ycbcr.Cr))); float num3 = System.Math.Max(0f, System.Math.Min(1f, (float)((double)ycbcr.Y + 1.771 * (double)ycbcr.Cb + 0.0 * (double)ycbcr.Cr))); rgb.Red = (byte)(num * 255f); rgb.Green = (byte)(num2 * 255f); rgb.Blue = (byte)(num3 * 255f); rgb.Alpha = byte.MaxValue; }
/// <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 var r = System.Math.Max(0.0f, System.Math.Min(1.0f, (float)(ycbcr.Y + 0.0000 * ycbcr.Cb + 1.4022 * ycbcr.Cr))); var g = System.Math.Max(0.0f, System.Math.Min(1.0f, (float)(ycbcr.Y - 0.3456 * ycbcr.Cb - 0.7145 * ycbcr.Cr))); var b = System.Math.Max(0.0f, System.Math.Min(1.0f, (float)(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); rgb.Alpha = 255; }
/// <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 space.</param> /// public static void ToRGB(YCbCr ycbcr, RGB rgb) { // Don't worry about zeros. Compiler will remove them float r = Math.Max(0.0f, Math.Min(1.0f, (float)(ycbcr.Y + 0.0000 * ycbcr.Cb + 1.4022 * ycbcr.Cr))); float g = Math.Max(0.0f, Math.Min(1.0f, (float)(ycbcr.Y - 0.3456 * ycbcr.Cb - 0.7145 * ycbcr.Cr))); float b = Math.Max(0.0f, Math.Min(1.0f, (float)(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); rgb.Alpha = 255; }
private unsafe void ProcessImage(UnmanagedImage image) { this.CheckSourceFormat(image.PixelFormat); int width = image.Width; int height = image.Height; this.pixels = this.pixelsWithoutBlack = 0; int[] numArray = new int[0x100]; int[] numArray2 = new int[0x100]; int[] numArray3 = new int[0x100]; int[] numArray4 = new int[0x100]; int[] numArray5 = new int[0x100]; int[] numArray6 = new int[0x100]; RGB rgb = new RGB(); YCbCr ycbcr = new YCbCr(); int num3 = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; int num4 = image.Stride - (width * num3); byte *numPtr = (byte *)image.ImageData.ToPointer(); for (int i = 0; i < height; i++) { int num6 = 0; while (num6 < width) { rgb.Red = numPtr[2]; rgb.Green = numPtr[1]; rgb.Blue = numPtr[0]; YCbCr.FromRGB(rgb, ycbcr); numArray[(int)(ycbcr.Y * 255.0)]++; numArray2[(int)((ycbcr.Cb + 0.5) * 255.0)]++; numArray3[(int)((ycbcr.Cr + 0.5) * 255.0)]++; this.pixels++; if (((ycbcr.Y != 0.0) || (ycbcr.Cb != 0.0)) || (ycbcr.Cr != 0.0)) { numArray4[(int)(ycbcr.Y * 255.0)]++; numArray5[(int)((ycbcr.Cb + 0.5) * 255.0)]++; numArray6[(int)((ycbcr.Cr + 0.5) * 255.0)]++; this.pixelsWithoutBlack++; } num6++; numPtr += num3; } numPtr += num4; } this.yHistogram = new ContinuousHistogram(numArray, new DoubleRange(0.0, 1.0)); this.cbHistogram = new ContinuousHistogram(numArray2, new DoubleRange(-0.5, 0.5)); this.crHistogram = new ContinuousHistogram(numArray3, new DoubleRange(-0.5, 0.5)); this.yHistogramWithoutBlack = new ContinuousHistogram(numArray4, new DoubleRange(0.0, 1.0)); this.cbHistogramWithoutBlack = new ContinuousHistogram(numArray5, new DoubleRange(-0.5, 0.5)); this.crHistogramWithoutBlack = new ContinuousHistogram(numArray6, new DoubleRange(-0.5, 0.5)); }
private unsafe void ProcessImage(UnmanagedImage image, byte *mask, int maskLineSize) { int width = image.Width; int height = image.Height; pixels = (pixelsWithoutBlack = 0); int[] array = new int[256]; int[] array2 = new int[256]; int[] array3 = new int[256]; int[] array4 = new int[256]; int[] array5 = new int[256]; int[] array6 = new int[256]; RGB rGB = new RGB(); YCbCr yCbCr = new YCbCr(); int num = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; int num2 = image.Stride - width * num; int num3 = maskLineSize - width; byte *ptr = (byte *)image.ImageData.ToPointer(); if (mask == null) { for (int i = 0; i < height; i++) { int num4 = 0; while (num4 < width) { rGB.Red = ptr[2]; rGB.Green = ptr[1]; rGB.Blue = *ptr; YCbCr.FromRGB(rGB, yCbCr); array[(int)(yCbCr.Y * 255f)]++; array2[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++; array3[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++; pixels++; if ((double)yCbCr.Y != 0.0 || (double)yCbCr.Cb != 0.0 || (double)yCbCr.Cr != 0.0) { array4[(int)(yCbCr.Y * 255f)]++; array5[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++; array6[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++; pixelsWithoutBlack++; } num4++; ptr += num; } ptr += num2; } } else { for (int j = 0; j < height; j++) { int num5 = 0; while (num5 < width) { if (*mask != 0) { rGB.Red = ptr[2]; rGB.Green = ptr[1]; rGB.Blue = *ptr; YCbCr.FromRGB(rGB, yCbCr); array[(int)(yCbCr.Y * 255f)]++; array2[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++; array3[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++; pixels++; if ((double)yCbCr.Y != 0.0 || (double)yCbCr.Cb != 0.0 || (double)yCbCr.Cr != 0.0) { array4[(int)(yCbCr.Y * 255f)]++; array5[(int)(((double)yCbCr.Cb + 0.5) * 255.0)]++; array6[(int)(((double)yCbCr.Cr + 0.5) * 255.0)]++; pixelsWithoutBlack++; } } num5++; ptr += num; mask++; } ptr += num2; mask += num3; } } yHistogram = new ContinuousHistogram(array, new Range(0f, 1f)); cbHistogram = new ContinuousHistogram(array2, new Range(-0.5f, 0.5f)); crHistogram = new ContinuousHistogram(array3, new Range(-0.5f, 0.5f)); yHistogramWithoutBlack = new ContinuousHistogram(array4, new Range(0f, 1f)); cbHistogramWithoutBlack = new ContinuousHistogram(array5, new Range(-0.5f, 0.5f)); crHistogramWithoutBlack = new ContinuousHistogram(array6, new Range(-0.5f, 0.5f)); }
/// <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> /// /// <returns>Returns <see cref="YCbCr"/> instance, which represents converted color value.</returns> /// public static YCbCr FromRGB( RGB rgb ) { YCbCr ycbcr = new YCbCr( ); FromRGB( rgb, ycbcr ); return ycbcr; }
/// <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 float r = Math.Max( 0.0f, Math.Min( 1.0f, (float) ( ycbcr.Y + 0.0000 * ycbcr.Cb + 1.4022 * ycbcr.Cr ) ) ); float g = Math.Max( 0.0f, Math.Min( 1.0f, (float) ( ycbcr.Y - 0.3456 * ycbcr.Cb - 0.7145 * ycbcr.Cr ) ) ); float b = Math.Max( 0.0f, Math.Min( 1.0f, (float) ( 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 ); }
// Gather statistics for the specified image private unsafe void ProcessImage(UnmanagedImage image, byte *mask, int maskLineSize) { // get image dimension int width = image.Width; int height = image.Height; pixels = pixelsWithoutBlack = 0; int[] yhisto = new int[256]; int[] cbhisto = new int[256]; int[] crhisto = new int[256]; int[] yhistoWB = new int[256]; int[] cbhistoWB = new int[256]; int[] crhistoWB = new int[256]; RGB rgb = new RGB( ); YCbCr ycbcr = new YCbCr( ); int pixelSize = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; int offset = image.Stride - width * pixelSize; int maskOffset = maskLineSize - width; // do the job byte *p = (byte *)image.ImageData.ToPointer( ); if (mask == null) { // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, p += pixelSize) { rgb.Red = p[RGB.R]; rgb.Green = p[RGB.G]; rgb.Blue = p[RGB.B]; // convert to YCbCr color space AForge.Imaging.YCbCr.FromRGB(rgb, ycbcr); yhisto[(int)(ycbcr.Y * 255)]++; cbhisto[(int)((ycbcr.Cb + 0.5) * 255)]++; crhisto[(int)((ycbcr.Cr + 0.5) * 255)]++; pixels++; if ((ycbcr.Y != 0.0) || (ycbcr.Cb != 0.0) || (ycbcr.Cr != 0.0)) { yhistoWB[(int)(ycbcr.Y * 255)]++; cbhistoWB[(int)((ycbcr.Cb + 0.5) * 255)]++; crhistoWB[(int)((ycbcr.Cr + 0.5) * 255)]++; pixelsWithoutBlack++; } } p += offset; } } else { // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, p += pixelSize, mask++) { if (*mask == 0) { continue; } rgb.Red = p[RGB.R]; rgb.Green = p[RGB.G]; rgb.Blue = p[RGB.B]; // convert to YCbCr color space AForge.Imaging.YCbCr.FromRGB(rgb, ycbcr); yhisto[(int)(ycbcr.Y * 255)]++; cbhisto[(int)((ycbcr.Cb + 0.5) * 255)]++; crhisto[(int)((ycbcr.Cr + 0.5) * 255)]++; pixels++; if ((ycbcr.Y != 0.0) || (ycbcr.Cb != 0.0) || (ycbcr.Cr != 0.0)) { yhistoWB[(int)(ycbcr.Y * 255)]++; cbhistoWB[(int)((ycbcr.Cb + 0.5) * 255)]++; crhistoWB[(int)((ycbcr.Cr + 0.5) * 255)]++; pixelsWithoutBlack++; } } p += offset; mask += maskOffset; } } // create histograms yHistogram = new ContinuousHistogram(yhisto, new Range(0.0f, 1.0f)); cbHistogram = new ContinuousHistogram(cbhisto, new Range(-0.5f, 0.5f)); crHistogram = new ContinuousHistogram(crhisto, new Range(-0.5f, 0.5f)); yHistogramWithoutBlack = new ContinuousHistogram(yhistoWB, new Range(0.0f, 1.0f)); cbHistogramWithoutBlack = new ContinuousHistogram(cbhistoWB, new Range(-0.5f, 0.5f)); crHistogramWithoutBlack = new ContinuousHistogram(crhistoWB, new Range(-0.5f, 0.5f)); }
/// <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 ) { float r = (float) rgb.Red / 255; float g = (float) rgb.Green / 255; float b = (float) rgb.Blue / 255; ycbcr.Y = (float) ( 0.2989 * r + 0.5866 * g + 0.1145 * b ); ycbcr.Cb = (float) ( -0.1687 * r - 0.3313 * g + 0.5000 * b ); ycbcr.Cr = (float) ( 0.5000 * r - 0.4184 * g - 0.0816 * b ); }
// On mouse position over image changed private void document_MouseImagePosition(object sender, SelectionEventArgs e) { if (e.Location.X >= 0) { this.PositionToolStripStatusLabel.Text = string.Format(" ({0}, {1})", e.Location.X, e.Location.Y); // get current color Bitmap image = ((ImageHandlerForm)sender).Image; if (image.PixelFormat == PixelFormat.Format24bppRgb) { Color color = image.GetPixel(e.Location.X, e.Location.Y); RGB rgb = new RGB(color); YCbCr ycbcr = new YCbCr(); AForge.Imaging.ColorConverter.RGB2YCbCr(rgb, ycbcr); // RGB this.colorPanel.Text = string.Format("RGB: {0}, {1}, {2}", color.R, color.G, color.B); // HSL this.hslPanel.Text = string.Format("HSL: {0}, {1:F3}, {2:F3}", (int)color.GetHue(), color.GetSaturation(), color.GetBrightness()); // YCbCr this.ycbcrPanel.Text = string.Format("YCbCr: {0:F3}, {1:F3}, {2:F3}", ycbcr.Y, ycbcr.Cb, ycbcr.Cr); } else if (image.PixelFormat == PixelFormat.Format8bppIndexed) { Color color = image.GetPixel(e.Location.X, e.Location.Y); this.colorPanel.Text = "Gray: " + color.R.ToString(); this.hslPanel.Text = ""; this.ycbcrPanel.Text = ""; } } else { this.PositionToolStripStatusLabel.Text = ""; this.colorPanel.Text = ""; this.hslPanel.Text = ""; this.ycbcrPanel.Text = ""; } }
// On mouse position over image changed private void document_MouseImagePosition(object sender, SelectionEventArgs e) { if (e.Location.X >= 0) { this.selectionPanel.Text = string.Format( "({0}, {1})", e.Location.X, e.Location.Y ); // get current color Bitmap image = ((ImageDoc) sender).Image; if (image.PixelFormat == PixelFormat.Format24bppRgb) { Color color = image.GetPixel(e.Location.X, e.Location.Y); RGB rgb = new RGB( color ); YCbCr ycbcr = new YCbCr( ); AForge.Imaging.ColorConverter.RGB2YCbCr( rgb, ycbcr ); // RGB this.colorPanel.Text = string.Format( "RGB: {0}; {1}; {2}", color.R, color.G, color.B ); // HSL this.hslPanel.Text = string.Format( "HSL: {0}; {1:F3}; {2:F3}", (int) color.GetHue(), color.GetSaturation(), color.GetBrightness() ); // YCbCr this.ycbcrPanel.Text = string.Format( "YCbCr: {0:F3}; {1:F3}; {2:F3}", ycbcr.Y, ycbcr.Cb, ycbcr.Cr ); //SS: отображение области для расчета среднего значения цвета Rectangle avArea=((ImageDoc)sender).AverageArea; if (!avArea.IsEmpty) this.avColorPanel.Text = string.Format("AVERAGE: [{0}; {1}] - [{2}; {3}]", avArea.Left, avArea.Top, avArea.Right, avArea.Bottom); else this.avColorPanel.Text = ""; if (((ImageDoc)sender).SelectingArea) this.infoPanel.Text = "Now select area or press right mouse button to cancel"; else if (((ImageDoc)sender).SelectingPoint || ((ImageDoc)sender).SelectingLayerPoint) this.infoPanel.Text = "Now pick a point or press right mouse button to cancel"; else this.infoPanel.Text = ""; } else if (image.PixelFormat == PixelFormat.Format8bppIndexed) { Color color = image.GetPixel(e.Location.X, e.Location.Y); this.colorPanel.Text = "Gray: " + color.R.ToString(); this.hslPanel.Text = ""; this.ycbcrPanel.Text = ""; } } else { this.selectionPanel.Text = ""; this.colorPanel.Text = ""; this.hslPanel.Text = ""; this.ycbcrPanel.Text = ""; } }
// Gather statistics private void ProcessImage( BitmapData imageData, int width, int height ) { pixels = pixelsWithoutBlack = 0; int[] yhisto = new int[256]; int[] cbhisto = new int[256]; int[] crhisto = new int[256]; int[] yhistoWB = new int[256]; int[] cbhistoWB = new int[256]; int[] crhistoWB = new int[256]; RGB rgb = new RGB( ); YCbCr ycbcr = new YCbCr( ); int offset = imageData.Stride - width * 3; // do the job unsafe { byte * p = (byte *) imageData.Scan0.ToPointer( ); // for each line for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p += 3 ) { rgb.Red = p[RGB.R]; rgb.Green = p[RGB.G]; rgb.Blue = p[RGB.B]; // convert to YCbCr color space AForge.Imaging.ColorConverter.RGB2YCbCr( rgb, ycbcr ); yhisto [(int) ( ycbcr.Y * 255 )]++; cbhisto[(int) ( ( ycbcr.Cb + 0.5 ) * 255 )]++; crhisto[(int) ( ( ycbcr.Cr + 0.5 ) * 255 )]++; pixels++; if ( ( ycbcr.Y != 0.0 ) || ( ycbcr.Cb != 0.0 ) || ( ycbcr.Cr != 0.0 ) ) { yhistoWB [(int) ( ycbcr.Y * 255 )]++; cbhistoWB[(int) ( ( ycbcr.Cb + 0.5 ) * 255 )]++; crhistoWB[(int) ( ( ycbcr.Cr + 0.5 ) * 255 )]++; pixelsWithoutBlack++; } } p += offset; } } // create histograms yHistogram = new HistogramD( yhisto , new RangeD( 0.0, 1.0 ) ); cbHistogram = new HistogramD( cbhisto, new RangeD( -0.5, 0.5 ) ); crHistogram = new HistogramD( crhisto, new RangeD( -0.5, 0.5 ) ); yHistogramWithoutBlack = new HistogramD( yhistoWB , new RangeD( 0.0, 1.0 ) ); cbHistogramWithoutBlack = new HistogramD( cbhistoWB, new RangeD( -0.5, 0.5 ) ); crHistogramWithoutBlack = new HistogramD( crhistoWB, new RangeD( -0.5, 0.5 ) ); }
// Gather statistics for the specified image private unsafe void ProcessImage(UnmanagedImage image, byte* mask, int maskLineSize) { // get image dimension int width = image.Width; int height = image.Height; pixels = pixelsWithoutBlack = 0; int[] yhisto = new int[256]; int[] cbhisto = new int[256]; int[] crhisto = new int[256]; int[] yhistoWB = new int[256]; int[] cbhistoWB = new int[256]; int[] crhistoWB = new int[256]; RGB rgb = new RGB(); YCbCr ycbcr = new YCbCr(); int pixelSize = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; int offset = image.Stride - width * pixelSize; int maskOffset = maskLineSize - width; // do the job byte* p = (byte*)image.ImageData.ToPointer(); if (mask == null) { // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, p += pixelSize) { rgb.Red = p[RGB.R]; rgb.Green = p[RGB.G]; rgb.Blue = p[RGB.B]; // convert to YCbCr color space AForge.Imaging.YCbCr.FromRGB(rgb, ycbcr); yhisto[(int)(ycbcr.Y * 255)]++; cbhisto[(int)((ycbcr.Cb + 0.5) * 255)]++; crhisto[(int)((ycbcr.Cr + 0.5) * 255)]++; pixels++; if ((ycbcr.Y != 0.0) || (ycbcr.Cb != 0.0) || (ycbcr.Cr != 0.0)) { yhistoWB[(int)(ycbcr.Y * 255)]++; cbhistoWB[(int)((ycbcr.Cb + 0.5) * 255)]++; crhistoWB[(int)((ycbcr.Cr + 0.5) * 255)]++; pixelsWithoutBlack++; } } p += offset; } } else { // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, p += pixelSize, mask++) { if (*mask == 0) continue; rgb.Red = p[RGB.R]; rgb.Green = p[RGB.G]; rgb.Blue = p[RGB.B]; // convert to YCbCr color space AForge.Imaging.YCbCr.FromRGB(rgb, ycbcr); yhisto[(int)(ycbcr.Y * 255)]++; cbhisto[(int)((ycbcr.Cb + 0.5) * 255)]++; crhisto[(int)((ycbcr.Cr + 0.5) * 255)]++; pixels++; if ((ycbcr.Y != 0.0) || (ycbcr.Cb != 0.0) || (ycbcr.Cr != 0.0)) { yhistoWB[(int)(ycbcr.Y * 255)]++; cbhistoWB[(int)((ycbcr.Cb + 0.5) * 255)]++; crhistoWB[(int)((ycbcr.Cr + 0.5) * 255)]++; pixelsWithoutBlack++; } } p += offset; mask += maskOffset; } } // create histograms yHistogram = new ContinuousHistogram(yhisto, new Range(0.0f, 1.0f)); cbHistogram = new ContinuousHistogram(cbhisto, new Range(-0.5f, 0.5f)); crHistogram = new ContinuousHistogram(crhisto, new Range(-0.5f, 0.5f)); yHistogramWithoutBlack = new ContinuousHistogram(yhistoWB, new Range(0.0f, 1.0f)); cbHistogramWithoutBlack = new ContinuousHistogram(cbhistoWB, new Range(-0.5f, 0.5f)); crHistogramWithoutBlack = new ContinuousHistogram(crhistoWB, new Range(-0.5f, 0.5f)); }
// Convert from YCbCr to RGB color space public static void YCbCr2RGB( 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 ); }
/// <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; }
// Gather statistics private void ProcessImage(BitmapData imageData, int width, int height) { pixels = pixelsWithoutBlack = 0; int[] yhisto = new int[256]; int[] cbhisto = new int[256]; int[] crhisto = new int[256]; int[] yhistoWB = new int[256]; int[] cbhistoWB = new int[256]; int[] crhistoWB = new int[256]; RGB rgb = new RGB( ); YCbCr ycbcr = new YCbCr( ); int offset = imageData.Stride - width * 3; // do the job unsafe { byte *p = (byte *)imageData.Scan0.ToPointer( ); // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, p += 3) { rgb.Red = p[RGB.R]; rgb.Green = p[RGB.G]; rgb.Blue = p[RGB.B]; // convert to YCbCr color space AForge.Imaging.ColorConverter.RGB2YCbCr(rgb, ycbcr); yhisto [(int)(ycbcr.Y * 255)]++; cbhisto[(int)((ycbcr.Cb + 0.5) * 255)]++; crhisto[(int)((ycbcr.Cr + 0.5) * 255)]++; pixels++; if ((ycbcr.Y != 0.0) || (ycbcr.Cb != 0.0) || (ycbcr.Cr != 0.0)) { yhistoWB [(int)(ycbcr.Y * 255)]++; cbhistoWB[(int)((ycbcr.Cb + 0.5) * 255)]++; crhistoWB[(int)((ycbcr.Cr + 0.5) * 255)]++; pixelsWithoutBlack++; } } p += offset; } } // create histograms yHistogram = new HistogramD(yhisto, new RangeD(0.0, 1.0)); cbHistogram = new HistogramD(cbhisto, new RangeD(-0.5, 0.5)); crHistogram = new HistogramD(crhisto, new RangeD(-0.5, 0.5)); yHistogramWithoutBlack = new HistogramD(yhistoWB, new RangeD(0.0, 1.0)); cbHistogramWithoutBlack = new HistogramD(cbhistoWB, new RangeD(-0.5, 0.5)); crHistogramWithoutBlack = new HistogramD(crhistoWB, new RangeD(-0.5, 0.5)); }