ViSP  2.6.2
vpHistogram.cpp
1 /****************************************************************************
2  *
3  * $Id: vpHistogram.cpp 3530 2012-01-03 10:52:12Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 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 // comparison,
55 bool compare_vpHistogramPeak (vpHistogramPeak first, vpHistogramPeak second)
56 {
57  if (first.getValue() > second.getValue()) return true;
58  else return false;
59 }
60 
61 
62 
67 {
68  histogram = NULL;
69  size = 256;
70  init();
71 }
72 
77 {
78  // vpTRACE("copy");
79  histogram = NULL;
80  init(h.size);
81  memcpy(histogram, h.histogram, size * sizeof(unsigned));
82 }
83 
92 {
93  histogram = NULL;
94  size = 256;
95  init();
96 
97  calculate(I);
98 }
99 
104 {
105  if (histogram != NULL) {
106  // vpTRACE("free: %p", &histogram);
107  delete [] histogram;
108  histogram = NULL;
109  size = 0;
110  }
111 }
112 
126 vpHistogram &
128 {
129  init(h.size);
130  memcpy(histogram, h.histogram, size * sizeof(unsigned));
131 
132  return *this;
133 }
134 
140 void
141 vpHistogram::init(unsigned size)
142 {
143  if (histogram != NULL) {
144  delete [] histogram;
145  histogram = NULL;
146  }
147 
148  this->size = size;
149  histogram = new unsigned [size];
150 
151  memset(histogram, 0, size * sizeof(unsigned));
152 
153  // vpTRACE("alloc: %p", &histogram);
154 }
155 
156 
165 {
166  memset(histogram, 0, size * sizeof(unsigned));
167 
168  for (unsigned i=0; i < I.getHeight(); i ++) {
169  for (unsigned j=0; j < I.getWidth(); j ++) {
170  histogram[ I[i][j] ] ++;
171  }
172  }
173 }
174 
195 void
196 vpHistogram::smooth(const unsigned int fsize)
197 {
198  if (histogram == NULL) {
199  vpERROR_TRACE("Histogram array not initialised\n");
201  "Histogram array not initialised")) ;
202  }
203 
204  vpHistogram h;
205  h = *this;
206 
207  int hsize = (int)fsize / 2; // half filter size
208  unsigned int sum;
209  unsigned int nb;
210 
211  for (unsigned i=0; i < size; i ++) {
212  sum = 0;
213  nb = 0;
214  for (int j=-hsize; j <= hsize; j ++) {
215  // exploitation of the overflow to detect negative value...
216  if ( /*(i + j) >= 0 &&*/ (i + (unsigned int)j) < size ) {
217  sum += h.histogram[i + (unsigned int)j];
218  nb ++;
219  }
220  }
221  histogram[i] = sum / nb;
222  }
223 
224 }
225 
240 unsigned vpHistogram::getPeaks(std::list<vpHistogramPeak> & peaks)
241 {
242  if (histogram == NULL) {
243  vpERROR_TRACE("Histogram array not initialised\n");
245  "Histogram array not initialised")) ;
246  }
247 
248  int prev_slope; // Previous histogram inclination
249  int next_slope; // Next histogram inclination
250  vpHistogramPeak p; // An histogram peak
251  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
252 
253  peaks.clear();
254 
255  // Parse the histogram to get the local maxima
256  unsigned cpt = 0;
257  unsigned sum_level = 0;
258  nbpeaks = 0;
259  prev_slope = 1;
260 
261  for (unsigned i = 0; i < size-1; i++) {
262  next_slope = (int)histogram[i+1] - (int)histogram[i];
263 
264 // if ((prev_slope < 0) && (next_slope > 0) ) {
265 // sum_level += i;
266 // cpt ++;
267 // continue;
268 // }
269 
270  if ((prev_slope > 0) && (next_slope == 0) ) {
271  sum_level += i + 1;
272  cpt ++;
273  continue;
274  }
275 
276 
277  // Peak detection
278  if ( (prev_slope > 0) && (next_slope < 0) ) {
279  sum_level += i;
280  cpt ++;
281 
282  unsigned int level = sum_level / cpt;
283  p.set((unsigned char)level, histogram[level]);
284  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
285  peaks.push_back(p);
286 
287  nbpeaks ++;
288 
289  }
290 
291  prev_slope = next_slope;
292  sum_level = 0;
293  cpt = 0;
294  }
295  if (prev_slope > 0) {
296  p.set((unsigned char)size-1u, histogram[size-1]);
297  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
298  peaks.push_back(p);
299  nbpeaks ++;
300  }
301 
302  return nbpeaks;
303 }
304 
322 unsigned vpHistogram::getPeaks(unsigned char dist,
323  vpHistogramPeak & peak1,
324  vpHistogramPeak & peak2)
325 {
326  std::list<vpHistogramPeak> peaks;
327  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
328 
329  nbpeaks = getPeaks(peaks);
330  sort(peaks);
331 
332  if (nbpeaks == 0) {
333  peak1.set(0, 0);
334  peak2.set(0, 0);
335  return 0;
336  }
337 
338  if (nbpeaks == 1) {
339  peak1 = peaks.front();
340  peak2.set(0, 0);
341  return 1;
342  }
343 
344  // Parse the peaks list to get the peak with a distance greater
345  // than dist to the highest
346  peak1 = peaks.front();
347  for(std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++ it)
348  {
349  vpHistogramPeak p = *it;
350  if (abs(p.getLevel() - peak1.getLevel()) > dist) {
351  // The second peak is found
352  peak2 = p;
353  return 2;
354  }
355  }
356 
357  // No second peak found
358  peak2.set(0, 0);
359  return 1;
360 }
361 
362 
378 bool
379 vpHistogram::getPeaks(unsigned char dist,
380  vpHistogramPeak & peakl,
381  vpHistogramPeak & peakr,
382  vpHistogramValey & valey)
383 {
384  unsigned char *peak; // Local maxima values
385  int prev_slope; // Previous histogram inclination
386  int next_slope; // Next histogram inclination
387  unsigned index_highest_peak; // Index in peak[] array of the highest peak
388  unsigned index_second_peak; // Index in peak[] array of the second peak
389 
390  unsigned int prof;
391  unsigned int maxprof; // Nb pixels difference between 2 maxi peaks
392  unsigned int nbmini; // Minimum numbers
393  unsigned int sumindmini; // Sum
394  unsigned int mini; // current minimum
395  unsigned int nbpeaks; // Number of peaks in the histogram (ie local maxima)
396 
397  // Init the valey
398  valey.set(0, 0);
399 
400  // Allocation for the
401  peak = new unsigned char [size];
402 
403  // Parse the histogram to get the local maxima
404  nbpeaks = 0;
405  prev_slope = 1;
406  for (unsigned i = 0; i < size-1; i++) {
407  next_slope = (int)histogram[i+1] - (int)histogram[i];
408  if (next_slope == 0)
409  continue;
410  // Peak detection
411  if ( (prev_slope > 0) && (next_slope < 0) )
412  peak[nbpeaks ++] = (unsigned char)i;
413 
414  prev_slope = next_slope;
415  }
416  if (prev_slope > 0)
417  peak[nbpeaks ++] = (unsigned char)(size-1);
418 
419 // vpTRACE("nb peaks: %d", nbpeaks);
420 // for (unsigned i=0; i < nbpeaks; i ++)
421 // vpTRACE("peak %d: pos %d value: %d", i, peak[i], histogram[ peak[i] ]);
422 
423  // Get the global maximum
424  index_highest_peak = 0;
425  for (unsigned int i=0; i < nbpeaks; i++) {
426  if (histogram[ peak[i] ] > histogram[ peak[index_highest_peak] ]) {
427  index_highest_peak = i;
428  }
429  }
430 
431 // vpTRACE("highest peak index: %d pos: %d value: %d",
432 // index_highest_peak, peak[index_highest_peak],
433 // histogram[ peak[index_highest_peak] ]);
434 
435  maxprof=0;
436  index_second_peak=index_highest_peak;
437 
438  // Search second local maximum on the left of the global maximum
439  for (unsigned i = 0; i < index_highest_peak; i++) {
440  if (peak[index_highest_peak] - peak[i] > dist) {
441  prof=0;
442  for (int j=peak[i]; j <= peak[index_highest_peak]-dist; j++)
443  if((histogram[peak[i]] - histogram[j]) > prof)
444  prof = histogram[peak[i]] - histogram[j];
445 
446  if (prof > maxprof) {
447  maxprof = prof;
448  index_second_peak = i;
449  }
450  }
451  }
452 
453  // Search second local maximum on the right of the global maximum
454  for (unsigned i = index_highest_peak+1; i < nbpeaks; i++) {
455  if (peak[i] - peak[index_highest_peak] > dist) {
456  prof=0;
457  for (int j=peak[index_highest_peak]+dist; j <= peak[i]; j++)
458  if((histogram[peak[i]] - histogram[j]) > prof)
459  prof = histogram[peak[i]] - histogram[j];
460 
461  if (prof > maxprof) {
462  maxprof = prof;
463  index_second_peak = i;
464  }
465  }
466  }
467 // vpTRACE("second peak index: %d pos: %d value: %d",
468 // index_second_peak, peak[index_second_peak],
469 // histogram[ peak[index_second_peak] ]);
470 
471  // Determine position of the first and second highest peaks
472  if (peak[index_highest_peak] < peak[index_second_peak])
473  {
474  peakr.set(peak[index_second_peak], histogram[ peak[index_second_peak] ]);
475  peakl.set(peak[index_highest_peak], histogram[ peak[index_highest_peak] ]);
476  }
477  else
478  {
479  peakl.set(peak[index_second_peak], histogram[ peak[index_second_peak] ]);
480  peakr.set(peak[index_highest_peak], histogram[ peak[index_highest_peak]]);
481  }
482 
483  if (peakl == peakr) {
484 
485  delete [] peak;
486 
487  return (false); // Not a bimodal histogram
488  }
489 
490  // Search the valey
491  mini = peakl.getValue();
492  sumindmini=0;
493  nbmini=0;
494  for (unsigned i=peakl.getLevel(); i <= peakr.getLevel(); i++) {
495  if (histogram[i] < mini) {
496  mini=histogram[i];
497  nbmini=1;
498  sumindmini=i;
499  continue;
500  }
501  if (histogram[i] == mini) {
502  sumindmini += i;
503  nbmini ++;
504  }
505  }
506  // vpTRACE("nbmini %d", nbmini);
507  // vpTRACE("sumindmini %d", sumindmini);
508  // vpTRACE("mini: indmini: %d", sumindmini/nbmini);
509 
510  if (nbmini == 0) {
511  // no valey found
512  valey.set(0, 0);
513 
514  delete [] peak;
515 
516  return false;
517  }
518  else {
519  mini = sumindmini/nbmini; // mean
520  valey.set((unsigned char)mini, histogram[mini]);
521 
522  delete [] peak;
523 
524  return (true);
525  }
526 }
527 
539 unsigned vpHistogram::getValey(std::list<vpHistogramValey> & valey)
540 {
541  if (histogram == NULL) {
542  vpERROR_TRACE("Histogram array not initialised\n");
544  "Histogram array not initialised")) ;
545  }
546 
547  int prev_slope; // Previous histogram inclination
548  int next_slope; // Next histogram inclination
549  vpHistogramValey p; // An histogram valey
550  unsigned nbvaley; // Number of valey in the histogram (ie local minima)
551 
552  valey.clear();
553 
554  // Parse the histogram to get the local minima
555  unsigned cpt = 0;
556  unsigned sum_level = 0;
557  nbvaley = 0;
558  prev_slope = -1;
559 
560  for (unsigned i = 0; i < size-1; i++) {
561  next_slope = (int)histogram[i+1] - (int)histogram[i];
562 
563  if ((prev_slope < 0) && (next_slope == 0) ) {
564  sum_level += i + 1;
565  cpt ++;
566  continue;
567  }
568 
569  // Valey detection
570  if ( (prev_slope < 0) && (next_slope > 0) ) {
571  sum_level += i;
572  cpt ++;
573 
574  unsigned int level = sum_level / cpt;
575  p.set((unsigned char)level, histogram[level]);
576  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
577  valey.push_back(p);
578 
579  nbvaley ++;
580 
581  }
582 
583  prev_slope = next_slope;
584  sum_level = 0;
585  cpt = 0;
586  }
587  if (prev_slope < 0) {
588  p.set((unsigned char)size-1u, histogram[size-1]);
589  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
590  valey.push_back(p);
591  nbvaley ++;
592  }
593 
594  return nbvaley;
595 }
596 
611 bool
613  const vpHistogramPeak & peak2,
614  vpHistogramValey & valey)
615 {
616 
617  // Set the left and right peaks
618  vpHistogramPeak peakl, peakr;
619  if (peak1.getLevel() > peak2.getLevel()) {
620  peakl = peak2;
621  peakr = peak1;
622  }
623  else {
624  peakl = peak1;
625  peakr = peak2;
626  }
627 
628  // Search the valey
629  unsigned int nbmini; // Minimum numbers
630  unsigned int sumindmini; // Sum
631  unsigned int mini; // current minimum
632 
633  mini = peakl.getValue();
634  sumindmini=0;
635  nbmini=0;
636  for (unsigned i=peakl.getLevel(); i <= peakr.getLevel(); i++) {
637  if (histogram[i] < mini) {
638  mini=histogram[i];
639  nbmini=1;
640  sumindmini=i;
641  continue;
642  }
643  if (histogram[i] == mini) {
644  sumindmini += i;
645  nbmini ++;
646  }
647  }
648 
649  if (nbmini == 0) {
650  // no valey found
651  valey.set(0, 0);
652 
653  return false;
654  }
655  else {
656  unsigned int minipos = sumindmini/nbmini; // position of the minimum
657 
658  valey.set((unsigned char)minipos, histogram[minipos]);
659  return true;
660  }
661 }
680 unsigned
681 vpHistogram::getValey(unsigned char dist,
682  const vpHistogramPeak & peak,
683  vpHistogramValey & valeyl,
684  vpHistogramValey & valeyr)
685 {
686  unsigned int ret = 0x11;
687  unsigned int nbmini; // Minimum numbers
688  unsigned int sumindmini; // Sum
689  unsigned int mini; // current minimum
690  vpHistogramPeak peakr, peakl; // Left and right peaks of peak
691  std::list<vpHistogramPeak> peaks; // list of histogram peaks
692  // unsigned int nbpeaks=0; // Number of peaks in the histogram (ie local maxima)
693 
694  if (peak.getLevel() == 0) {
695  valeyl.set(0, 0);
696  ret &= 0x01;
697  }
698  if (peak.getLevel() == size -1) {
699  valeyr.set((unsigned char)(size-1), 0);
700  ret &= 0x10;
701  }
702 
703  if (ret >> 1) // consider the left part of the requested peak
704  {
705  // If the list of peaks is empty, compute it
706  if (peaks.empty())
707  {
708  /* nbpeaks = */ getPeaks(peaks);
709  }
710 
711  // if (1) {
712  // // vpTRACE("nb peaks: %d", nbpeaks);
713  // peaks.front();
714  // for (unsigned i=0; i < nbpeaks; i ++) {
715  // vpHistogramPeak p = peaks.value();
716  // // vpTRACE("peak index %d: pos %d value: %d",
717  // // i, p.getLevel(), p.getValue());
718  // peaks.next();
719  // }
720  // }
721  // Go to the requested peak in the list
722  std::list<vpHistogramPeak>::const_iterator it;
723  unsigned index = 0;
724  for (it = peaks.begin(); it != peaks.end(); ++ it)
725  {
726  if (peak == *it) {
727  // we are on the peak.
728  break;
729  }
730  index ++;
731  }
732 
733  bool found = false;
734  if (index == 0) {
735  // No chance to get a peak on the left
736  // should not occur !
737  peakl.set(0,0);
738  }
739  else {
740  // search for the nearest peak on the left that matches the distance
741  std::list<vpHistogramPeak>::const_iterator lit; // left iterator
742  for(lit = peaks.begin(); lit != it; ++ lit)
743  {
744  if (abs((*lit).getLevel() - peak.getLevel()) > dist) {
745  // peakl found
746  peakl = *lit;
747  found = true; // we cannot stop here, since the other peaks on the right may exist
748  }
749  }
750  }
751  if ( ! found)
752  peakl.set(0,0);
753 
754  // Search the valey on the left
755  mini = peak.getValue();
756  sumindmini=0;
757  nbmini=0;
758  for (unsigned i=peakl.getLevel(); i < peak.getLevel(); i++) {
759  if (histogram[i] < mini) {
760  mini=histogram[i];
761  nbmini=1;
762  sumindmini=i;
763  continue;
764  }
765  if (histogram[i] == mini) {
766  sumindmini += i;
767  nbmini ++;
768  }
769  }
770  if (nbmini == 0) {
771  valeyl.set(0, 0);
772  ret &= 0x01;
773  }
774  else {
775  unsigned int minipos = sumindmini/nbmini; // position of the minimum
776  valeyl.set((unsigned char)minipos, histogram[minipos]);
777  ret &= 0x11;
778  }
779  }
780 
781  if (ret << 1) {
782  // If the list of peaks is empty, compute it
783  if (peaks.empty()) {
784  /* nbpeaks = */ getPeaks(peaks);
785  }
786  // Go to the requested peak in the list
787  std::list<vpHistogramPeak>::const_iterator it;
788  unsigned index = 0;
789  for (it = peaks.begin(); it != peaks.end(); ++ it)
790  {
791  if (peak == *it) {
792  // we are on the peak.
793  break;
794  }
795  index ++;
796  }
797 
798  bool found = false;
799  // search for the nearest peak on the right that matches the distance
800  std::list<vpHistogramPeak>::const_iterator rit; // right iterator
801  for(rit = it; rit != peaks.end(); ++ rit)
802 
803  if (abs((*rit).getLevel() - peak.getLevel()) > dist) {
804  // peakr found
805  peakr = *rit;
806  found = true;
807  break; // we can stop here
808  }
809 
810  if ( ! found)
811  peakr.set((unsigned char)(size-1),0);
812 
813  // Search the valey on the right
814  mini = peak.getValue();
815  sumindmini=0;
816  nbmini=0;
817  for (unsigned i=(unsigned int)peak.getLevel()+1; i <= (unsigned int)peakr.getLevel(); i++) {
818  if (histogram[i] < mini) {
819  mini=histogram[i];
820  nbmini=1;
821  sumindmini=i;
822  continue;
823  }
824  if (histogram[i] == mini) {
825  sumindmini += i;
826  nbmini ++;
827  }
828  }
829  if (nbmini == 0) {
830  valeyr.set((unsigned char)(size-1), 0);
831  ret &= 0x10;
832  }
833  else {
834  unsigned int minipos = sumindmini/nbmini; // position of the minimum
835  valeyr.set((unsigned char)minipos, histogram[minipos]);
836  ret &= 0x11;
837  }
838  }
839 
840  return ret;
841 }
842 
851 unsigned vpHistogram::sort(std::list<vpHistogramPeak> & peaks)
852 {
853 
854  if ( peaks.empty() ) {
855  return 0;
856  }
857 
858  peaks.sort(compare_vpHistogramPeak);
859 
860  return peaks.size();
861 }
862 
875 bool
876 vpHistogram::write(const std::string &filename)
877 {
878  return ( this->write(filename.c_str()) );
879 }
880 
893 bool
894 vpHistogram::write(const char *filename)
895 {
896  std::string opath;
897 
898  FILE *fd = fopen(filename, "w");
899  if (fd == NULL)
900  return false;
901  for (unsigned i=0; i < size; i ++)
902  fprintf(fd, "%d %d\n", i, histogram[i]);
903  fclose(fd);
904 
905  return true;
906 }
907 
908 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
909 
926 {
927  if (histogram == NULL) {
928  vpERROR_TRACE("Histogram array not initialised\n");
930  "Histogram array not initialised")) ;
931  }
932 
933  int prev_slope; // Previous histogram inclination
934  int next_slope; // Next histogram inclination
935  vpHistogramPeak p; // An histogram peak
936  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
937 
938  if ( ! peaks.empty() )
939  peaks.kill();
940 
941  peaks.front();
942 
943  // Parse the histogram to get the local maxima
944  unsigned cpt = 0;
945  unsigned sum_level = 0;
946  nbpeaks = 0;
947  prev_slope = 1;
948 
949  for (unsigned i = 0; i < size-1; i++) {
950  next_slope = (int)histogram[i+1] - (int)histogram[i];
951 
952 // if ((prev_slope < 0) && (next_slope > 0) ) {
953 // sum_level += i;
954 // cpt ++;
955 // continue;
956 // }
957 
958  if ((prev_slope > 0) && (next_slope == 0) ) {
959  sum_level += i + 1;
960  cpt ++;
961  continue;
962  }
963 
964 
965  // Peak detection
966  if ( (prev_slope > 0) && (next_slope < 0) ) {
967  sum_level += i;
968  cpt ++;
969 
970  unsigned int level = sum_level / cpt;
971  p.set((unsigned char)level, histogram[level]);
972  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
973  peaks.addRight(p);
974 
975  nbpeaks ++;
976 
977  }
978 
979  prev_slope = next_slope;
980  sum_level = 0;
981  cpt = 0;
982  }
983  if (prev_slope > 0) {
984  p.set((unsigned char)size-1u, histogram[size-1]);
985  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
986  peaks.addRight(p);
987  nbpeaks ++;
988  }
989 
990  return nbpeaks;
991 }
992 
1007 {
1008  if (histogram == NULL) {
1009  vpERROR_TRACE("Histogram array not initialised\n");
1011  "Histogram array not initialised")) ;
1012  }
1013 
1014  int prev_slope; // Previous histogram inclination
1015  int next_slope; // Next histogram inclination
1016  vpHistogramValey p; // An histogram valey
1017  unsigned nbvaley; // Number of valey in the histogram (ie local minima)
1018 
1019  if ( ! valey.empty() )
1020  valey.kill();
1021 
1022  valey.front();
1023 
1024  // Parse the histogram to get the local minima
1025  unsigned cpt = 0;
1026  unsigned sum_level = 0;
1027  nbvaley = 0;
1028  prev_slope = -1;
1029 
1030  for (unsigned i = 0; i < size-1; i++) {
1031  next_slope = (int)histogram[i+1] - (int)histogram[i];
1032 
1033  if ((prev_slope < 0) && (next_slope == 0) ) {
1034  sum_level += i + 1;
1035  cpt ++;
1036  continue;
1037  }
1038 
1039  // Valey detection
1040  if ( (prev_slope < 0) && (next_slope > 0) ) {
1041  sum_level += i;
1042  cpt ++;
1043 
1044  unsigned int level = sum_level / cpt;
1045  p.set((unsigned char)level, histogram[level]);
1046  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
1047  valey.addRight(p);
1048 
1049  nbvaley ++;
1050 
1051  }
1052 
1053  prev_slope = next_slope;
1054  sum_level = 0;
1055  cpt = 0;
1056  }
1057  if (prev_slope < 0) {
1058  p.set((unsigned char)size-1u, histogram[size-1]);
1059  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
1060  valey.addRight(p);
1061  nbvaley ++;
1062  }
1063 
1064  return nbvaley;
1065 }
1066 
1078 {
1079 
1080  vpList<vpHistogramPeak> _peaks;
1081  vpHistogramPeak p, _p; // A peak
1082  unsigned nbpeaks = 0;
1083 
1084  if ( peaks.empty() ) {
1085  nbpeaks = 0;
1086  return nbpeaks;
1087  }
1088 
1089  _peaks = peaks;
1090  peaks.kill(); // erase the output list
1091  // Sort the list of peaks from highest to the lowest
1092  peaks.front();
1093  _p = _peaks.value();
1094  // Add first value in the list
1095  peaks.addRight(_p);
1096  nbpeaks ++;
1097  // parse the rest of the list
1098  _peaks.next();
1099  while (! _peaks.outside() ) {
1100  _p = _peaks.value();
1101  peaks.front();
1102  while (! peaks.outside() ) {
1103  p = peaks.value();
1104  if (_p.getValue() > p.getValue()) {
1105  peaks.addLeft(_p);
1106  nbpeaks ++;
1107  break;
1108  }
1109  if( peaks.nextOutside()) {
1110  peaks.addRight(_p);
1111  nbpeaks ++;
1112  break;
1113  }
1114 
1115  peaks.next();
1116  }
1117 
1118  _peaks.next();
1119  }
1120  return nbpeaks;
1121 }
1122 
1123 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1124 
1125 /*
1126  * Local variables:
1127  * c-basic-offset: 2
1128  * End:
1129  */
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:431
unsigned int getWidth() const
Definition: vpImage.h:154
#define vpERROR_TRACE
Definition: vpDebug.h:379
Provide simple list management.
Definition: vpList.h:112
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:694
Declaration of the peak (maximum value) in a gray level image histogram.
void set(unsigned char level, unsigned value)
void next(void)
position the current element on the next one
Definition: vpList.h:275
void addLeft(const type &el)
add a new element in the list, at the left of the current one
Definition: vpList.h:513
void smooth(const unsigned int fsize=3)
void set(unsigned char level, unsigned value)
void front(void)
Position the current element on the first element of the list.
Definition: vpList.h:386
type & value(void)
return the value of the current element
Definition: vpList.h:303
void addRight(const type &el)
add a new element in the list, at the right of the current one
Definition: vpList.h:480
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:447
bool write(const std::string &filename)
unsigned int getHeight() const
Definition: vpImage.h:145
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:414