views:

281

answers:

2

I have some values and their possibilities, actually histogram of image. My aim is to equalize that histogram using this formula: alt text

In order to use this formula I devided the histogram by number of image pixels. So I got a normalized histogram (probability values). Then for every pixel of the image I calculated a new value using that formula above, so I just make a sum of elements of normalized histogram. For example pixel with value 23 gets a new value which is calculated as the sum of elements of normalized histogram from 0 to 23. hist[0] + ... + hist[23]. And then multiplying the sum by 255 to get values between 0 and 255 (not between 0 and 1)

The method gives good result, I saw some results in the book, but in my case, my implementation doesn't give good results, it is wrong actually, does anybody see the mistake in my approach?

+1  A: 

You seem to be describing the correct algorithm; for another pointer on histogram equalization, see here:

http://en.wikipedia.org/wiki/Histogram_equalization#Implementation

I suspect that the mistake is not in the algorithm but in your implementation of it. Have you checked to see that the histogram looks reasonable? Is the code reasonably short so that you can post it?

Martin B
+1  A: 

This is an implementation in C#. In my case I normalize the histogram when I finish to calculate it. It may help you

public void Histogram(double[] histogram, Rectangle roi)
        {
            BitmapData data = Util.SetImageToProcess(image, roi);

            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
                return;

            if (histogram.Length < Util.GrayLevels)
                return;

            histogram.Initialize();
            int width = data.Width;
            int height = data.Height;
            int offset = data.Stride - width;

            unsafe
            {
                byte* ptr = (byte*)data.Scan0;

                for (int y = 0; y < height; ++y)
                {
                    for (int x = 0; x < width; ++x, ++ptr)
                        histogram[ptr[0]]++;

                    ptr += offset;
                }
            }
            image.UnlockBits(data);

            NormalizeHistogram(histogram, height * width);
        }

        public void NormalizeHistogram(double[] histogram, int imageArea)
        {
            for (int i = 0; i < histogram.Length; ++i)
                histogram[i] = (double)histogram[i] / imageArea;
        }

 public void HistogramEqualization(double[] histogram)
        {
            double[] cdf = new double[Util.GrayLevels];

            double sum = 0;
            for (int i = 0; i < Util.GrayLevels; i++)
            {
                sum += histogram[i];
                cdf[i] = sum;
            }

            BitmapData data = Util.SetImageToProcess(image);

            unsafe
            {
                byte* ptr = (byte*)data.Scan0;
                int offset = data.Stride - data.Width;
                int width = data.Width;
                int height = data.Height;

                for(int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; ++x, ++ptr)
                        ptr[0] = (byte)(cdf[ptr[0]] * ((byte)Util.MaxGrayLevel));

                }
                ptr += offset;
            }
            image.UnlockBits(data);
        }



    static public BitmapData SetImageToProcess(Bitmap image, Rectangle roi)
    {
        if (image != null)
            return image.LockBits(
                roi,
                ImageLockMode.ReadWrite,
                image.PixelFormat);

        return null;
    }
Andres
Thanks! It really helped!
maximus