Accord.Vision.Tracking.Camshift.createHistogram C# (CSharp) Method

createHistogram() private method

Creates a color histogram discarding low intensity colors
private createHistogram ( UnmanagedImage frame, Rectangle area ) : float[]
frame Accord.Imaging.UnmanagedImage
area System.Drawing.Rectangle
return float[]
        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));

                        Accord.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));

                        Accord.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;
        }