Histogram for continuous random values.

The class wraps histogram for continuous stochastic function, which is represented by integer array and range of the function. Values of the integer array are treated as total amount of hits on the corresponding subranges, which are calculated by splitting the specified range into required amount of consequent ranges.

For example, if the integer array is equal to { 1, 2, 4, 8, 16 } and the range is set to [0, 1], then the histogram consists of next subranges: [0.0, 0.2] - 1 hit; [0.2, 0.4] - 2 hits; [0.4, 0.6] - 4 hits; [0.6, 0.8] - 8 hits; [0.8, 1.0] - 16 hits.

Sample usage:

// create histogram ContinuousHistogram histogram = new ContinuousHistogram( new int[] { 0, 0, 8, 4, 2, 4, 7, 1, 0 }, new DoubleRange( 0.0, 1.0 ) ); // get mean and standard deviation values System.Diagnostics.Debug.WriteLine( "mean = " + histogram.Mean + ", std.dev = " + histogram.StdDev );
Beispiel #1
0
        // Selection changed in component combo
        private void componentCombo_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            AForge.Math.ContinuousHistogram h = null;
            DoubleRange input  = new DoubleRange(0, 1);
            DoubleRange output = new DoubleRange(0, 1);

            if (componentCombo.SelectedIndex == 0)
            {
                // satureation
                h      = imgStat.Saturation;
                input  = inSaturation;
                output = outSaturation;
            }
            else
            {
                // luminance
                h      = imgStat.Luminance;
                input  = inLuminance;
                output = outLuminance;
            }

            histogram.Values = h.Values;

            inMinBox.Text  = input.Min.ToString("F3");
            inMaxBox.Text  = input.Max.ToString("F3");
            outMinBox.Text = output.Min.ToString("F3");
            outMaxBox.Text = output.Max.ToString("F3");

            // input slider
            inSlider.Min = (int)(input.Min * 255);
            inSlider.Max = (int)(input.Max * 255);
            // output slider
            outSlider.Min = (int)(output.Min * 255);
            outSlider.Max = (int)(output.Max * 255);
        }
        // Selection changed in component combo
        private void componentCombo_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            AForge.Math.ContinuousHistogram h = null;
            DoubleRange input  = new DoubleRange(0, 1);
            DoubleRange output = new DoubleRange(0, 1);
            double      start  = 0;

            switch (componentCombo.SelectedIndex)
            {
            case 0:
                // Y
                h      = imgStat.Y;
                input  = inY;
                output = outY;
                break;

            case 1:
                // Cb
                h      = imgStat.Cb;
                input  = inCb;
                output = outCb;
                start  = -0.5;
                break;

            case 2:
                // Cr
                h      = imgStat.Cr;
                input  = inCr;
                output = outCr;
                start  = -0.5;
                break;
            }

            histogram.Values = h.Values;

            inMinBox.Text  = input.Min.ToString("F3");
            inMaxBox.Text  = input.Max.ToString("F3");
            outMinBox.Text = output.Min.ToString("F3");
            outMaxBox.Text = output.Max.ToString("F3");

            // input slider
            inSlider.Min = (int)((input.Min - start) * 255);
            inSlider.Max = (int)((input.Max - start) * 255);
            // output slider
            outSlider.Min = (int)((output.Min - start) * 255);
            outSlider.Max = (int)((output.Max - start) * 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[] 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 ) );
        }
        // 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));
        }