public LayerProperties() { colorReplacement = Color.White; hslReplacementColor = new HSL(); RGB c = new RGB(colorReplacement); AForge.Imaging.ColorConverter.RGB2HSL(c,hslReplacementColor); }
static KernelSupportVectorMachine LearnSVM(HSL[] positives, HSL[] negatives, double throwExceptionWhenErrorGreaterThan) { int[] classes = new int[positives.Length + negatives.Length]; double[][] vectors = new double[classes.Length][]; int index = 0; for (int c = 0; c < positives.Length; c++, index++) { classes[index] = 1; vectors[index] = HSLToDouble(positives[c]); } for (int c = 0; c < negatives.Length; c++, index++) { classes[index] = -1; vectors[index] = HSLToDouble(negatives[c]); } KernelSupportVectorMachine svm = new KernelSupportVectorMachine(new Gaussian(.1), vectors[0].Length); SequentialMinimalOptimization smo = new SequentialMinimalOptimization(svm, vectors.ToArray(), classes); //smo.Complexity = 1.0; double error = smo.Run(); if (error > throwExceptionWhenErrorGreaterThan) { throw new Exception("Failed to get reasonable error value."); } return svm; }
public void AddColor(HSL selectedColor,IntRange Hue_range, DoubleRange Saturation_range, DoubleRange Luminance_range) { TreeNode node = new TreeNode(new String(' ',100)); node.Tag = new LayerColor(selectedColor, Hue_range, Saturation_range, Luminance_range); node.Checked = true; new_color_parent.Nodes.Add(node); new_color_parent.ExpandAll(); treeLayers.SelectedNode = node; UpdateFilter(); }
public LayerColor(HSL _color, IntRange _hue_range, DoubleRange _sat_range, DoubleRange _lum_range) { color = _color; hue_range = _hue_range; sat_range = _sat_range; lum_range = _lum_range; RGB rgb = new RGB(); AForge.Imaging.ColorConverter.HSL2RGB(color, rgb); RGBColor = rgb.Color; }
/// <summary> /// Convert from RGB to HSL color space. /// </summary> /// /// <param name="rgb">Source color in <b>RGB</b> color space.</param> /// <param name="hsl">Destination color in <b>HSL</b> color space.</param> /// /// <remarks><para>See <a href="http://en.wikipedia.org/wiki/HSI_color_space#Conversion_from_RGB_to_HSL_or_HSV">HSL and HSV Wiki</a> /// for information about the algorithm to convert from RGB to HSL.</para></remarks> /// public static void FromRGB( RGB rgb, HSL hsl ) { float r = ( rgb.Red / 255.0f ); float g = ( rgb.Green / 255.0f ); float b = ( rgb.Blue / 255.0f ); float min = Math.Min( Math.Min( r, g ), b ); float max = Math.Max( Math.Max( r, g ), b ); float delta = max - min; // get luminance value hsl.Luminance = ( max + min ) / 2; if ( delta == 0 ) { // gray color hsl.Hue = 0; hsl.Saturation = 0.0f; } else { // get saturation value hsl.Saturation = ( hsl.Luminance <= 0.5 ) ? ( delta / ( max + min ) ) : ( delta / ( 2 - max - min ) ); // get hue value float hue; if ( r == max ) { hue = ( ( g - b ) / 6 ) / delta; } else if ( g == max ) { hue = ( 1.0f / 3 ) + ( ( b - r ) / 6 ) / delta; } else { hue = ( 2.0f / 3 ) + ( ( r - g ) / 6 ) / delta; } // correct hue if needed if ( hue < 0 ) hue += 1; if ( hue > 1 ) hue -= 1; hsl.Hue = (int) ( hue * 360 ); } }
public static void ToRGB(HSL hsl, RGB rgb) { if (hsl.Saturation == 0.0) { rgb.Red = rgb.Green = rgb.Blue = (byte)(hsl.Luminance * 255.0); } else { double vH = ((double)hsl.Hue) / 360.0; double num2 = (hsl.Luminance < 0.5) ? (hsl.Luminance * (1.0 + hsl.Saturation)) : ((hsl.Luminance + hsl.Saturation) - (hsl.Luminance * hsl.Saturation)); double num = (2.0 * hsl.Luminance) - num2; rgb.Red = (byte)(255.0 * Hue_2_RGB(num, num2, vH + 0.33333333333333331)); rgb.Green = (byte)(255.0 * Hue_2_RGB(num, num2, vH)); rgb.Blue = (byte)(255.0 * Hue_2_RGB(num, num2, vH - 0.33333333333333331)); } }
// Convert from RGB to HSL color space public static void RGB2HSL(RGB rgb, HSL hsl) { double r = (rgb.Red / 255.0); double g = (rgb.Green / 255.0); double b = (rgb.Blue / 255.0); double min = Math.Min(Math.Min(r, g), b); double max = Math.Max(Math.Max(r, g), b); double delta = max - min; // get luminance value hsl.Luminance = (max + min) / 2; if (delta == 0) { // gray color hsl.Hue = 0; hsl.Saturation = 0.0; } else { // get saturation value hsl.Saturation = (hsl.Luminance < 0.5) ? (delta / (max + min)) : (delta / (2 - max - min)); // get hue value double del_r = (((max - r) / 6) + (delta / 2)) / delta; double del_g = (((max - g) / 6) + (delta / 2)) / delta; double del_b = (((max - b) / 6) + (delta / 2)) / delta; double hue; if (r == max) hue = del_b - del_g; else if (g == max) hue = (1.0 / 3) + del_r - del_b; else hue = (2.0 / 3) + del_g - del_r; // correct hue if needed if (hue < 0) hue += 1; if (hue > 1) hue -= 1; hsl.Hue = (int) (hue * 360); } }
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]; RGB rgb = new RGB(); HSL hsl = new HSL(); 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]; HSL.FromRGB(rgb, hsl); numArray[(int)(hsl.Saturation * 255.0)]++; numArray2[(int)(hsl.Luminance * 255.0)]++; this.pixels++; if (hsl.Luminance != 0.0) { numArray3[(int)(hsl.Saturation * 255.0)]++; numArray4[(int)(hsl.Luminance * 255.0)]++; this.pixelsWithoutBlack++; } num6++; numPtr += num3; } numPtr += num4; } this.saturation = new ContinuousHistogram(numArray, new DoubleRange(0.0, 1.0)); this.luminance = new ContinuousHistogram(numArray2, new DoubleRange(0.0, 1.0)); this.saturationWithoutBlack = new ContinuousHistogram(numArray3, new DoubleRange(0.0, 1.0)); this.luminanceWithoutBlack = new ContinuousHistogram(numArray4, new DoubleRange(0.0, 1.0)); }
public static void FromRGB(RGB rgb, HSL hsl) { double num = ((double)rgb.Red) / 255.0; double num2 = ((double)rgb.Green) / 255.0; double num3 = ((double)rgb.Blue) / 255.0; double num4 = Math.Min(Math.Min(num, num2), num3); double num5 = Math.Max(Math.Max(num, num2), num3); double num6 = num5 - num4; hsl.Luminance = (num5 + num4) / 2.0; if (num6 == 0.0) { hsl.Hue = 0; hsl.Saturation = 0.0; } else { double num7; hsl.Saturation = (hsl.Luminance <= 0.5) ? (num6 / (num5 + num4)) : (num6 / ((2.0 - num5) - num4)); if (num == num5) { num7 = ((num2 - num3) / 6.0) / num6; } else if (num2 == num5) { num7 = 0.33333333333333331 + (((num3 - num) / 6.0) / num6); } else { num7 = 0.66666666666666663 + (((num - num2) / 6.0) / num6); } if (num7 < 0.0) { num7++; } if (num7 > 1.0) { num7--; } hsl.Hue = (int)(num7 * 360.0); } }
// Convert from HSL to RGB color space public static void HSL2RGB(HSL hsl, RGB rgb) { if (hsl.Saturation == 0) { // gray values rgb.Red = rgb.Green = rgb.Blue = (byte) (hsl.Luminance * 255); } else { double v1, v2; double hue = (double) hsl.Hue / 360; v2 = (hsl.Luminance < 0.5) ? (hsl.Luminance * (1 + hsl.Saturation)) : ((hsl.Luminance + hsl.Saturation) - (hsl.Luminance * hsl.Saturation)); v1 = 2 * hsl.Luminance - v2; rgb.Red = (byte)(255 * Hue_2_RGB(v1, v2, hue + (1.0 / 3))); rgb.Green = (byte)(255 * Hue_2_RGB(v1, v2, hue)); rgb.Blue = (byte)(255 * Hue_2_RGB(v1, v2, hue - (1.0 / 3))); } }
// Convert from HSL to RGB color space public static void HSL2RGB(HSL hsl, RGB rgb) { if (hsl.Saturation == 0) { // gray values rgb.Red = rgb.Green = rgb.Blue = (byte)(hsl.Luminance * 255); } else { double v1, v2; double hue = (double)hsl.Hue / 360; v2 = (hsl.Luminance < 0.5) ? (hsl.Luminance * (1 + hsl.Saturation)) : ((hsl.Luminance + hsl.Saturation) - (hsl.Luminance * hsl.Saturation)); v1 = 2 * hsl.Luminance - v2; rgb.Red = (byte)(255 * Hue_2_RGB(v1, v2, hue + (1.0 / 3))); rgb.Green = (byte)(255 * Hue_2_RGB(v1, v2, hue)); rgb.Blue = (byte)(255 * Hue_2_RGB(v1, v2, hue - (1.0 / 3))); } }
static void PrintAccuracy(string colorName, KernelSupportVectorMachine svm, HSL[] positives, HSL[] negatives) { int numberCorrect = 0; for (int c = 0; c < positives.Length; c++) { double result = svm.Compute(HSLToDouble(positives[c])); if (Math.Sign(result) == 1) { numberCorrect++; } } for (int c = 0; c < negatives.Length; c++) { double result = svm.Compute(HSLToDouble(negatives[c])); if (Math.Sign(result) == -1) { numberCorrect++; } } Console.WriteLine(colorName + " accuracy is " + (numberCorrect / (positives.Length + negatives.Length * 1.0)).ToString()); }
/// <summary> /// Convert from HSL to RGB color space. /// </summary> /// /// <param name="hsl">Source color in <b>HSL</b> color space.</param> /// <param name="rgb">Destination color in <b>RGB</b> color space.</param> /// public static void ToRGB(HSL hsl, RGB rgb) { if (hsl.Saturation == 0) { // gray values rgb.Red = rgb.Green = rgb.Blue = (byte)(hsl.Luminance * 255); } else { float v1, v2; float hue = (float)hsl.Hue / 360; v2 = (hsl.Luminance < 0.5) ? (hsl.Luminance * (1 + hsl.Saturation)) : ((hsl.Luminance + hsl.Saturation) - (hsl.Luminance * hsl.Saturation)); v1 = 2 * hsl.Luminance - v2; rgb.Red = (byte)(255 * Hue_2_RGB(v1, v2, hue + (1.0f / 3))); rgb.Green = (byte)(255 * Hue_2_RGB(v1, v2, hue)); rgb.Blue = (byte)(255 * Hue_2_RGB(v1, v2, hue - (1.0f / 3))); } rgb.Alpha = 255; }
// On mouse up private void ImageDoc_MouseUp( object sender, System.Windows.Forms.MouseEventArgs e ) { //SS: завершение выделения области или точки if (dragging && !(avcolorselectionarea || avcolorselectionpoint || layerselectionpoint)) { // stop dragging and cropping dragging = cropping = false; // release capture this.Capture = false; // set default mouse pointer this.Cursor = Cursors.Default; // erase frame Graphics g = this.CreateGraphics( ); DrawSelectionFrame( g ); g.Dispose( ); // normalize start and end points NormalizePoints( ref start, ref end ); // crop tge image logger.StoreMessage("Cropping image"); ApplyFilter( new Crop( new Rectangle( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 ) ) ); } if (avcolorselectionarea) { dragging = false; this.AvegareColorSelectArea(); // release capture this.Capture = false; Graphics g = this.CreateGraphics(); DrawSelectionFrame(g); g.Dispose(); NormalizePoints(ref start, ref end); averageArea = new Rectangle(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1); CalcAverageColor(); } if (avcolorselectionpoint) { //SS: выключаем режим выбора точки this.AvegareColorSelectPoint(); this.Capture = false; NormalizePoints(ref start, ref end); //SS: расчет фактических размеров области вокруг выбранной точки Point TopLeft = new Point(start.X - ((int)averageAreaSizes.X / 2), start.Y - ((int)averageAreaSizes.Y / 2)); if (TopLeft.X < 0) TopLeft.X = 0; if (TopLeft.Y < 0) TopLeft.Y = 0; int area_width = TopLeft.X + averageAreaSizes.X < image.Width ? averageAreaSizes.X : image.Width - TopLeft.X; int area_height = TopLeft.Y + averageAreaSizes.Y < image.Height ? averageAreaSizes.Y : image.Height - TopLeft.Y; averageArea = new Rectangle(TopLeft, new Size(area_width, area_height)); CalcAverageColor(); } if (layerselectionpoint) { //SS: выключаем режим выбора точки this.LayerSelectPoint(); this.Capture = false; NormalizePoints(ref start, ref end); Color pixel = image.GetPixel(start.X, start.Y); HSL hsl_pixel = new HSL(); AForge.Imaging.ColorConverter.RGB2HSL(new RGB(pixel), hsl_pixel); colorHSLPreviewForm form = new colorHSLPreviewForm(); form.SelectedColor = hsl_pixel; if (form.ShowDialog() == DialogResult.OK) { HSLLayers.AddColor(hsl_pixel,form.Hue_range,form.Saturation_range,form.Luminance_range); } form.Dispose(); HSLLayers.Show(); } }
private void fillColorCombo_SelectedIndexChanged(object sender, EventArgs e) { RGB selected_color=new RGB((Color)fillColorCombo.Items[fillColorCombo.SelectedIndex]); HSL hsl = new HSL(); AForge.Imaging.ColorConverter.RGB2HSL(selected_color, hsl); filter.FillColor = hsl; filterPreview.RefreshFilter(); }
public void SetAverageColor(HSL avgColor) { averageColor = avgColor; Graphics g = Graphics.FromImage(previewFillColor.Image); RGB rgbpreview = new RGB(); AForge.Imaging.ColorConverter.HSL2RGB(averageColor,rgbpreview); g.FillRectangle(new SolidBrush(rgbpreview.Color), 0, 0, previewFillColor.Width, previewFillColor.Height); g.DrawRectangle(new Pen(new SolidBrush(Color.Black)), new Rectangle(0, 0, previewFillColor.Width - 1, previewFillColor.Height - 3)); g.Dispose(); previewFillColor.Invalidate(); avgColorH.Text = string.Format("{0}", averageColor.Hue); avgColorS.Text = string.Format("{0:F3}", averageColor.Saturation); avgColorL.Text = string.Format("{0:F3}", averageColor.Luminance); }
// Paint control protected override void OnPaint( PaintEventArgs pe ) { Graphics g = pe.Graphics; Rectangle rc = this.ClientRectangle; Rectangle rcPie; Brush brush; RGB rgb = new RGB( ); HSL hsl = new HSL( ); // get pie rectangle rcPie = new Rectangle( 4, 4, Math.Min( rc.Right, rc.Bottom ) - 8, Math.Min( rc.Right, rc.Bottom ) - 8 ); // init HSL value hsl.Luminance = 0.5; hsl.Saturation = 1.0; if ( type == HuePickerType.Value ) { // draw HSL pie for ( int i = 0; i < 360; i++ ) { hsl.Hue = i; // convert from HSL to RGB AForge.Imaging.ColorConverter.HSL2RGB( hsl, rgb ); // create brush brush = new SolidBrush( rgb.Color ); // draw one hue value g.FillPie( brush, rcPie, -i, -1 ); brush.Dispose( ); } } else { // draw HSL pie for ( int i = 0; i < 360; i++ ) { if ( ( ( min < max ) && ( i >= min ) && ( i <= max ) ) || ( ( min > max ) && ( ( i >= min ) || ( i <= max ) ) ) ) { hsl.Hue = i; // convert from HSL to RGB AForge.Imaging.ColorConverter.HSL2RGB( hsl, rgb ); // create brush brush = new SolidBrush( rgb.Color ); } else { brush = new SolidBrush( Color.FromArgb( 128, 128, 128 ) ); } // draw one hue value g.FillPie( brush, rcPie, -i, -1 ); brush.Dispose( ); } } // double halfWidth = (double) rcPie.Width / 2; double angleRad = -min * Math.PI / 180; double angleCos = Math.Cos( angleRad ); double angleSin = Math.Sin( angleRad ); double x = halfWidth * angleCos; double y = halfWidth * angleSin; ptCenter.X = rcPie.Left + (int) ( halfWidth ); ptCenter.Y = rcPie.Top + (int) ( halfWidth ); ptMin.X = rcPie.Left + (int) ( halfWidth + x ); ptMin.Y = rcPie.Top + (int) ( halfWidth + y ); // draw MIN pointer g.FillEllipse( blackBrush, rcPie.Left + (int) ( halfWidth + x ) - 4, rcPie.Top + (int) ( halfWidth + y ) - 4, 8, 8 ); g.DrawLine( blackPen, ptCenter, ptMin ); // check picker type if ( type == HuePickerType.Region ) { angleRad = -max * Math.PI / 180; angleCos = Math.Cos( angleRad ); angleSin = Math.Sin( angleRad ); x = halfWidth * angleCos; y = halfWidth * angleSin; ptMax.X = rcPie.Left + (int) ( halfWidth + x ); ptMax.Y = rcPie.Top + (int) ( halfWidth + y ); // draw MAX pointer g.FillEllipse( whiteBrush, rcPie.Left + (int) ( halfWidth + x ) - 4, rcPie.Top + (int) ( halfWidth + y ) - 4, 8, 8 ); g.DrawLine( whitePen, ptCenter, ptMax ); } base.OnPaint( pe ); }
// 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[] s = new int[256]; int[] l = new int[256]; int[] swb = new int[256]; int[] lwb = new int[256]; RGB rgb = new RGB( ); HSL hsl = new HSL( ); 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 HSL color space AForge.Imaging.HSL.FromRGB( rgb, hsl ); s[(int) ( hsl.Saturation * 255 )]++; l[(int) ( hsl.Luminance * 255 )]++; pixels++; if ( hsl.Luminance != 0.0 ) { swb[(int) ( hsl.Saturation * 255 )]++; lwb[(int) ( hsl.Luminance * 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 HSL color space AForge.Imaging.HSL.FromRGB( rgb, hsl ); s[(int) ( hsl.Saturation * 255 )]++; l[(int) ( hsl.Luminance * 255 )]++; pixels++; if ( hsl.Luminance != 0.0 ) { swb[(int) ( hsl.Saturation * 255 )]++; lwb[(int) ( hsl.Luminance * 255 )]++; pixelsWithoutBlack++; } } p += offset; mask += maskOffset; } } // create histograms saturation = new ContinuousHistogram( s, new Range( 0, 1 ) ); luminance = new ContinuousHistogram( l, new Range( 0, 1 ) ); saturationWithoutBlack = new ContinuousHistogram( swb, new Range( 0, 1 ) ); luminanceWithoutBlack = new ContinuousHistogram( lwb, new Range( 0, 1 ) ); }
public static void inkFinder() { Image<Hls, Byte> wrk = new Image<Hls, Byte>(img); Image<Gray, Byte>[] channels = wrk.Split(); Image<Gray, Byte> imgHue = channels[0]; Image<Gray, Byte> imgLig = channels[1]; Image<Gray, Byte> imgSat = channels[2]; int bl = 0; int wi = 0; int col = 0; ArrayList white = new ArrayList(); // HSL for white ones //ArrayList black = new ArrayList(); // HSL for black ones ArrayList other = new ArrayList(); // // collect for (int i = 0; i < wrk.Height; i++) { for (int j = 0; j < wrk.Width; j++) { int hue = (int)(imgHue[i, j].Intensity * 2); float sat = (float)(imgSat[i, j].Intensity/255); float lig = (float)(imgLig[i, j].Intensity/255); //double border = -Math.Sqrt((1 - (lig - 0.5f) * (lig - 0.5f) / 0.34 / 0.34) * 0.84 * 0.84) + 1; if (lig < 0.275 - 0.125 * sat || lig < 0.5 - 0.5 * sat / 0.6 || (sat < 0.18 && lig < 0.5)) { //black.Add(new HSL(hue, sat, lig)); bl++; continue; } if (lig > 0.725 + 0.125 * sat || lig > 0.5 + 0.5 * sat / 0.6 || (sat < 0.18 && lig >= 0.5)) { white.Add(new HSL(hue, sat, lig)); wi++; continue; } col++; addToOther(other, 5, hue, sat, lig); } Console.WriteLine("Row - " + i + " : clusters - " + other.Count); } Console.WriteLine(bl + " " + wi + " " + col); Console.WriteLine(other.Count); ArrayList majCol = (ArrayList)other[0]; // // find major color for (int t = 0; t < other.Count; t++) { if (majCol.Count < ((ArrayList)other[t]).Count) { majCol = (ArrayList)other[t]; } } // // find ranges HSL firstCol = (HSL)majCol[0]; filterHue = new IntRange(firstCol.Hue, firstCol.Hue); filterLig = new Range(firstCol.Luminance, firstCol.Luminance); filterSat = new Range(firstCol.Saturation, firstCol.Saturation); for (int q = 0; q < majCol.Count; q++) { HSL nextCol = (HSL)majCol[q]; if (nextCol.Hue < filterHue.Min) filterHue.Min = nextCol.Hue; if (nextCol.Hue > filterHue.Max) filterHue.Max = nextCol.Hue; if (nextCol.Luminance < filterLig.Min) filterLig.Min = nextCol.Luminance; if (nextCol.Luminance > filterLig.Max) filterLig.Max = nextCol.Luminance; if (nextCol.Saturation < filterSat.Min) filterSat.Min = nextCol.Saturation; if (nextCol.Saturation > filterSat.Max) filterSat.Max = nextCol.Saturation; } // // find fill color int huesum = 0; float satsum = 0; float ligsum = 0; for (int p = 0; p < white.Count; p++) { HSL wh = (HSL)white[p]; huesum += wh.Hue; satsum += wh.Saturation; ligsum += wh.Luminance; } fillColor = new HSL(huesum / white.Count, satsum / white.Count, ligsum / white.Count); }
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]; RGB rGB = new RGB(); HSL hSL = new HSL(); 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; HSL.FromRGB(rGB, hSL); array[(int)(hSL.Saturation * 255f)]++; array2[(int)(hSL.Luminance * 255f)]++; pixels++; if ((double)hSL.Luminance != 0.0) { array3[(int)(hSL.Saturation * 255f)]++; array4[(int)(hSL.Luminance * 255f)]++; 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; HSL.FromRGB(rGB, hSL); array[(int)(hSL.Saturation * 255f)]++; array2[(int)(hSL.Luminance * 255f)]++; pixels++; if ((double)hSL.Luminance != 0.0) { array3[(int)(hSL.Saturation * 255f)]++; array4[(int)(hSL.Luminance * 255f)]++; pixelsWithoutBlack++; } } num5++; ptr += num; mask++; } ptr += num2; mask += num3; } } saturation = new ContinuousHistogram(array, new Range(0f, 1f)); luminance = new ContinuousHistogram(array2, new Range(0f, 1f)); saturationWithoutBlack = new ContinuousHistogram(array3, new Range(0f, 1f)); luminanceWithoutBlack = new ContinuousHistogram(array4, new Range(0f, 1f)); }
/// <summary> /// Convert from RGB to HSL color space. /// </summary> /// /// <param name="rgb">Source color in <b>RGB</b> color space.</param> /// /// <returns>Returns <see cref="HSL"/> instance, which represents converted color value.</returns> /// public static HSL FromRGB( RGB rgb ) { HSL hsl = new HSL( ); FromRGB( rgb, hsl ); return hsl; }
/// <summary> /// Image histogram back-projection. /// </summary> /// private unsafe void generateBackprojectionMap(UnmanagedImage frame, float[] ratioHistogram) { int width = frame.Width; int height = frame.Height; int stride = frame.Stride; int pixelSize = Bitmap.GetPixelFormatSize(frame.PixelFormat) / 8; int offset = stride - width * pixelSize; fixed (float* map_ptr = map) { byte* src = (byte*)frame.ImageData.ToPointer(); float* dst = map_ptr; if (mode == CamshiftMode.HSL) { // Process as HSL HSL hsl = new HSL(); RGB rgb = new RGB(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src += pixelSize, dst++) { // RGB rgb.Red = (*(src + RGB.R)); rgb.Green = (*(src + RGB.G)); rgb.Blue = (*(src + RGB.B)); // Transform into HSL AForge.Imaging.HSL.FromRGB(rgb, hsl); if ((hsl.Saturation >= hslSaturation.Min) && (hsl.Saturation <= hslSaturation.Max) && (hsl.Luminance >= hslLuminance.Min) && (hsl.Luminance <= hslLuminance.Max)) *dst = ratioHistogram[hsl.Hue]; else *dst = 0; } src += offset; } } else if (mode == CamshiftMode.Mixed) { // Process in mixed mode HSL hsl = new HSL(); RGB rgb = new RGB(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src += pixelSize, dst++) { // RGB rgb.Red = (*(src + RGB.R)); rgb.Green = (*(src + RGB.G)); rgb.Blue = (*(src + RGB.B)); // Transform into HSL AForge.Imaging.HSL.FromRGB(rgb, hsl); if ((hsl.Saturation >= hslSaturation.Min) && (hsl.Saturation <= hslSaturation.Max) && (hsl.Luminance >= hslLuminance.Min) && (hsl.Luminance <= hslLuminance.Max)) *dst = ratioHistogram[(int)(hsl.Hue * 10 + hsl.Saturation * 100 + hsl.Luminance * 10)]; else *dst = 0; } src += offset; } } else { // Process as RGB for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src += pixelSize, dst++) { // RGB int r = (int)(*(src + RGB.R)) >> 4; int g = (int)(*(src + RGB.G)) >> 4; int b = (int)(*(src + RGB.B)) >> 4; *dst = ratioHistogram[256 * r + 16 * g + b]; } src += offset; } } } }
/// <summary> /// Creates a color histogram discarding low intensity colors /// </summary> /// private unsafe float[] createHistogram(UnmanagedImage frame, Rectangle area) { int width = frame.Width; int height = frame.Height; int stride = frame.Stride; int pixelSize = Bitmap.GetPixelFormatSize(frame.PixelFormat) / 8; int offset = stride - area.Width * pixelSize; float[] histogram = new float[histogramSize]; // stay inside the image int areaX = Math.Max(area.X, 0); int areaY = Math.Max(area.Y, 0); int areaWidth = Math.Min(area.Width, width - areaX); int areaHeight = Math.Min(area.Height, height - areaY); if (mode == CamshiftMode.HSL) { // Process as HSL HSL hsl = new HSL(); RGB rgb = new RGB(); byte* src = (byte*)frame.ImageData.ToPointer() + areaX * pixelSize + areaY * stride; for (int y = 0; y < areaHeight; y++) { for (int x = 0; x < areaWidth; x++, src += 3) { rgb.Red = (*(src + RGB.R)); rgb.Green = (*(src + RGB.G)); rgb.Blue = (*(src + RGB.B)); AForge.Imaging.HSL.FromRGB(rgb, hsl); if ((hsl.Saturation >= hslSaturation.Min) && (hsl.Saturation <= hslSaturation.Max) && (hsl.Luminance >= hslLuminance.Min) && (hsl.Luminance <= hslLuminance.Max)) histogram[hsl.Hue] += 1; } src += offset; } } else if (mode == CamshiftMode.Mixed) { // Process in mixed mode HSL hsl = new HSL(); RGB rgb = new RGB(); byte* src = (byte*)frame.ImageData.ToPointer() + areaX * pixelSize + areaY * stride; for (int y = 0; y < areaHeight; y++) { for (int x = 0; x < areaWidth; x++, src += 3) { rgb.Red = (*(src + RGB.R)); rgb.Green = (*(src + RGB.G)); rgb.Blue = (*(src + RGB.B)); AForge.Imaging.HSL.FromRGB(rgb, hsl); if ((hsl.Saturation >= hslSaturation.Min) && (hsl.Saturation <= hslSaturation.Max) && (hsl.Luminance >= hslLuminance.Min) && (hsl.Luminance <= hslLuminance.Max)) histogram[(int)(hsl.Hue * 10 + hsl.Saturation * 100 + hsl.Luminance * 10)] += 1; } src += offset; } } else { // Process as RGB byte* src = (byte*)frame.ImageData.ToPointer() + areaX * pixelSize + areaY * stride; for (int y = 0; y < areaHeight; y++) { for (int x = 0; x < areaWidth; x++, src += 3) { // (small values are discarded) int r = (int)(*(src + RGB.R)) >> 4; int g = (int)(*(src + RGB.G)) >> 4; int b = (int)(*(src + RGB.B)) >> 4; histogram[256 * r + 16 * g + b] += 1; } src += offset; } } return histogram; }
/// <summary> /// Convert from HSL to RGB color space. /// </summary> /// /// <param name="hsl">Source color in <b>HSL</b> color space.</param> /// <param name="rgb">Destination color in <b>RGB</b> color space.</param> /// public static void ToRGB( HSL hsl, RGB rgb ) { if ( hsl.Saturation == 0 ) { // gray values rgb.Red = rgb.Green = rgb.Blue = (byte) ( hsl.Luminance * 255 ); } else { float v1, v2; float hue = (float) hsl.Hue / 360; v2 = ( hsl.Luminance < 0.5 ) ? ( hsl.Luminance * ( 1 + hsl.Saturation ) ) : ( ( hsl.Luminance + hsl.Saturation ) - ( hsl.Luminance * hsl.Saturation ) ); v1 = 2 * hsl.Luminance - v2; rgb.Red = (byte) ( 255 * Hue_2_RGB( v1, v2, hue + ( 1.0f / 3 ) ) ); rgb.Green = (byte) ( 255 * Hue_2_RGB( v1, v2, hue ) ); rgb.Blue = (byte) ( 255 * Hue_2_RGB( v1, v2, hue - ( 1.0f / 3 ) ) ); rgb.Alpha = 255; } }
static double[] HSLToDouble(HSL hsl) { return new double[] { hsl.Hue, hsl.Saturation, hsl.Luminance }; }
// 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[] s = new int[256]; int[] l = new int[256]; int[] swb = new int[256]; int[] lwb = new int[256]; RGB rgb = new RGB( ); HSL hsl = new HSL( ); 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 HSL color space AForge.Imaging.HSL.FromRGB(rgb, hsl); s[(int)(hsl.Saturation * 255)]++; l[(int)(hsl.Luminance * 255)]++; pixels++; if (hsl.Luminance != 0.0) { swb[(int)(hsl.Saturation * 255)]++; lwb[(int)(hsl.Luminance * 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 HSL color space AForge.Imaging.HSL.FromRGB(rgb, hsl); s[(int)(hsl.Saturation * 255)]++; l[(int)(hsl.Luminance * 255)]++; pixels++; if (hsl.Luminance != 0.0) { swb[(int)(hsl.Saturation * 255)]++; lwb[(int)(hsl.Luminance * 255)]++; pixelsWithoutBlack++; } } p += offset; mask += maskOffset; } } // create histograms saturation = new ContinuousHistogram(s, new Range(0, 1)); luminance = new ContinuousHistogram(l, new Range(0, 1)); saturationWithoutBlack = new ContinuousHistogram(swb, new Range(0, 1)); luminanceWithoutBlack = new ContinuousHistogram(lwb, new Range(0, 1)); }
//SS: процедура вычисления "среднего" цвета для двух моделей RGB и HSL private void CalcAverageColor() { uint pixel_count=0; if (avcolorspace == "RGB") { uint RSum=0, GSum=0, BSum=0; for (int i=AverageArea.Left;i<AverageArea.Right;i++) for (int j=AverageArea.Top;j<AverageArea.Bottom;j++) { Color Pixel = image.GetPixel(i, j); RSum += Pixel.R; GSum += Pixel.G; BSum += Pixel.B; pixel_count++; } averageRGB = new RGB((byte)(RSum / pixel_count),(byte)(GSum / pixel_count),(byte)(BSum / pixel_count)); AForge.Imaging.ColorConverter.RGB2HSL(averageRGB, averageHSL); logger.StoreMessage("Average color in RGB colorspace"); //вызываем форму фильтрации this.filteringRgbFiltersItem_Click(this, null); } else { uint HSum = 0; double SSum = 0, LSum = 0; for (int i=AverageArea.Left;i<=AverageArea.Right;i++) for (int j = AverageArea.Top; j <= AverageArea.Bottom; j++) { Color Pixel = image.GetPixel(i, j); HSum += (uint)Pixel.GetHue(); SSum += Pixel.GetSaturation(); LSum += Pixel.GetBrightness(); pixel_count++; } averageHSL = new HSL((int)(HSum/pixel_count),SSum/pixel_count,LSum/pixel_count); AForge.Imaging.ColorConverter.HSL2RGB(averageHSL, averageRGB); logger.StoreMessage("Average color in HSL colorspace"); //вызываем форму фильтрации this.filteringHslFiltersItem_Click(this, null); } }