Кумулятивная функция распределения: как рассчитать ее в дискретном случае - PullRequest
0 голосов
/ 17 февраля 2010

У меня есть некоторые значения и их возможности, собственно гистограмма изображения. Моя цель - выровнять эту гистограмму по следующей формуле: alt text
(источник: wikimedia.org )

Чтобы использовать эту формулу, я разделил гистограмму на количество пикселей изображения. Итак, я получил нормализованную гистограмму (значения вероятности). Затем для каждого пикселя изображения я рассчитал новое значение, используя эту формулу выше, поэтому я просто делаю сумму элементов нормализованной гистограммы. Например, пиксель со значением 23 получает новое значение, которое вычисляется как сумма элементов нормализованной гистограммы от 0 до 23. исторических [0] + ... + исторических [23]. А затем умножить сумму на 255, чтобы получить значения от 0 до 255 (не от 0 до 1)

Метод дает хороший результат, я видел некоторые результаты в книге, но в моем случае моя реализация не дает хороших результатов, на самом деле это неправильно, кто-нибудь видит ошибку в моем подходе?

Ответы [ 2 ]

1 голос
/ 18 февраля 2010

Это реализация в 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;
    }
1 голос
/ 17 февраля 2010

Вы, кажется, описываете правильный алгоритм; другой указатель на выравнивание гистограммы смотрите здесь:

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

Я подозреваю, что ошибка не в алгоритме, а в вашей реализации. Вы проверили, чтобы увидеть, что гистограмма выглядит разумно? Код достаточно короткий, чтобы вы могли опубликовать его?

...