Re[4]: sample for Histogram Equalization
От: Reunion  
Дата: 12.07.05 03:54
Оценка:
Здравствуйте, Lafkadio, Вы писали:

[skiped]

Я тут поколдовал над исходником и вот, что получилось:

void CHistogramDlg::Equilize2(CImage *pSrcImg, CImage *pDstImg)
{
    long histogram[256];                // Histogram of the source image

    /**long new_histogram[256];**/        // Desired histogram
    long uniform_level;                    // In here the desired histogram is
                                        // replaced with one uniform level

    byte LUT[256];                        // Table transform function - LUT
    int error;
    unsigned long total, sum_des, sum_fct;

    int w = pSrcImg->GetWidth();        // With od the images
    int h = pSrcImg->GetHeight();        // Height of the images
    // Other variables
    int x, y, c, i, j;
    BYTE *pPix1 = NULL, *pPix2 = NULL;

    // Zero the histogram
    for(c = 0; c < 256; c ++)
        histogram[c] = 0;

    // Calculate the source image histogram
    for(y = 0; y < h; y ++)
        for(x = 0; x < w; x ++){
            pPix1 = pSrcImg->GetPixel(x, y);
            // Calculate intensity
            c = (int)floor(0.299 * (*(pPix1 + 2)) + 0.587 * (*(pPix1 + 1)) + 0.114 * (*pPix1));
            histogram[c] ++;
        }

    total = w * h;
    uniform_level = total / 256;
    /** // Calculate the desired (flat) histogram
    for(i = 0; i < 256; i ++)
        new_histogram[i] = total / 256;**/

    // Calculate table transform function
    sum_des = uniform_level/**new_histogram[0]**/;
    sum_fct = 0;
    for(i = 0, j = 0; j <= 255; ){
        error = sum_des - sum_fct;
        LUT[j] = i;
        if(histogram[j] <= 2 * error){
            sum_fct += histogram[j];
            j ++;
        }
        else{
            i ++;
            if(i <= 255)
                sum_des += uniform_level/**new_histogram[i]**/;
        }
    }

    // Apply
    for(y = 0; y < h; y ++)
        for(x = 0; x < w; x ++){
            pPix1 = pSrcImg->GetPixel(x, y);
            pPix2 = pDstImg->GetPixel(x, y);

            *(pPix2 + 2) = LUT[*(pPix1 + 2)];
            *(pPix2 + 1) = LUT[*(pPix1 + 1)];
            *pPix2 = LUT[*pPix1];
        }
}


Теперь пояснения.
Вот это кусок кода...
Vg=0;
for(i=255; i>=0; i--) 
{
    Vg += pHist[i];
    pHistNew[i]=0;
}

... делает ни что иное, как подсчет количества пикселей и обнуление желаемой гистограммы.

Это...
for(i=255; i>=0; i--) 
    Vg -= (pHistNew[i] = Vg/(i+1));

... равносильно...
for(i=0; i<256; i++) 
    pHistNew[i] = total / 256;

... где total — число пикселей в изображении.
Тогда возникает вопрос, зачем заводить целый массив если все его элементы одинаковы и в дальнейшем не изменяются. Поэтому я заменил его одной переменной.
Код работы с массивом оставил на случай, если придет в голову как можно задать другую (например "более подходящую") гистограмму. Но пока таких мыслей нет...

PS. Кстати, а у тебя есть книга Яншина в электронном виде?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.