/// <summary>
        /// Any pixel values above threshold will be changed to max value.
        /// (Low-pass filter)
        /// </summary>
        /// <param name="imageBytes">Image bytes (Grayscale/RGB)</param>
        /// <param name="pixelDepth">Pixel depth. i.e. 1 for grayscale, 3 for color</param>
        /// <param name="maxValue">Max value to retain</param>
        public static void ApplyMaxDirect(byte[] imageBytes, int pixelDepth, byte maxValue)
        {
            bool isColor = BitmapDataExt.IsColorPixelDepth(pixelDepth);

            // Apply threshold value to image.
            for (int i = 0; i < imageBytes.Length; i += pixelDepth)
            {
                if (imageBytes[i] > maxValue)
                {
                    imageBytes[i] = maxValue;
                }

                if (isColor && i < imageBytes.Length - 2)
                {
                    // G
                    if (imageBytes[i + 1] > maxValue)
                    {
                        imageBytes[i + 1] = maxValue;
                    }

                    // R
                    if (imageBytes[i + 2] > maxValue)
                    {
                        imageBytes[i + 2] = maxValue;
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Gets (256) array of histogram values for image.
        /// </summary>
        /// <param name="imageBytes">Image bytes</param>
        /// <param name="pixelDepth">Pixel depth of image</param>
        /// <returns>256 array of histogram values</returns>
        public static int[] GetHistogramValues(byte[] imageBytes, int pixelDepth)
        {
            bool isColor = BitmapDataExt.IsColorPixelDepth(pixelDepth);

            // 0-255
            int[] histogram = new int[byte.MaxValue + 1];

            int  limit = BitmapDataExt.GetSafeArrayLimitForImage(isColor, pixelDepth, imageBytes);
            byte avg;

            // Find number of pixels at each level.
            for (int i = 0; i < limit; i += pixelDepth)
            {
                if (isColor)
                {
                    avg = (byte)((imageBytes[i] + imageBytes[i + 1] + imageBytes[i + 2]) / 3);
                }
                else
                {
                    avg = imageBytes[i];
                }

                // double-check within range.
                if (avg >= 0 && avg < histogram.Length)
                {
                    histogram[avg]++;
                }
            }

            return(histogram);
        }
        /// <summary>
        /// Histogram Equalization will enhance general contrast
        /// by distributing grey levels wider and more evenly.
        /// </summary>
        /// <param name="imageBytes">Image bytes</param>
        /// <param name="pixelDepth">Pixel depth of image</param>
        /// <param name="imageWidth">Image width</param>
        /// <param name="imageHeight">Image height</param>
        public static void HistogramEqualizationDirect(byte[] imageBytes, int pixelDepth, int imageWidth, int imageHeight)
        {
            int[] histogram = ImageHistogram.GetHistogramValues(imageBytes, pixelDepth);

            double numberOfPixels      = imageWidth * imageHeight;
            double numberOfLevels      = histogram.Length;
            int    cumulativeFrequency = 0;
            int    equalizedValue;

            // Calculate cumulative distribution for histogram
            for (int i = 0; i < histogram.Length; i++)
            {
                cumulativeFrequency += histogram[i];

                // Calculate equalized value
                equalizedValue = (int)Math.Round((numberOfLevels * cumulativeFrequency) / numberOfPixels) - 1;

                // Ensure +ve value
                histogram[i] = Math.Max(0, equalizedValue);
            }

            bool isColor = BitmapDataExt.IsColorPixelDepth(pixelDepth);
            int  limit   = BitmapDataExt.GetSafeArrayLimitForImage(isColor, pixelDepth, imageBytes);

            // Apply distribution to image to equalize
            if (isColor)
            {
                // Exclude alpha/transparency byte
                int pixelDepthWithoutAlpha = Math.Min(pixelDepth, Constants.PixelDepthRGB);

                for (int i = 0, j; i < limit; i += pixelDepth)
                {
                    for (j = 0; j < pixelDepthWithoutAlpha; j++)
                    {
                        imageBytes[i + j] = (byte)histogram[imageBytes[i + j]];
                    }
                }
            }
            else
            {
                for (int i = 0; i < limit; i++)
                {
                    imageBytes[i] = (byte)histogram[imageBytes[i]];
                }
            }
        }
        /// <summary>
        /// Any pixel values outside the threshold will be changed to min/max.
        /// </summary>
        /// <param name="imageBytes">Image bytes (Grayscale/RGB)</param>
        /// <param name="pixelDepth">Depth of pixels (typically 1 for grayscale, 3 for color)</param>
        /// <param name="minValue">Minimum threshold value</param>
        /// <param name="maxValue">Maximum threshold value</param>
        public static void ApplyMinMaxDirect(byte[] imageBytes, int pixelDepth, byte minValue, byte maxValue)
        {
            bool isColor = BitmapDataExt.IsColorPixelDepth(pixelDepth);

            // Adjust image to within min/max.
            for (int i = 0; i < imageBytes.Length; i += pixelDepth)
            {
                // Change values outside threshold to extremes
                if (imageBytes[i] < minValue)
                {
                    imageBytes[i] = minValue;
                }
                else if (imageBytes[i] > maxValue)
                {
                    imageBytes[i] = maxValue;
                }

                // Extra bytes for color images (RGB)
                if (isColor && i < imageBytes.Length - 2)
                {
                    // G
                    if (imageBytes[i + 1] < minValue)
                    {
                        imageBytes[i + 1] = minValue;
                    }
                    else if (imageBytes[i + 1] > maxValue)
                    {
                        imageBytes[i + 1] = maxValue;
                    }

                    // R
                    if (imageBytes[i + 2] < minValue)
                    {
                        imageBytes[i + 2] = minValue;
                    }
                    else if (imageBytes[i + 2] > maxValue)
                    {
                        imageBytes[i + 2] = maxValue;
                    }
                }
            }
        }