Я пытаюсь выровнять гистограмму изображения HSV, используя openCV и C ++.
Я знаю, что есть библиотеки с openCV, которые сделают это для меня, но я хочу попробовать это вручную, чтобы понять метод.
Я предполагаю, что выравнивание будет сделано на канале V изображения HSV?
Я нашел метод выравнивания гистограммы в оттенках серого, который включает
Я попробовал этот метод на бумаге с простой сеткой значений 5×5, и это, казалось, дало эффект выравнивания значений.
Я пытался реализовать это в 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;
}
Канал — это изображение Mat, представляющее значения V моего изображения HSV. Я почти уверен, что проблема заключается в первом цикле for, который суммирует все вхождения этого значения в изображении. Я довольно новичок в C ++, поэтому вполне могут быть и другие ошибки.
Любая помощь приветствуется.
Вы забыли инициализировать свой hist
массив к нулям, например, так:
int hist[256] = {0};
Обновить:
prob[j] = hist[j]/total;
всегда будет 0, так как вы делаете целочисленное деление (оба условия int
-s). Чтобы этого избежать 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++)
...
Других решений пока нет …