2013-11-08 4 views
0

Я пытаюсь выравнивать гистограмму изображения HSV с помощью openCV и C++. Я знаю, что есть библиотеки с openCV, которые сделают это для меня, но я хочу попробовать его вручную, чтобы понять метод.Уравнивать гистограмму для изображения HSV

Я предполагаю, что выравнивание будет выполнено на V-канале изображения HSV? я нашел способ градаций серого выравнивания гистограммы, которая включает в себя

  • Count Количество пикселей каждого значения
  • Найти вероятность каждого пиксела в изображении
  • Вычислить интегральную функцию распределения
  • Вычислить CDF * Максимальное значение в изображении.
  • Вокруг этого числа, чтобы получить значение пикселя

Я пробовал этот метод на бумаге с помощью простого 5x5 сетки значений и, казалось, дают эффект выравнивания значений.

Я попытался реализовать это в C++, но я не получаю ожидаемые значения.

int rows = channel.rows; 
int cols = channel.cols; 
int hist[256]; 
int total = rows*cols; 
for(int i = 0; i<rows; i++) 
{ 
    for(int k = 0; k<cols; k++) 
    { 
     int value = channel.at<cv::Vec3b>(i,k)[0]; 
     hist[value] = hist[value] + 1; 
    } 
} 

double prob[255]; 
int newValues[255]; 
double cuml = 0; 
for(int j = 0; j< 255; j++) 
{ 
    prob[j] = hist[j]/total; // Probability of each value in image 
    cuml = cuml + prob[j]; // Cumulative probability of current and all previous values 
    double cdfmax = cuml * 255; // Cumulative probability * max value 
    newValues[j] = (int) round(cdfmax); 
    cout << hist[j] << endl; 
    cout << prob[j] << endl; 
} 

Канал представляет собой изображение мата, представляющее значения V моего изображения HSV. Я уверен, что проблема заключается в первом цикле для того, чтобы суммировать все вхождения этого значения в изображении. Я довольно новичок в C++, поэтому могут быть и другие ошибки. Любая помощь приветствуется.

ответ

3

Вы забываете инициализировать hist массив нулями, например, как это:

int hist[256] = {0}; 

Update:

prob[j] = hist[j]/total; всегда будет приводить к 0, так как вы делаете целочисленное деление (оба термина int - с). Чтобы избежать этого, сделайте prob[j] = hist[j]/(double)total;.

Вторая часть кода использует только 255 значений вашей гистограммы (однако она имеет 256 ящиков). Поэтому обновите его до 256, например:

double prob[256]; 
int newValues[256]; 
double cuml = 0; 
for(int j = 0; j< 256; j++) 
... 
+0

Спасибо, что дало мне более реалистичные значения. Теперь проблема состоит в том, что все вероятности выходят на 0. Общее количество пикселей, вычисленных по строкам * cols = 234164. И вычисляю вероятность как: Число каждого значения пикселя/всего. Я также инициализировал другие массивы до 0. –

+0

Я обновил свой ответ. – Sigroad

+0

Отлично! Завершенная таблица поиска и результат выглядят так же, как и метод библиотеки OpenCV, поэтому я предполагаю, что это означает, что это правильно. Спасибо. –

Смежные вопросы