累积分布函数:如何在离散情况下计算它

时间:2010-02-17 16:13:52

标签: image-processing

我有一些价值观及其可能性,实际上是图像的直方图。 我的目标是使用以下公式来均衡直方图: alt text http://upload.wikimedia.org/math/1/a/d/1ad81c5bfdd01016c7019a33dd1faea1.png

为了使用这个公式,我按照图像像素的数量划分了直方图。所以我得到了一个标准化的直方图(概率值)。 然后,对于图像的每个像素,我使用上面的公式计算了一个新值,所以我只是对归一化直方图的元素进行求和。 例如,具有值23的像素获得新值,其被计算为从0到23的归一化直方图的元素的总和。 hist [0] + ... + hist [23]。 然后将总和乘以255得到0到25​​5之间的值(不在0和1之间)

该方法给出了很好的结果,我在书中看到了一些结果,但在我的情况下,我的实现没有给出好的结果,实际上是错的,有人看到我的方法中的错误吗?

2 个答案:

答案 0 :(得分:1)

您似乎在描述正确的算法;有关直方图均衡的另一个指针,请参见此处:

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

我怀疑错误不是在算法中,而是在你的实现中。您是否检查过直方图看起来合理?代码是否合理地短,以便您可以发布它?

答案 1 :(得分:1)

这是C#中的一个实现。在我的情况下,当我完成计算时,我将直方图标准化。它可能会帮助你

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