141 if (level < m_size) {
142 return m_histogram[level];
145 std::stringstream ss;
146 ss <<
"Level is > to size (" << m_size <<
") !";
171 if (level < m_size) {
172 return m_histogram[level];
175 std::stringstream ss;
176 ss <<
"Level is > to size (" << m_size <<
") !";
199 inline unsigned get(
const unsigned char level)
const
201 if (level < m_size) {
202 return m_histogram[level];
205 std::stringstream ss;
206 ss <<
"Level is > to size (" << m_size <<
") !";
227 inline void set(
const unsigned char level,
unsigned int value)
229 if (level < m_size) {
230 m_histogram[level] = value;
233 std::stringstream ss;
234 ss <<
"Level is > to size (" << m_size <<
") !";
256#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
257 template <
typename ArithmeticType>
258 typename std::enable_if<std::is_floating_point<ArithmeticType>::value,
void>::type
calculate(
const vpImage<ArithmeticType> &I,
const ArithmeticType &minVal,
const ArithmeticType &maxVal, ArithmeticType &widthBin,
unsigned int nbins = 256,
unsigned int nbThreads = 1)
260 widthBin = (maxVal - minVal)/
static_cast<ArithmeticType
>(nbins);
261 if (m_size < nbins) {
265 memset(m_histogram, 0, m_size *
sizeof(
unsigned int));
267 bool use_single_thread;
268#if !defined(VISP_HAVE_THREADS)
269 use_single_thread =
true;
271 use_single_thread = (nbThreads == 0 || nbThreads == 1);
274 if ((!use_single_thread) && (I.getSize() <= nbThreads)) {
275 use_single_thread =
true;
278 if (use_single_thread) {
280 const bool alwaysTrue =
true;
281 const bool *ptrMaskCurrent = &alwaysTrue;
283 ptrMaskCurrent =
static_cast<const bool *
>(mp_mask->bitmap);
286 unsigned int size_ = I.getWidth() * I.getHeight();
287 unsigned int idCurrent = 0;
290 while (idCurrent < size_) {
291 if (*ptrMaskCurrent) {
292 unsigned int id =
static_cast<unsigned int>(std::floor((I.bitmap[idCurrent] - minVal)/widthBin));
303#if defined(VISP_HAVE_THREADS)
305 std::vector<std::thread *> threadpool;
306 std::vector<vpHistogramFloatingPoints_Param_t<ArithmeticType> *> histogramParams;
308 unsigned int image_size = I.getSize();
309 unsigned int step = image_size / nbThreads;
310 unsigned int last_step = image_size - step * (nbThreads - 1);
312 for (
unsigned int index = 0; index < nbThreads; ++index) {
313 unsigned int start_index = index * step;
314 unsigned int end_index = (index + 1) * step;
316 if (index == nbThreads - 1) {
317 end_index = start_index + last_step;
320 vpHistogramFloatingPoints_Param_t<ArithmeticType> *histogram_param =
new vpHistogramFloatingPoints_Param_t<ArithmeticType>(start_index, end_index, minVal, widthBin, &I, mp_mask);
321 histogram_param->m_histogram =
new unsigned int[m_size];
322 histogram_param->m_mask = mp_mask;
323 memset(histogram_param->m_histogram, 0, m_size *
sizeof(
unsigned int));
325 histogramParams.push_back(histogram_param);
328 std::thread *histogram_thread =
new std::thread(&computeHistogramFloatingPointThread<ArithmeticType>, histogram_param);
329 threadpool.push_back(histogram_thread);
332 for (
size_t cpt = 0; cpt < threadpool.size(); ++cpt) {
334 threadpool[cpt]->join();
338 for (
unsigned int cpt1 = 0; cpt1 < m_size; ++cpt1) {
339 unsigned int sum = 0;
341 for (
size_t cpt2 = 0; cpt2 < histogramParams.size(); ++cpt2) {
342 sum += histogramParams[cpt2]->m_histogram[cpt1];
345 m_histogram[cpt1] = sum;
350 for (
size_t cpt = 0; cpt < threadpool.size(); ++cpt) {
351 delete threadpool[cpt];
354 for (
size_t cpt = 0; cpt < histogramParams.size(); ++cpt) {
355 delete histogramParams[cpt];
365 unsigned int maxValue_ = 0);
367 void smooth(
unsigned int fsize = 3);
368 unsigned getPeaks(std::list<vpHistogramPeak> &peaks);
371 unsigned getValey(std::list<vpHistogramValey> &valey);
375 unsigned sort(std::list<vpHistogramPeak> &peaks);
377 bool write(
const std::string &filename);
378 bool write(
const char *filename);
388 inline unsigned getSize()
const {
return m_size; }
421#if defined(VISP_HAVE_THREADS) && (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
423#ifndef DOXYGEN_SHOULD_SKIP_THIS
424 template <
typename ArithmeticType>
425 struct vpHistogramFloatingPoints_Param_t
427 unsigned int m_start_index;
428 unsigned int m_end_index;
430 unsigned int *m_histogram;
431 const ArithmeticType m_minVal;
432 const ArithmeticType m_step;
436 vpHistogramFloatingPoints_Param_t() : m_start_index(0), m_end_index(0), m_histogram(nullptr), m_minVal(0.), m_step(1.), m_I(nullptr), m_mask(nullptr) { }
438 vpHistogramFloatingPoints_Param_t(
unsigned int start_index,
unsigned int end_index,
const ArithmeticType &minVal,
const ArithmeticType &step,
const vpImage<ArithmeticType> *
const I,
const vpImage<bool> *
const mask)
439 : m_start_index(start_index), m_end_index(end_index), m_histogram(nullptr), m_minVal(minVal), m_step(
step), m_I(I), m_mask(mask)
442 ~vpHistogramFloatingPoints_Param_t()
444 if (m_histogram !=
nullptr) {
445 delete[] m_histogram;
450 template <
typename ArithmeticType>
451 static typename std::enable_if<std::is_floating_point<ArithmeticType>::value,
void>::type computeHistogramFloatingPointThread(vpHistogramFloatingPoints_Param_t<ArithmeticType> *histogram_param)
453 unsigned int start_index = histogram_param->m_start_index;
454 unsigned int end_index = histogram_param->m_end_index;
455 unsigned int stopUnroll = end_index - 8;
456 unsigned int current_index = start_index;
458 const vpImage<ArithmeticType> *I = histogram_param->m_I;
461 const ArithmeticType &minVal = histogram_param->m_minVal;
462 const ArithmeticType &
step = histogram_param->m_step;
464 auto computeIndex = [&minVal, &
step](
const ArithmeticType &val) {
465 return static_cast<unsigned int> (std::floor((val - minVal)/step));
468 const bool alwaysTrue =
true;
469 const bool *ptrMaskCurrent = &alwaysTrue;
470 if (histogram_param->m_mask) {
471 ptrMaskCurrent = (
const bool *)histogram_param->m_mask->bitmap + start_index;
474 if (end_index >= 8 + start_index) {
476 while (current_index <= stopUnroll) {
477 if (*ptrMaskCurrent) {
478 unsigned int id = computeIndex(I->
bitmap[current_index]);
479 histogram_param->m_histogram[id]++;
482 if (histogram_param->m_mask !=
nullptr) {
486 if (*ptrMaskCurrent) {
487 unsigned int id = computeIndex(I->
bitmap[current_index]);
488 histogram_param->m_histogram[id]++;
491 if (histogram_param->m_mask !=
nullptr) {
495 if (*ptrMaskCurrent) {
496 unsigned int id = computeIndex(I->
bitmap[current_index]);
497 histogram_param->m_histogram[id]++;
500 if (histogram_param->m_mask !=
nullptr) {
504 if (*ptrMaskCurrent) {
505 unsigned int id = computeIndex(I->
bitmap[current_index]);
506 histogram_param->m_histogram[id]++;
509 if (histogram_param->m_mask !=
nullptr) {
513 if (*ptrMaskCurrent) {
514 unsigned int id = computeIndex(I->
bitmap[current_index]);
515 histogram_param->m_histogram[id]++;
518 if (histogram_param->m_mask !=
nullptr) {
522 if (*ptrMaskCurrent) {
523 unsigned int id = computeIndex(I->
bitmap[current_index]);
524 histogram_param->m_histogram[id]++;
527 if (histogram_param->m_mask !=
nullptr) {
531 if (*ptrMaskCurrent) {
532 unsigned int id = computeIndex(I->
bitmap[current_index]);
533 histogram_param->m_histogram[id]++;
536 if (histogram_param->m_mask !=
nullptr) {
540 if (*ptrMaskCurrent) {
541 unsigned int id = computeIndex(I->
bitmap[current_index]);
542 histogram_param->m_histogram[id]++;
545 if (histogram_param->m_mask !=
nullptr) {
551 while (current_index < end_index) {
552 if (*ptrMaskCurrent) {
553 unsigned int id = computeIndex(I->
bitmap[current_index]);
554 histogram_param->m_histogram[id]++;
556 if (histogram_param->m_mask !=
nullptr) {
565 void init(
unsigned size = 256);
567 unsigned int *m_histogram;
569 const vpImage<bool> *mp_mask;
570 unsigned int m_total;
571 static const unsigned int constr_val_256;
std::enable_if< std::is_floating_point< ArithmeticType >::value, void >::type calculate(const vpImage< ArithmeticType > &I, const ArithmeticType &minVal, const ArithmeticType &maxVal, ArithmeticType &widthBin, unsigned int nbins=256, unsigned int nbThreads=1)