开发者

Cumulative distribution function: how to calculate it in discrete case

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

Cumulative distribution function: how to calculate it in discrete case

(source: wikimedia.org)

In order to use this formula I devided the histogram by number of image pixels. So I go开发者_如何学编程t 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?


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


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜