ViSP  2.9.0
vpHistogram.cpp
1 /****************************************************************************
2  *
3  * $Id: vpHistogram.cpp 4649 2014-02-07 14:57:11Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Gray level histogram manipulation.
36  *
37  * Author:
38  * Fabien Spindler
39  *
40  *****************************************************************************/
41 
51 #include <visp/vpHistogram.h>
52 #include <stdlib.h>
53 
54 bool compare_vpHistogramPeak (vpHistogramPeak first, vpHistogramPeak second);
55 
56 // comparison,
57 bool compare_vpHistogramPeak (vpHistogramPeak first, vpHistogramPeak second)
58 {
59  if (first.getValue() > second.getValue()) return true;
60  else return false;
61 }
62 
63 
64 
68 vpHistogram::vpHistogram() : histogram(NULL), size(256)
69 {
70  init();
71 }
72 
76 vpHistogram::vpHistogram(const vpHistogram &h) : histogram(NULL), size(256)
77 {
78  init(h.size);
79  memcpy(histogram, h.histogram, size * sizeof(unsigned));
80 }
81 
90  : histogram(NULL), size(256)
91 {
92  init();
93 
94  calculate(I);
95 }
96 
101 {
102  if (histogram != NULL) {
103  // vpTRACE("free: %p", &histogram);
104  delete [] histogram;
105  histogram = NULL;
106  size = 0;
107  }
108 }
109 
123 vpHistogram &
125 {
126  init(h.size);
127  memcpy(histogram, h.histogram, size * sizeof(unsigned));
128 
129  return *this;
130 }
131 
137 void
138 vpHistogram::init(unsigned size_)
139 {
140  if (histogram != NULL) {
141  delete [] histogram;
142  histogram = NULL;
143  }
144 
145  this->size = size_;
146  histogram = new unsigned [size];
147 
148  memset(histogram, 0, size * sizeof(unsigned));
149 
150  // vpTRACE("alloc: %p", &histogram);
151 }
152 
153 
162 {
163  memset(histogram, 0, size * sizeof(unsigned));
164 
165  for (unsigned i=0; i < I.getHeight(); i ++) {
166  for (unsigned j=0; j < I.getWidth(); j ++) {
167  histogram[ I[i][j] ] ++;
168  }
169  }
170 }
171 
192 void
193 vpHistogram::smooth(const unsigned int fsize)
194 {
195  if (histogram == NULL) {
196  vpERROR_TRACE("Histogram array not initialised\n");
198  "Histogram array not initialised")) ;
199  }
200 
201  vpHistogram h;
202  h = *this;
203 
204  int hsize = (int)fsize / 2; // half filter size
205  unsigned int sum;
206  unsigned int nb;
207 
208  for (unsigned i=0; i < size; i ++) {
209  sum = 0;
210  nb = 0;
211  for (int j=-hsize; j <= hsize; j ++) {
212  // exploitation of the overflow to detect negative value...
213  if ( /*(i + j) >= 0 &&*/ (i + (unsigned int)j) < size ) {
214  sum += h.histogram[i + (unsigned int)j];
215  nb ++;
216  }
217  }
218  histogram[i] = sum / nb;
219  }
220 
221 }
222 
237 unsigned vpHistogram::getPeaks(std::list<vpHistogramPeak> & peaks)
238 {
239  if (histogram == NULL) {
240  vpERROR_TRACE("Histogram array not initialised\n");
242  "Histogram array not initialised")) ;
243  }
244 
245  int prev_slope; // Previous histogram inclination
246  int next_slope; // Next histogram inclination
247  vpHistogramPeak p; // An histogram peak
248  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
249 
250  peaks.clear();
251 
252  // Parse the histogram to get the local maxima
253  unsigned cpt = 0;
254  unsigned sum_level = 0;
255  nbpeaks = 0;
256  prev_slope = 1;
257 
258  for (unsigned i = 0; i < size-1; i++) {
259  next_slope = (int)histogram[i+1] - (int)histogram[i];
260 
261 // if ((prev_slope < 0) && (next_slope > 0) ) {
262 // sum_level += i;
263 // cpt ++;
264 // continue;
265 // }
266 
267  if ((prev_slope > 0) && (next_slope == 0) ) {
268  sum_level += i + 1;
269  cpt ++;
270  continue;
271  }
272 
273 
274  // Peak detection
275  if ( (prev_slope > 0) && (next_slope < 0) ) {
276  sum_level += i;
277  cpt ++;
278 
279  unsigned int level = sum_level / cpt;
280  p.set((unsigned char)level, histogram[level]);
281  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
282  peaks.push_back(p);
283 
284  nbpeaks ++;
285 
286  }
287 
288  prev_slope = next_slope;
289  sum_level = 0;
290  cpt = 0;
291  }
292  if (prev_slope > 0) {
293  p.set((unsigned char)size-1u, histogram[size-1]);
294  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
295  peaks.push_back(p);
296  nbpeaks ++;
297  }
298 
299  return nbpeaks;
300 }
301 
319 unsigned vpHistogram::getPeaks(unsigned char dist,
320  vpHistogramPeak & peak1,
321  vpHistogramPeak & peak2)
322 {
323  std::list<vpHistogramPeak> peaks;
324  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
325 
326  nbpeaks = getPeaks(peaks);
327  sort(peaks);
328 
329  if (nbpeaks == 0) {
330  peak1.set(0, 0);
331  peak2.set(0, 0);
332  return 0;
333  }
334 
335  if (nbpeaks == 1) {
336  peak1 = peaks.front();
337  peak2.set(0, 0);
338  return 1;
339  }
340 
341  // Parse the peaks list to get the peak with a distance greater
342  // than dist to the highest
343  peak1 = peaks.front();
344  for(std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++ it)
345  {
346  vpHistogramPeak p = *it;
347  if (abs(p.getLevel() - peak1.getLevel()) > dist) {
348  // The second peak is found
349  peak2 = p;
350  return 2;
351  }
352  }
353 
354  // No second peak found
355  peak2.set(0, 0);
356  return 1;
357 }
358 
359 
375 bool
376 vpHistogram::getPeaks(unsigned char dist,
377  vpHistogramPeak & peakl,
378  vpHistogramPeak & peakr,
379  vpHistogramValey & valey)
380 {
381  unsigned char *peak; // Local maxima values
382  int prev_slope; // Previous histogram inclination
383  int next_slope; // Next histogram inclination
384  unsigned index_highest_peak; // Index in peak[] array of the highest peak
385  unsigned index_second_peak; // Index in peak[] array of the second peak
386 
387  unsigned int prof;
388  unsigned int maxprof; // Nb pixels difference between 2 maxi peaks
389  unsigned int nbmini; // Minimum numbers
390  unsigned int sumindmini; // Sum
391  unsigned int mini; // current minimum
392  unsigned int nbpeaks; // Number of peaks in the histogram (ie local maxima)
393 
394  // Init the valey
395  valey.set(0, 0);
396 
397  // Allocation for the
398  peak = new unsigned char [size];
399 
400  // Parse the histogram to get the local maxima
401  nbpeaks = 0;
402  prev_slope = 1;
403  for (unsigned i = 0; i < size-1; i++) {
404  next_slope = (int)histogram[i+1] - (int)histogram[i];
405  if (next_slope == 0)
406  continue;
407  // Peak detection
408  if ( (prev_slope > 0) && (next_slope < 0) )
409  peak[nbpeaks ++] = (unsigned char)i;
410 
411  prev_slope = next_slope;
412  }
413  if (prev_slope > 0)
414  peak[nbpeaks ++] = (unsigned char)(size-1);
415 
416 // vpTRACE("nb peaks: %d", nbpeaks);
417 // for (unsigned i=0; i < nbpeaks; i ++)
418 // vpTRACE("peak %d: pos %d value: %d", i, peak[i], histogram[ peak[i] ]);
419 
420  // Get the global maximum
421  index_highest_peak = 0;
422  for (unsigned int i=0; i < nbpeaks; i++) {
423  if (histogram[ peak[i] ] > histogram[ peak[index_highest_peak] ]) {
424  index_highest_peak = i;
425  }
426  }
427 
428 // vpTRACE("highest peak index: %d pos: %d value: %d",
429 // index_highest_peak, peak[index_highest_peak],
430 // histogram[ peak[index_highest_peak] ]);
431 
432  maxprof=0;
433  index_second_peak=index_highest_peak;
434 
435  // Search second local maximum on the left of the global maximum
436  for (unsigned i = 0; i < index_highest_peak; i++) {
437  if (peak[index_highest_peak] - peak[i] > dist) {
438  prof=0;
439  for (int j=peak[i]; j <= peak[index_highest_peak]-dist; j++)
440  if((histogram[peak[i]] - histogram[j]) > prof)
441  prof = histogram[peak[i]] - histogram[j];
442 
443  if (prof > maxprof) {
444  maxprof = prof;
445  index_second_peak = i;
446  }
447  }
448  }
449 
450  // Search second local maximum on the right of the global maximum
451  for (unsigned i = index_highest_peak+1; i < nbpeaks; i++) {
452  if (peak[i] - peak[index_highest_peak] > dist) {
453  prof=0;
454  for (int j=peak[index_highest_peak]+dist; j <= peak[i]; j++)
455  if((histogram[peak[i]] - histogram[j]) > prof)
456  prof = histogram[peak[i]] - histogram[j];
457 
458  if (prof > maxprof) {
459  maxprof = prof;
460  index_second_peak = i;
461  }
462  }
463  }
464 // vpTRACE("second peak index: %d pos: %d value: %d",
465 // index_second_peak, peak[index_second_peak],
466 // histogram[ peak[index_second_peak] ]);
467 
468  // Determine position of the first and second highest peaks
469  if (peak[index_highest_peak] < peak[index_second_peak])
470  {
471  peakr.set(peak[index_second_peak], histogram[ peak[index_second_peak] ]);
472  peakl.set(peak[index_highest_peak], histogram[ peak[index_highest_peak] ]);
473  }
474  else
475  {
476  peakl.set(peak[index_second_peak], histogram[ peak[index_second_peak] ]);
477  peakr.set(peak[index_highest_peak], histogram[ peak[index_highest_peak]]);
478  }
479 
480  if (peakl == peakr) {
481 
482  delete [] peak;
483 
484  return (false); // Not a bimodal histogram
485  }
486 
487  // Search the valey
488  mini = peakl.getValue();
489  sumindmini=0;
490  nbmini=0;
491  for (unsigned i=peakl.getLevel(); i <= peakr.getLevel(); i++) {
492  if (histogram[i] < mini) {
493  mini=histogram[i];
494  nbmini=1;
495  sumindmini=i;
496  continue;
497  }
498  if (histogram[i] == mini) {
499  sumindmini += i;
500  nbmini ++;
501  }
502  }
503  // vpTRACE("nbmini %d", nbmini);
504  // vpTRACE("sumindmini %d", sumindmini);
505  // vpTRACE("mini: indmini: %d", sumindmini/nbmini);
506 
507  if (nbmini == 0) {
508  // no valey found
509  valey.set(0, 0);
510 
511  delete [] peak;
512 
513  return false;
514  }
515  else {
516  mini = sumindmini/nbmini; // mean
517  valey.set((unsigned char)mini, histogram[mini]);
518 
519  delete [] peak;
520 
521  return (true);
522  }
523 }
524 
536 unsigned vpHistogram::getValey(std::list<vpHistogramValey> & valey)
537 {
538  if (histogram == NULL) {
539  vpERROR_TRACE("Histogram array not initialised\n");
541  "Histogram array not initialised")) ;
542  }
543 
544  int prev_slope; // Previous histogram inclination
545  int next_slope; // Next histogram inclination
546  vpHistogramValey p; // An histogram valey
547  unsigned nbvaley; // Number of valey in the histogram (ie local minima)
548 
549  valey.clear();
550 
551  // Parse the histogram to get the local minima
552  unsigned cpt = 0;
553  unsigned sum_level = 0;
554  nbvaley = 0;
555  prev_slope = -1;
556 
557  for (unsigned i = 0; i < size-1; i++) {
558  next_slope = (int)histogram[i+1] - (int)histogram[i];
559 
560  if ((prev_slope < 0) && (next_slope == 0) ) {
561  sum_level += i + 1;
562  cpt ++;
563  continue;
564  }
565 
566  // Valey detection
567  if ( (prev_slope < 0) && (next_slope > 0) ) {
568  sum_level += i;
569  cpt ++;
570 
571  unsigned int level = sum_level / cpt;
572  p.set((unsigned char)level, histogram[level]);
573  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
574  valey.push_back(p);
575 
576  nbvaley ++;
577 
578  }
579 
580  prev_slope = next_slope;
581  sum_level = 0;
582  cpt = 0;
583  }
584  if (prev_slope < 0) {
585  p.set((unsigned char)size-1u, histogram[size-1]);
586  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
587  valey.push_back(p);
588  nbvaley ++;
589  }
590 
591  return nbvaley;
592 }
593 
608 bool
610  const vpHistogramPeak & peak2,
611  vpHistogramValey & valey)
612 {
613 
614  // Set the left and right peaks
615  vpHistogramPeak peakl, peakr;
616  if (peak1.getLevel() > peak2.getLevel()) {
617  peakl = peak2;
618  peakr = peak1;
619  }
620  else {
621  peakl = peak1;
622  peakr = peak2;
623  }
624 
625  // Search the valey
626  unsigned int nbmini; // Minimum numbers
627  unsigned int sumindmini; // Sum
628  unsigned int mini; // current minimum
629 
630  mini = peakl.getValue();
631  sumindmini=0;
632  nbmini=0;
633  for (unsigned i=peakl.getLevel(); i <= peakr.getLevel(); i++) {
634  if (histogram[i] < mini) {
635  mini=histogram[i];
636  nbmini=1;
637  sumindmini=i;
638  continue;
639  }
640  if (histogram[i] == mini) {
641  sumindmini += i;
642  nbmini ++;
643  }
644  }
645 
646  if (nbmini == 0) {
647  // no valey found
648  valey.set(0, 0);
649 
650  return false;
651  }
652  else {
653  unsigned int minipos = sumindmini/nbmini; // position of the minimum
654 
655  valey.set((unsigned char)minipos, histogram[minipos]);
656  return true;
657  }
658 }
677 unsigned
678 vpHistogram::getValey(unsigned char dist,
679  const vpHistogramPeak & peak,
680  vpHistogramValey & valeyl,
681  vpHistogramValey & valeyr)
682 {
683  unsigned int ret = 0x11;
684  unsigned int nbmini; // Minimum numbers
685  unsigned int sumindmini; // Sum
686  unsigned int mini; // current minimum
687  vpHistogramPeak peakr, peakl; // Left and right peaks of peak
688  std::list<vpHistogramPeak> peaks; // list of histogram peaks
689  // unsigned int nbpeaks=0; // Number of peaks in the histogram (ie local maxima)
690 
691  if (peak.getLevel() == 0) {
692  valeyl.set(0, 0);
693  ret &= 0x01;
694  }
695  if (peak.getLevel() == size -1) {
696  valeyr.set((unsigned char)(size-1), 0);
697  ret &= 0x10;
698  }
699 
700  if (ret >> 1) // consider the left part of the requested peak
701  {
702  // If the list of peaks is empty, compute it
703  if (peaks.empty())
704  {
705  /* nbpeaks = */ getPeaks(peaks);
706  }
707 
708  // if (1) {
709  // // vpTRACE("nb peaks: %d", nbpeaks);
710  // peaks.front();
711  // for (unsigned i=0; i < nbpeaks; i ++) {
712  // vpHistogramPeak p = peaks.value();
713  // // vpTRACE("peak index %d: pos %d value: %d",
714  // // i, p.getLevel(), p.getValue());
715  // peaks.next();
716  // }
717  // }
718  // Go to the requested peak in the list
719  std::list<vpHistogramPeak>::const_iterator it;
720  unsigned index = 0;
721  for (it = peaks.begin(); it != peaks.end(); ++ it)
722  {
723  if (peak == *it) {
724  // we are on the peak.
725  break;
726  }
727  index ++;
728  }
729 
730  bool found = false;
731  if (index == 0) {
732  // No chance to get a peak on the left
733  // should not occur !
734  peakl.set(0,0);
735  }
736  else {
737  // search for the nearest peak on the left that matches the distance
738  std::list<vpHistogramPeak>::const_iterator lit; // left iterator
739  for(lit = peaks.begin(); lit != it; ++ lit)
740  {
741  if (abs((*lit).getLevel() - peak.getLevel()) > dist) {
742  // peakl found
743  peakl = *lit;
744  found = true; // we cannot stop here, since the other peaks on the right may exist
745  }
746  }
747  }
748  if ( ! found)
749  peakl.set(0,0);
750 
751  // Search the valey on the left
752  mini = peak.getValue();
753  sumindmini=0;
754  nbmini=0;
755  for (unsigned i=peakl.getLevel(); i < peak.getLevel(); i++) {
756  if (histogram[i] < mini) {
757  mini=histogram[i];
758  nbmini=1;
759  sumindmini=i;
760  continue;
761  }
762  if (histogram[i] == mini) {
763  sumindmini += i;
764  nbmini ++;
765  }
766  }
767  if (nbmini == 0) {
768  valeyl.set(0, 0);
769  ret &= 0x01;
770  }
771  else {
772  unsigned int minipos = sumindmini/nbmini; // position of the minimum
773  valeyl.set((unsigned char)minipos, histogram[minipos]);
774  ret &= 0x11;
775  }
776  }
777 
778  if (ret << 1) {
779  // If the list of peaks is empty, compute it
780  if (peaks.empty()) {
781  /* nbpeaks = */ getPeaks(peaks);
782  }
783  // Go to the requested peak in the list
784  std::list<vpHistogramPeak>::const_iterator it;
785  unsigned index = 0;
786  for (it = peaks.begin(); it != peaks.end(); ++ it)
787  {
788  if (peak == *it) {
789  // we are on the peak.
790  break;
791  }
792  index ++;
793  }
794 
795  bool found = false;
796  // search for the nearest peak on the right that matches the distance
797  std::list<vpHistogramPeak>::const_iterator rit; // right iterator
798  for(rit = it; rit != peaks.end(); ++ rit)
799 
800  if (abs((*rit).getLevel() - peak.getLevel()) > dist) {
801  // peakr found
802  peakr = *rit;
803  found = true;
804  break; // we can stop here
805  }
806 
807  if ( ! found)
808  peakr.set((unsigned char)(size-1),0);
809 
810  // Search the valey on the right
811  mini = peak.getValue();
812  sumindmini=0;
813  nbmini=0;
814  for (unsigned i=(unsigned int)peak.getLevel()+1; i <= (unsigned int)peakr.getLevel(); i++) {
815  if (histogram[i] < mini) {
816  mini=histogram[i];
817  nbmini=1;
818  sumindmini=i;
819  continue;
820  }
821  if (histogram[i] == mini) {
822  sumindmini += i;
823  nbmini ++;
824  }
825  }
826  if (nbmini == 0) {
827  valeyr.set((unsigned char)(size-1), 0);
828  ret &= 0x10;
829  }
830  else {
831  unsigned int minipos = sumindmini/nbmini; // position of the minimum
832  valeyr.set((unsigned char)minipos, histogram[minipos]);
833  ret &= 0x11;
834  }
835  }
836 
837  return ret;
838 }
839 
848 unsigned vpHistogram::sort(std::list<vpHistogramPeak> & peaks)
849 {
850 
851  if ( peaks.empty() ) {
852  return 0;
853  }
854 
855  peaks.sort(compare_vpHistogramPeak);
856 
857  return (unsigned int)peaks.size();
858 }
859 
872 bool
873 vpHistogram::write(const std::string &filename)
874 {
875  return ( this->write(filename.c_str()) );
876 }
877 
890 bool
891 vpHistogram::write(const char *filename)
892 {
893  std::string opath;
894 
895  FILE *fd = fopen(filename, "w");
896  if (fd == NULL)
897  return false;
898  for (unsigned i=0; i < size; i ++)
899  fprintf(fd, "%d %d\n", i, histogram[i]);
900  fclose(fd);
901 
902  return true;
903 }
904 
905 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
906 
923 {
924  if (histogram == NULL) {
925  vpERROR_TRACE("Histogram array not initialised\n");
927  "Histogram array not initialised")) ;
928  }
929 
930  int prev_slope; // Previous histogram inclination
931  int next_slope; // Next histogram inclination
932  vpHistogramPeak p; // An histogram peak
933  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
934 
935  if ( ! peaks.empty() )
936  peaks.kill();
937 
938  peaks.front();
939 
940  // Parse the histogram to get the local maxima
941  unsigned cpt = 0;
942  unsigned sum_level = 0;
943  nbpeaks = 0;
944  prev_slope = 1;
945 
946  for (unsigned i = 0; i < size-1; i++) {
947  next_slope = (int)histogram[i+1] - (int)histogram[i];
948 
949 // if ((prev_slope < 0) && (next_slope > 0) ) {
950 // sum_level += i;
951 // cpt ++;
952 // continue;
953 // }
954 
955  if ((prev_slope > 0) && (next_slope == 0) ) {
956  sum_level += i + 1;
957  cpt ++;
958  continue;
959  }
960 
961 
962  // Peak detection
963  if ( (prev_slope > 0) && (next_slope < 0) ) {
964  sum_level += i;
965  cpt ++;
966 
967  unsigned int level = sum_level / cpt;
968  p.set((unsigned char)level, histogram[level]);
969  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
970  peaks.addRight(p);
971 
972  nbpeaks ++;
973 
974  }
975 
976  prev_slope = next_slope;
977  sum_level = 0;
978  cpt = 0;
979  }
980  if (prev_slope > 0) {
981  p.set((unsigned char)size-1u, histogram[size-1]);
982  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
983  peaks.addRight(p);
984  nbpeaks ++;
985  }
986 
987  return nbpeaks;
988 }
989 
1004 {
1005  if (histogram == NULL) {
1006  vpERROR_TRACE("Histogram array not initialised\n");
1008  "Histogram array not initialised")) ;
1009  }
1010 
1011  int prev_slope; // Previous histogram inclination
1012  int next_slope; // Next histogram inclination
1013  vpHistogramValey p; // An histogram valey
1014  unsigned nbvaley; // Number of valey in the histogram (ie local minima)
1015 
1016  if ( ! valey.empty() )
1017  valey.kill();
1018 
1019  valey.front();
1020 
1021  // Parse the histogram to get the local minima
1022  unsigned cpt = 0;
1023  unsigned sum_level = 0;
1024  nbvaley = 0;
1025  prev_slope = -1;
1026 
1027  for (unsigned i = 0; i < size-1; i++) {
1028  next_slope = (int)histogram[i+1] - (int)histogram[i];
1029 
1030  if ((prev_slope < 0) && (next_slope == 0) ) {
1031  sum_level += i + 1;
1032  cpt ++;
1033  continue;
1034  }
1035 
1036  // Valey detection
1037  if ( (prev_slope < 0) && (next_slope > 0) ) {
1038  sum_level += i;
1039  cpt ++;
1040 
1041  unsigned int level = sum_level / cpt;
1042  p.set((unsigned char)level, histogram[level]);
1043  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
1044  valey.addRight(p);
1045 
1046  nbvaley ++;
1047 
1048  }
1049 
1050  prev_slope = next_slope;
1051  sum_level = 0;
1052  cpt = 0;
1053  }
1054  if (prev_slope < 0) {
1055  p.set((unsigned char)size-1u, histogram[size-1]);
1056  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
1057  valey.addRight(p);
1058  nbvaley ++;
1059  }
1060 
1061  return nbvaley;
1062 }
1063 
1075 {
1076 
1077  vpList<vpHistogramPeak> _peaks;
1078  vpHistogramPeak p, _p; // A peak
1079  unsigned nbpeaks = 0;
1080 
1081  if ( peaks.empty() ) {
1082  nbpeaks = 0;
1083  return nbpeaks;
1084  }
1085 
1086  _peaks = peaks;
1087  peaks.kill(); // erase the output list
1088  // Sort the list of peaks from highest to the lowest
1089  peaks.front();
1090  _p = _peaks.value();
1091  // Add first value in the list
1092  peaks.addRight(_p);
1093  nbpeaks ++;
1094  // parse the rest of the list
1095  _peaks.next();
1096  while (! _peaks.outside() ) {
1097  _p = _peaks.value();
1098  peaks.front();
1099  while (! peaks.outside() ) {
1100  p = peaks.value();
1101  if (_p.getValue() > p.getValue()) {
1102  peaks.addLeft(_p);
1103  nbpeaks ++;
1104  break;
1105  }
1106  if( peaks.nextOutside()) {
1107  peaks.addRight(_p);
1108  nbpeaks ++;
1109  break;
1110  }
1111 
1112  peaks.next();
1113  }
1114 
1115  _peaks.next();
1116  }
1117  return nbpeaks;
1118 }
1119 
1120 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1121 
1122 /*
1123  * Local variables:
1124  * c-basic-offset: 2
1125  * End:
1126  */
void calculate(const vpImage< unsigned char > &I)
unsigned getPeaks(std::list< vpHistogramPeak > &peaks)
virtual ~vpHistogram()
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
Definition: vpList.h:429
unsigned int getWidth() const
Definition: vpImage.h:159
#define vpERROR_TRACE
Definition: vpDebug.h:395
Provide simple list management.
Definition: vpList.h:113
unsigned getValue() const
vpHistogram & operator=(const vpHistogram &h)
Class to compute a gray level image histogram.
Definition: vpHistogram.h:115
Error that can be emited by the vpImage class and its derivates.
void kill()
Destroy the list.
Definition: vpList.h:692
Declaration of the peak (maximum value) in a gray level image histogram.
void next(void)
position the current element on the next one
Definition: vpList.h:273
void addLeft(const type &el)
add a new element in the list, at the left of the current one
Definition: vpList.h:511
void smooth(const unsigned int fsize=3)
void set(unsigned char lvl, unsigned val)
void front(void)
Position the current element on the first element of the list.
Definition: vpList.h:384
type & value(void)
return the value of the current element
Definition: vpList.h:301
void addRight(const type &el)
add a new element in the list, at the right of the current one
Definition: vpList.h:478
void set(unsigned char lvl, unsigned val)
unsigned sort(std::list< vpHistogramPeak > &peaks)
unsigned char getLevel() const
bool nextOutside(void) const
Test if the next element is outside the list (ie if the current element is the last one) ...
Definition: vpList.h:445
bool write(const std::string &filename)
unsigned int getHeight() const
Definition: vpImage.h:150
Declaration of the valey (minimum value) in a gray level image histogram.
unsigned getValey(std::list< vpHistogramValey > &valey)
bool empty(void) const
Test if the list is empty.
Definition: vpList.h:412