49 #include <visp3/core/vpDisplay.h> 50 #include <visp3/core/vpHistogram.h> 51 #include <visp3/core/vpImageConvert.h> 53 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0)) 54 #include <visp3/core/vpThread.h> 58 struct Histogram_Param_t {
59 unsigned int m_start_index;
60 unsigned int m_end_index;
62 unsigned int m_lut[256];
63 unsigned int *m_histogram;
66 Histogram_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_histogram(NULL), m_I(NULL) {}
68 Histogram_Param_t(
const unsigned int start_index,
const unsigned int end_index,
const vpImage<unsigned char> *
const I)
69 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_histogram(NULL), m_I(I)
75 if (m_histogram != NULL) {
83 Histogram_Param_t *histogram_param =
static_cast<Histogram_Param_t *
>(args);
84 unsigned int start_index = histogram_param->m_start_index;
85 unsigned int end_index = histogram_param->m_end_index;
89 unsigned char *ptrStart = (
unsigned char *)(I->
bitmap) + start_index;
90 unsigned char *ptrEnd = (
unsigned char *)(I->
bitmap) + end_index;
91 unsigned char *ptrCurrent = ptrStart;
99 if (end_index - start_index >= 8) {
101 for (; ptrCurrent <= ptrEnd - 8;) {
102 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
105 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
108 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
111 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
114 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
117 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
120 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
123 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
128 for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
129 histogram_param->m_histogram[histogram_param->m_lut[*ptrCurrent]]++;
159 memcpy(histogram, h.histogram, size *
sizeof(
unsigned));
181 if (histogram != NULL) {
205 memcpy(histogram, h.histogram, size *
sizeof(
unsigned));
215 void vpHistogram::init(
unsigned size_)
217 if (histogram != NULL) {
223 histogram =
new unsigned[size];
225 memset(histogram, 0, size *
sizeof(
unsigned));
241 if (histogram != NULL) {
246 size = nbins > 256 ? 256 : (nbins > 0 ? nbins : 256);
247 if (nbins > 256 || nbins == 0) {
248 std::cerr <<
"nbins=" << nbins <<
" , nbins should be between ]0 ; 256] ; use by default nbins=256" << std::endl;
250 histogram =
new unsigned int[size];
253 memset(histogram, 0, size *
sizeof(
unsigned int));
255 bool use_single_thread;
256 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32) 257 use_single_thread =
true;
259 use_single_thread = (nbThreads == 0 || nbThreads == 1);
262 if (!use_single_thread && I.
getSize() <= nbThreads) {
263 use_single_thread =
true;
266 unsigned int lut[256];
267 for (
unsigned int i = 0; i < 256; i++) {
268 lut[i] = (
unsigned int)(i * size / 256.0);
271 if (use_single_thread) {
275 unsigned char *ptrStart = (
unsigned char *)I.
bitmap;
276 unsigned char *ptrEnd = ptrStart + size_;
277 unsigned char *ptrCurrent = ptrStart;
279 while (ptrCurrent != ptrEnd) {
280 histogram[lut[*ptrCurrent]]++;
284 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0)) 287 std::vector<vpThread *> threadpool;
288 std::vector<Histogram_Param_t *> histogramParams;
290 unsigned int image_size = I.
getSize();
291 unsigned int step = image_size / nbThreads;
292 unsigned int last_step = image_size - step * (nbThreads - 1);
294 for (
unsigned int index = 0; index < nbThreads; index++) {
295 unsigned int start_index = index * step;
296 unsigned int end_index = (index + 1) * step;
298 if (index == nbThreads - 1) {
299 end_index = start_index + last_step;
302 Histogram_Param_t *histogram_param =
new Histogram_Param_t(start_index, end_index, &I);
303 histogram_param->m_histogram =
new unsigned int[size];
304 memset(histogram_param->m_histogram, 0, size *
sizeof(
unsigned int));
305 memcpy(histogram_param->m_lut, lut, 256 *
sizeof(
unsigned int));
307 histogramParams.push_back(histogram_param);
311 threadpool.push_back(histogram_thread);
314 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
316 threadpool[cpt]->join();
319 for (
unsigned int cpt1 = 0; cpt1 < size; cpt1++) {
320 unsigned int sum = 0;
322 for (
size_t cpt2 = 0; cpt2 < histogramParams.size(); cpt2++) {
323 sum += histogramParams[cpt2]->m_histogram[cpt1];
326 histogram[cpt1] = sum;
330 for (
size_t cpt = 0; cpt < threadpool.size(); cpt++) {
331 delete threadpool[cpt];
334 for (
size_t cpt = 0; cpt < histogramParams.size(); cpt++) {
335 delete histogramParams[cpt];
353 const unsigned int maxValue_)
357 if (width < 36 || height < 36) {
358 std::cerr <<
"Image I must have at least width >= 36 && height >= 36 !" << std::endl;
362 unsigned int maxValue = maxValue_;
364 for (
unsigned int i = 0; i < size; i++) {
365 if (histogram[i] > maxValue) {
366 maxValue = histogram[i];
375 unsigned int max_height = height - 12;
376 double ratio_height = max_height / (double)maxValue;
377 double ratio_width = (width - 1) / (
double)(size - 1.0);
379 for (
unsigned int i = 1; i < size; i++) {
380 unsigned int value1 = histogram[i - 1];
381 unsigned int value2 = histogram[i];
383 vpImagePoint startPt((height - 1) - (value1 * ratio_height), (i - 1) * ratio_width);
384 vpImagePoint endPt((height - 1) - (value2 * ratio_height), (i * ratio_width));
411 if (histogram == NULL) {
419 int hsize = (int)fsize / 2;
421 for (
unsigned i = 0; i < size; i++) {
422 unsigned int sum = 0;
424 for (
int j = -hsize; j <= hsize; j++) {
426 if ( (i + (
unsigned int)j) < size) {
427 sum += h.histogram[i + (
unsigned int)j];
431 histogram[i] = sum / nb;
451 if (histogram == NULL) {
464 unsigned sum_level = 0;
468 for (
unsigned i = 0; i < size - 1; i++) {
469 int next_slope = (int)histogram[i + 1] - (
int)histogram[i];
477 if ((prev_slope > 0) && (next_slope == 0)) {
484 if ((prev_slope > 0) && (next_slope < 0)) {
488 unsigned int level = sum_level / cpt;
489 p.
set((
unsigned char)level, histogram[level]);
496 prev_slope = next_slope;
500 if (prev_slope > 0) {
501 p.
set((
unsigned char)size - 1u, histogram[size - 1]);
529 std::list<vpHistogramPeak> peaks;
542 peak1 = peaks.front();
549 peak1 = peaks.front();
550 for (std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++it) {
583 unsigned index_highest_peak;
584 unsigned index_second_peak;
587 unsigned int maxprof;
589 unsigned int sumindmini;
591 unsigned int nbpeaks;
597 peak =
new unsigned char[size];
602 for (
unsigned i = 0; i < size - 1; i++) {
603 int next_slope = (int)histogram[i + 1] - (
int)histogram[i];
607 if ((prev_slope > 0) && (next_slope < 0))
608 peak[nbpeaks++] = (
unsigned char)i;
610 prev_slope = next_slope;
613 peak[nbpeaks++] = (
unsigned char)(size - 1);
621 index_highest_peak = 0;
622 for (
unsigned int i = 0; i < nbpeaks; i++) {
623 if (histogram[peak[i]] > histogram[peak[index_highest_peak]]) {
624 index_highest_peak = i;
633 index_second_peak = index_highest_peak;
636 for (
unsigned i = 0; i < index_highest_peak; i++) {
637 if (peak[index_highest_peak] - peak[i] > dist) {
639 for (
int j = peak[i]; j <= peak[index_highest_peak] - dist; j++)
640 if ((histogram[peak[i]] - histogram[j]) > prof)
641 prof = histogram[peak[i]] - histogram[j];
643 if (prof > maxprof) {
645 index_second_peak = i;
651 for (
unsigned i = index_highest_peak + 1; i < nbpeaks; i++) {
652 if (peak[i] - peak[index_highest_peak] > dist) {
654 for (
int j = peak[index_highest_peak] + dist; j <= peak[i]; j++)
655 if ((histogram[peak[i]] - histogram[j]) > prof)
656 prof = histogram[peak[i]] - histogram[j];
658 if (prof > maxprof) {
660 index_second_peak = i;
669 if (peak[index_highest_peak] < peak[index_second_peak]) {
670 peakr.
set(peak[index_second_peak], histogram[peak[index_second_peak]]);
671 peakl.
set(peak[index_highest_peak], histogram[peak[index_highest_peak]]);
673 peakl.
set(peak[index_second_peak], histogram[peak[index_second_peak]]);
674 peakr.
set(peak[index_highest_peak], histogram[peak[index_highest_peak]]);
677 if (peakl == peakr) {
689 if (histogram[i] < mini) {
695 if (histogram[i] == mini) {
712 mini = sumindmini / nbmini;
713 valey.
set((
unsigned char)mini, histogram[mini]);
734 if (histogram == NULL) {
747 unsigned sum_level = 0;
751 for (
unsigned i = 0; i < size - 1; i++) {
752 int next_slope = (int)histogram[i + 1] - (
int)histogram[i];
754 if ((prev_slope < 0) && (next_slope == 0)) {
761 if ((prev_slope < 0) && (next_slope > 0)) {
765 unsigned int level = sum_level / cpt;
766 p.
set((
unsigned char)level, histogram[level]);
773 prev_slope = next_slope;
777 if (prev_slope < 0) {
778 p.
set((
unsigned char)size - 1u, histogram[size - 1]);
816 unsigned int sumindmini;
823 if (histogram[i] < mini) {
829 if (histogram[i] == mini) {
841 unsigned int minipos = sumindmini / nbmini;
843 valey.
set((
unsigned char)minipos, histogram[minipos]);
868 unsigned int ret = 0x11;
870 unsigned int sumindmini;
873 std::list<vpHistogramPeak> peaks;
882 valeyr.
set((
unsigned char)(size - 1), 0);
904 std::list<vpHistogramPeak>::const_iterator it;
906 for (it = peaks.begin(); it != peaks.end(); ++it) {
921 std::list<vpHistogramPeak>::const_iterator lit;
922 for (lit = peaks.begin(); lit != it; ++lit) {
923 if (abs((*lit).getLevel() - peak.
getLevel()) > dist) {
939 if (histogram[i] < mini) {
945 if (histogram[i] == mini) {
954 unsigned int minipos = sumindmini / nbmini;
955 valeyl.
set((
unsigned char)minipos, histogram[minipos]);
966 std::list<vpHistogramPeak>::const_iterator it;
968 for (it = peaks.begin(); it != peaks.end(); ++it) {
978 std::list<vpHistogramPeak>::const_iterator rit;
979 for (rit = it; rit != peaks.end(); ++rit)
981 if (abs((*rit).getLevel() - peak.
getLevel()) > dist) {
989 peakr.
set((
unsigned char)(size - 1), 0);
995 for (
unsigned i = (
unsigned int)peak.
getLevel() + 1; i <= (
unsigned int)peakr.
getLevel(); i++) {
996 if (histogram[i] < mini) {
1002 if (histogram[i] == mini) {
1008 valeyr.
set((
unsigned char)(size - 1), 0);
1011 unsigned int minipos = sumindmini / nbmini;
1012 valeyr.
set((
unsigned char)minipos, histogram[minipos]);
1031 if (peaks.empty()) {
1035 peaks.sort(compare_vpHistogramPeak);
1037 return (
unsigned int)peaks.size();
1068 FILE *fd = fopen(filename,
"w");
1071 for (
unsigned i = 0; i < size; i++)
1072 fprintf(fd,
"%u %u\n", i, histogram[i]);
unsigned getPeaks(std::list< vpHistogramPeak > &peaks)
void display(const vpImage< unsigned char > &I, const vpColor &color=vpColor::white, const unsigned int thickness=2, const unsigned int maxValue_=0)
unsigned int getWidth() const
unsigned getValue() const
Type * bitmap
points toward the bitmap
vpHistogram & operator=(const vpHistogram &h)
Class to define colors available for display functionnalities.
error that can be emited by ViSP classes.
Class to compute a gray level image histogram.
Error that can be emited by the vpImage class and its derivates.
Declaration of the peak (maximum value) in a gray level image histogram.
void smooth(const unsigned int fsize=3)
void set(unsigned char lvl, unsigned val)
unsigned int getSize() const
void calculate(const vpImage< unsigned char > &I, const unsigned int nbins=256, const unsigned int nbThreads=1)
void set(unsigned char lvl, unsigned val)
unsigned sort(std::list< vpHistogramPeak > &peaks)
unsigned char getLevel() const
bool write(const std::string &filename)
unsigned int getHeight() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
Declaration of the valey (minimum value) in a gray level image histogram.
unsigned getValey(std::list< vpHistogramValey > &valey)