Re: sample for Histogram Equalization
От: Lafkadio Россия  
Дата: 28.04.05 10:38
Оценка: 18 (3)
Здравствуйте, Denis, Вы писали:

D>есть совсем глупый вопрос, подскажите сампл простой который иллюстрирует subj.

Я пользуюсь следующей функцией:
Функция выравнивает гистограмму заданной прямоугольной области изображения. По рассчитанной гистограмме вычисляется дискретная функция распределения, в табличном представлении. Данная функция преобразует яркость изображения таким образом, чтобы гистограмма преобразованного поля была максимально приближена к равномерной. Далее для каждого пикселя изображения, его значение считается индексом в массиве табличного представления функции преобразования, и заменяется на выбранное в ней значение. Алгоритм функции взят из В. Яншин, Г. Калинин "Обработка изображений на языке Си для IBM PC. Алгоритмы и программы", Мир, 1994г. с 88-89.
 // Для простоты считаем что работаем с 8-битным изображением
 // m_ChannelSize- размер изображения
 // m_pActiveChannel - массив пикселей изобржения
 long pHist[256];//Гистограмма исходного изображения

 //очищаем гистограмму
 for (int i=0; i< 255; i++) 
    pHist[i] = 0;

 // Вычисляем гистограмму
 for (i=0; i< m_ChannelSize; i++)
    pHist[m_pActiveChannel[i]]++;

 int  ;
 long pHistNew[256];
 int Derr;
 DWORD Vg, SumDes, SumFct=0;
 BYTE Fns[256];// функция табличного преобразования

 Vg=0;
 for(i=255; i>=0; i--) 
 {
    Vg += pHist[i];
        pHistNew[i]=0;
 }

 //Вычисляем функцию распределения вероятности, апроксимруя ее
 //выражением P(x)=sum H(i),i=0..x где H- массив гистограммы
 for(i=255; i>=0; i--) 
    Vg -= (pHistNew[i] = Vg/(i+1));

 SumDes = pHistNew[0];
 // Вычисляем функцию табличного преобразования
 for (i=0, j=0; j<=255; )
 {
    Derr=SumDes-SumFct;
    if (pHist[j]<= 2*Derr)
    {
        SumFct += pHist[j];
        Fns[j++]=i;
    }
    else
    {
        Fns[j]=i++;
        if (i <= 255) 
                        SumDes += pHistNew[i];
    }
 }

 // Вычисляем границы гистограммы исходного изображения
 for (j=255; pHist[j]==0; j--);
 for (i=0; pHist[i]==0; i++);
 if (j-i > 255)
 {
    Fns[0]=0;
    Fns[r]=255;
 }

 // Вычисляем новое значение каждого пикселя по табличной функции
 for (i=0; i< m_ChannelSize; i++)
    m_pActiveChannel[i]=Fns[m_pActiveChannel[i]];


В книге Crane R., Simplified approach to image processing in C (PH, 1997)(ISBN 0132264161), p.49 приведен другой алгоритм:

/***************************************************************************
 * Func: histogram_equalize                                                *
 *                                                                         *
 * Desc: histogram equalize an input image and write it out                *
 *                                                                         *
 * Params: buffer - pointer to image in memory                             *
 *         number_of_pixels - total number of pixels in image              *
 ***************************************************************************/

void histogram_equalize(image_ptr buffer, unsigned long number_of_pixels)
    {
    unsigned long histogram[256]; /* image histogram */
    unsigned long sum_hist[256];  /* sum of histogram elements */
    float scale_factor;           /* normalized scale factor */
    unsigned long i;              /* index variable */
    unsigned long sum;            /* variable used to increment sum of hist */

    /* clear histogram to 0 */
    for(i=0; i<256; i++)
    histogram[i]=0;

    /* calculate histogram */
    for(i=0; i<number_of_pixels; i++)
    histogram[buffer[i]]++;

    /* calculate normalized sum of hist */
    sum = 0;
    scale_factor = 255.0 / number_of_pixels;
    for(i=0; i<256; i++)
    {
    sum += histogram[i];
    sum_hist[i] = (sum * scale_factor) + 0.5;
    }

    /* transform image using new sum_hist as a LUT */
    for(i=0; i<number_of_pixels; i++)
    buffer[i] = sum_hist[buffer[i]];
    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.