Visual Servoing Platform  version 3.0.0
vpHistogram.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Gray level histogram manipulation.
32  *
33  * Author:
34  * Fabien Spindler
35  *
36  *****************************************************************************/
37 
47 #include <stdlib.h>
48 #include <visp3/core/vpHistogram.h>
49 #include <visp3/core/vpImageConvert.h>
50 #include <visp3/core/vpDisplay.h>
51 
52 
53 bool compare_vpHistogramPeak (vpHistogramPeak first, vpHistogramPeak second);
54 
55 // comparison,
56 bool compare_vpHistogramPeak (vpHistogramPeak first, vpHistogramPeak second)
57 {
58  if (first.getValue() > second.getValue()) return true;
59  else return false;
60 }
61 
62 
63 
67 vpHistogram::vpHistogram() : histogram(NULL), size(256)
68 {
69  init();
70 }
71 
75 vpHistogram::vpHistogram(const vpHistogram &h) : histogram(NULL), size(256)
76 {
77  init(h.size);
78  memcpy(histogram, h.histogram, size * sizeof(unsigned));
79 }
80 
89  : histogram(NULL), size(256)
90 {
91  init();
92 
93  calculate(I);
94 }
95 
100 {
101  if (histogram != NULL) {
102  // vpTRACE("free: %p", &histogram);
103  delete [] histogram;
104  histogram = NULL;
105  size = 0;
106  }
107 }
108 
122 vpHistogram &
124 {
125  init(h.size);
126  memcpy(histogram, h.histogram, size * sizeof(unsigned));
127 
128  return *this;
129 }
130 
136 void
137 vpHistogram::init(unsigned size_)
138 {
139  if (histogram != NULL) {
140  delete [] histogram;
141  histogram = NULL;
142  }
143 
144  this->size = size_;
145  histogram = new unsigned [size];
146 
147  memset(histogram, 0, size * sizeof(unsigned));
148 
149  // vpTRACE("alloc: %p", &histogram);
150 }
151 
152 
160 void vpHistogram::calculate(const vpImage<unsigned char> &I, const unsigned int nbins)
161 {
162  if(size != nbins) {
163  if (histogram != NULL) {
164  delete [] histogram;
165  histogram = NULL;
166  }
167 
168  size = nbins > 256 ? 256 : (nbins > 0 ? nbins : 256);
169  if(nbins > 256 || nbins == 0) {
170  std::cerr << "nbins=" << nbins << " , nbins should be between ]0 ; 256] ; use by default nbins=256" << std::endl;
171  }
172  histogram = new unsigned int[size];
173  }
174 
175  memset(histogram, 0, size * sizeof(unsigned));
176 
177  unsigned int lut[256];
178  for(unsigned int i = 0; i < 256; i++) {
179  lut[i] = (unsigned int) (i * size / 256.0);
180  }
181 
182  unsigned int size_ = I.getWidth()*I.getHeight();
183  unsigned char *ptrStart = (unsigned char*) I.bitmap;
184  unsigned char *ptrEnd = ptrStart + size_;
185  unsigned char *ptrCurrent = ptrStart;
186 
187  while(ptrCurrent != ptrEnd) {
188  histogram[ lut[ *ptrCurrent ] ] ++;
189  ++ptrCurrent;
190  }
191 }
192 
202 void vpHistogram::display(const vpImage<unsigned char> &I, const vpColor &color, const unsigned int thickness,
203  const unsigned int maxValue_) {
204  unsigned int width = I.getWidth(), height = I.getHeight();
205  //Minimal width and height are 36 px
206  if(width < 36 || height < 36) {
207  std::cerr << "Image I must have at least width >= 36 && height >= 36 !" << std::endl;
208  return;
209  }
210 
211  unsigned int maxValue = maxValue_;
212  if(maxValue == 0) {
213  for(unsigned int i = 0; i < size; i++) {
214  if(histogram[i] > maxValue) {
215  maxValue = histogram[i];
216  }
217  }
218  }
219 
220  if (maxValue == 0) {
222  "Cannot display histogram; max value=0"));
223  }
224  //Keep 12 free pixels at the top
225  unsigned int max_height = height-12;
226  double ratio_height = max_height / (double) maxValue;
227  double ratio_width = (width-1) / (double) (size-1.0);
228 
229  for(unsigned int i = 1; i < size; i++) {
230  unsigned int value1 = histogram[i-1];
231  unsigned int value2 = histogram[i];
232 
233  vpImagePoint startPt((height-1)-(value1*ratio_height), (i-1)*ratio_width);
234  vpImagePoint endPt((height-1)-(value2*ratio_height), (i*ratio_width));
235  vpDisplay::displayLine(I, startPt, endPt, color, thickness);
236  }
237 }
238 
259 void
260 vpHistogram::smooth(const unsigned int fsize)
261 {
262  if (histogram == NULL) {
263  vpERROR_TRACE("Histogram array not initialised\n");
265  "Histogram array not initialised")) ;
266  }
267 
268  vpHistogram h;
269  h = *this;
270 
271  int hsize = (int)fsize / 2; // half filter size
272  unsigned int sum;
273  unsigned int nb;
274 
275  for (unsigned i=0; i < size; i ++) {
276  sum = 0;
277  nb = 0;
278  for (int j=-hsize; j <= hsize; j ++) {
279  // exploitation of the overflow to detect negative value...
280  if ( /*(i + j) >= 0 &&*/ (i + (unsigned int)j) < size ) {
281  sum += h.histogram[i + (unsigned int)j];
282  nb ++;
283  }
284  }
285  histogram[i] = sum / nb;
286  }
287 
288 }
289 
304 unsigned vpHistogram::getPeaks(std::list<vpHistogramPeak> & peaks)
305 {
306  if (histogram == NULL) {
307  vpERROR_TRACE("Histogram array not initialised\n");
309  "Histogram array not initialised")) ;
310  }
311 
312  int prev_slope; // Previous histogram inclination
313  int next_slope; // Next histogram inclination
314  vpHistogramPeak p; // An histogram peak
315  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
316 
317  peaks.clear();
318 
319  // Parse the histogram to get the local maxima
320  unsigned cpt = 0;
321  unsigned sum_level = 0;
322  nbpeaks = 0;
323  prev_slope = 1;
324 
325  for (unsigned i = 0; i < size-1; i++) {
326  next_slope = (int)histogram[i+1] - (int)histogram[i];
327 
328 // if ((prev_slope < 0) && (next_slope > 0) ) {
329 // sum_level += i;
330 // cpt ++;
331 // continue;
332 // }
333 
334  if ((prev_slope > 0) && (next_slope == 0) ) {
335  sum_level += i + 1;
336  cpt ++;
337  continue;
338  }
339 
340 
341  // Peak detection
342  if ( (prev_slope > 0) && (next_slope < 0) ) {
343  sum_level += i;
344  cpt ++;
345 
346  unsigned int level = sum_level / cpt;
347  p.set((unsigned char)level, histogram[level]);
348  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
349  peaks.push_back(p);
350 
351  nbpeaks ++;
352 
353  }
354 
355  prev_slope = next_slope;
356  sum_level = 0;
357  cpt = 0;
358  }
359  if (prev_slope > 0) {
360  p.set((unsigned char)size-1u, histogram[size-1]);
361  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
362  peaks.push_back(p);
363  nbpeaks ++;
364  }
365 
366  return nbpeaks;
367 }
368 
386 unsigned vpHistogram::getPeaks(unsigned char dist,
387  vpHistogramPeak & peak1,
388  vpHistogramPeak & peak2)
389 {
390  std::list<vpHistogramPeak> peaks;
391  unsigned nbpeaks; // Number of peaks in the histogram (ie local maxima)
392 
393  nbpeaks = getPeaks(peaks);
394  sort(peaks);
395 
396  if (nbpeaks == 0) {
397  peak1.set(0, 0);
398  peak2.set(0, 0);
399  return 0;
400  }
401 
402  if (nbpeaks == 1) {
403  peak1 = peaks.front();
404  peak2.set(0, 0);
405  return 1;
406  }
407 
408  // Parse the peaks list to get the peak with a distance greater
409  // than dist to the highest
410  peak1 = peaks.front();
411  for(std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++ it)
412  {
413  vpHistogramPeak p = *it;
414  if (abs(p.getLevel() - peak1.getLevel()) > dist) {
415  // The second peak is found
416  peak2 = p;
417  return 2;
418  }
419  }
420 
421  // No second peak found
422  peak2.set(0, 0);
423  return 1;
424 }
425 
426 
442 bool
443 vpHistogram::getPeaks(unsigned char dist,
444  vpHistogramPeak & peakl,
445  vpHistogramPeak & peakr,
446  vpHistogramValey & valey)
447 {
448  unsigned char *peak; // Local maxima values
449  int prev_slope; // Previous histogram inclination
450  int next_slope; // Next histogram inclination
451  unsigned index_highest_peak; // Index in peak[] array of the highest peak
452  unsigned index_second_peak; // Index in peak[] array of the second peak
453 
454  unsigned int prof;
455  unsigned int maxprof; // Nb pixels difference between 2 maxi peaks
456  unsigned int nbmini; // Minimum numbers
457  unsigned int sumindmini; // Sum
458  unsigned int mini; // current minimum
459  unsigned int nbpeaks; // Number of peaks in the histogram (ie local maxima)
460 
461  // Init the valey
462  valey.set(0, 0);
463 
464  // Allocation for the
465  peak = new unsigned char [size];
466 
467  // Parse the histogram to get the local maxima
468  nbpeaks = 0;
469  prev_slope = 1;
470  for (unsigned i = 0; i < size-1; i++) {
471  next_slope = (int)histogram[i+1] - (int)histogram[i];
472  if (next_slope == 0)
473  continue;
474  // Peak detection
475  if ( (prev_slope > 0) && (next_slope < 0) )
476  peak[nbpeaks ++] = (unsigned char)i;
477 
478  prev_slope = next_slope;
479  }
480  if (prev_slope > 0)
481  peak[nbpeaks ++] = (unsigned char)(size-1);
482 
483 // vpTRACE("nb peaks: %d", nbpeaks);
484 // for (unsigned i=0; i < nbpeaks; i ++)
485 // vpTRACE("peak %d: pos %d value: %d", i, peak[i], histogram[ peak[i] ]);
486 
487  // Get the global maximum
488  index_highest_peak = 0;
489  for (unsigned int i=0; i < nbpeaks; i++) {
490  if (histogram[ peak[i] ] > histogram[ peak[index_highest_peak] ]) {
491  index_highest_peak = i;
492  }
493  }
494 
495 // vpTRACE("highest peak index: %d pos: %d value: %d",
496 // index_highest_peak, peak[index_highest_peak],
497 // histogram[ peak[index_highest_peak] ]);
498 
499  maxprof=0;
500  index_second_peak=index_highest_peak;
501 
502  // Search second local maximum on the left of the global maximum
503  for (unsigned i = 0; i < index_highest_peak; i++) {
504  if (peak[index_highest_peak] - peak[i] > dist) {
505  prof=0;
506  for (int j=peak[i]; j <= peak[index_highest_peak]-dist; j++)
507  if((histogram[peak[i]] - histogram[j]) > prof)
508  prof = histogram[peak[i]] - histogram[j];
509 
510  if (prof > maxprof) {
511  maxprof = prof;
512  index_second_peak = i;
513  }
514  }
515  }
516 
517  // Search second local maximum on the right of the global maximum
518  for (unsigned i = index_highest_peak+1; i < nbpeaks; i++) {
519  if (peak[i] - peak[index_highest_peak] > dist) {
520  prof=0;
521  for (int j=peak[index_highest_peak]+dist; j <= peak[i]; j++)
522  if((histogram[peak[i]] - histogram[j]) > prof)
523  prof = histogram[peak[i]] - histogram[j];
524 
525  if (prof > maxprof) {
526  maxprof = prof;
527  index_second_peak = i;
528  }
529  }
530  }
531 // vpTRACE("second peak index: %d pos: %d value: %d",
532 // index_second_peak, peak[index_second_peak],
533 // histogram[ peak[index_second_peak] ]);
534 
535  // Determine position of the first and second highest peaks
536  if (peak[index_highest_peak] < peak[index_second_peak])
537  {
538  peakr.set(peak[index_second_peak], histogram[ peak[index_second_peak] ]);
539  peakl.set(peak[index_highest_peak], histogram[ peak[index_highest_peak] ]);
540  }
541  else
542  {
543  peakl.set(peak[index_second_peak], histogram[ peak[index_second_peak] ]);
544  peakr.set(peak[index_highest_peak], histogram[ peak[index_highest_peak]]);
545  }
546 
547  if (peakl == peakr) {
548 
549  delete [] peak;
550 
551  return (false); // Not a bimodal histogram
552  }
553 
554  // Search the valey
555  mini = peakl.getValue();
556  sumindmini=0;
557  nbmini=0;
558  for (unsigned i=peakl.getLevel(); i <= peakr.getLevel(); i++) {
559  if (histogram[i] < mini) {
560  mini=histogram[i];
561  nbmini=1;
562  sumindmini=i;
563  continue;
564  }
565  if (histogram[i] == mini) {
566  sumindmini += i;
567  nbmini ++;
568  }
569  }
570  // vpTRACE("nbmini %d", nbmini);
571  // vpTRACE("sumindmini %d", sumindmini);
572  // vpTRACE("mini: indmini: %d", sumindmini/nbmini);
573 
574  if (nbmini == 0) {
575  // no valey found
576  valey.set(0, 0);
577 
578  delete [] peak;
579 
580  return false;
581  }
582  else {
583  mini = sumindmini/nbmini; // mean
584  valey.set((unsigned char)mini, histogram[mini]);
585 
586  delete [] peak;
587 
588  return (true);
589  }
590 }
591 
603 unsigned vpHistogram::getValey(std::list<vpHistogramValey> & valey)
604 {
605  if (histogram == NULL) {
606  vpERROR_TRACE("Histogram array not initialised\n");
608  "Histogram array not initialised")) ;
609  }
610 
611  int prev_slope; // Previous histogram inclination
612  int next_slope; // Next histogram inclination
613  vpHistogramValey p; // An histogram valey
614  unsigned nbvaley; // Number of valey in the histogram (ie local minima)
615 
616  valey.clear();
617 
618  // Parse the histogram to get the local minima
619  unsigned cpt = 0;
620  unsigned sum_level = 0;
621  nbvaley = 0;
622  prev_slope = -1;
623 
624  for (unsigned i = 0; i < size-1; i++) {
625  next_slope = (int)histogram[i+1] - (int)histogram[i];
626 
627  if ((prev_slope < 0) && (next_slope == 0) ) {
628  sum_level += i + 1;
629  cpt ++;
630  continue;
631  }
632 
633  // Valey detection
634  if ( (prev_slope < 0) && (next_slope > 0) ) {
635  sum_level += i;
636  cpt ++;
637 
638  unsigned int level = sum_level / cpt;
639  p.set((unsigned char)level, histogram[level]);
640  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
641  valey.push_back(p);
642 
643  nbvaley ++;
644 
645  }
646 
647  prev_slope = next_slope;
648  sum_level = 0;
649  cpt = 0;
650  }
651  if (prev_slope < 0) {
652  p.set((unsigned char)size-1u, histogram[size-1]);
653  // vpTRACE("add %d %d", p.getLevel(), p.getValue());
654  valey.push_back(p);
655  nbvaley ++;
656  }
657 
658  return nbvaley;
659 }
660 
675 bool
677  const vpHistogramPeak & peak2,
678  vpHistogramValey & valey)
679 {
680 
681  // Set the left and right peaks
682  vpHistogramPeak peakl, peakr;
683  if (peak1.getLevel() > peak2.getLevel()) {
684  peakl = peak2;
685  peakr = peak1;
686  }
687  else {
688  peakl = peak1;
689  peakr = peak2;
690  }
691 
692  // Search the valey
693  unsigned int nbmini; // Minimum numbers
694  unsigned int sumindmini; // Sum
695  unsigned int mini; // current minimum
696 
697  mini = peakl.getValue();
698  sumindmini=0;
699  nbmini=0;
700  for (unsigned i=peakl.getLevel(); i <= peakr.getLevel(); i++) {
701  if (histogram[i] < mini) {
702  mini=histogram[i];
703  nbmini=1;
704  sumindmini=i;
705  continue;
706  }
707  if (histogram[i] == mini) {
708  sumindmini += i;
709  nbmini ++;
710  }
711  }
712 
713  if (nbmini == 0) {
714  // no valey found
715  valey.set(0, 0);
716 
717  return false;
718  }
719  else {
720  unsigned int minipos = sumindmini/nbmini; // position of the minimum
721 
722  valey.set((unsigned char)minipos, histogram[minipos]);
723  return true;
724  }
725 }
744 unsigned
745 vpHistogram::getValey(unsigned char dist,
746  const vpHistogramPeak & peak,
747  vpHistogramValey & valeyl,
748  vpHistogramValey & valeyr)
749 {
750  unsigned int ret = 0x11;
751  unsigned int nbmini; // Minimum numbers
752  unsigned int sumindmini; // Sum
753  unsigned int mini; // current minimum
754  vpHistogramPeak peakr, peakl; // Left and right peaks of peak
755  std::list<vpHistogramPeak> peaks; // list of histogram peaks
756  // unsigned int nbpeaks=0; // Number of peaks in the histogram (ie local maxima)
757 
758  if (peak.getLevel() == 0) {
759  valeyl.set(0, 0);
760  ret &= 0x01;
761  }
762  if (peak.getLevel() == size -1) {
763  valeyr.set((unsigned char)(size-1), 0);
764  ret &= 0x10;
765  }
766 
767  if (ret >> 1) // consider the left part of the requested peak
768  {
769  // If the list of peaks is empty, compute it
770  if (peaks.empty())
771  {
772  /* nbpeaks = */ getPeaks(peaks);
773  }
774 
775  // if (1) {
776  // // vpTRACE("nb peaks: %d", nbpeaks);
777  // peaks.front();
778  // for (unsigned i=0; i < nbpeaks; i ++) {
779  // vpHistogramPeak p = peaks.value();
780  // // vpTRACE("peak index %d: pos %d value: %d",
781  // // i, p.getLevel(), p.getValue());
782  // peaks.next();
783  // }
784  // }
785  // Go to the requested peak in the list
786  std::list<vpHistogramPeak>::const_iterator it;
787  unsigned index = 0;
788  for (it = peaks.begin(); it != peaks.end(); ++ it)
789  {
790  if (peak == *it) {
791  // we are on the peak.
792  break;
793  }
794  index ++;
795  }
796 
797  bool found = false;
798  if (index == 0) {
799  // No chance to get a peak on the left
800  // should not occur !
801  peakl.set(0,0);
802  }
803  else {
804  // search for the nearest peak on the left that matches the distance
805  std::list<vpHistogramPeak>::const_iterator lit; // left iterator
806  for(lit = peaks.begin(); lit != it; ++ lit)
807  {
808  if (abs((*lit).getLevel() - peak.getLevel()) > dist) {
809  // peakl found
810  peakl = *lit;
811  found = true; // we cannot stop here, since the other peaks on the right may exist
812  }
813  }
814  }
815  if ( ! found)
816  peakl.set(0,0);
817 
818  // Search the valey on the left
819  mini = peak.getValue();
820  sumindmini=0;
821  nbmini=0;
822  for (unsigned i=peakl.getLevel(); i < peak.getLevel(); i++) {
823  if (histogram[i] < mini) {
824  mini=histogram[i];
825  nbmini=1;
826  sumindmini=i;
827  continue;
828  }
829  if (histogram[i] == mini) {
830  sumindmini += i;
831  nbmini ++;
832  }
833  }
834  if (nbmini == 0) {
835  valeyl.set(0, 0);
836  ret &= 0x01;
837  }
838  else {
839  unsigned int minipos = sumindmini/nbmini; // position of the minimum
840  valeyl.set((unsigned char)minipos, histogram[minipos]);
841  ret &= 0x11;
842  }
843  }
844 
845  if (ret << 1) {
846  // If the list of peaks is empty, compute it
847  if (peaks.empty()) {
848  /* nbpeaks = */ getPeaks(peaks);
849  }
850  // Go to the requested peak in the list
851  std::list<vpHistogramPeak>::const_iterator it;
852  unsigned index = 0;
853  for (it = peaks.begin(); it != peaks.end(); ++ it)
854  {
855  if (peak == *it) {
856  // we are on the peak.
857  break;
858  }
859  index ++;
860  }
861 
862  bool found = false;
863  // search for the nearest peak on the right that matches the distance
864  std::list<vpHistogramPeak>::const_iterator rit; // right iterator
865  for(rit = it; rit != peaks.end(); ++ rit)
866 
867  if (abs((*rit).getLevel() - peak.getLevel()) > dist) {
868  // peakr found
869  peakr = *rit;
870  found = true;
871  break; // we can stop here
872  }
873 
874  if ( ! found)
875  peakr.set((unsigned char)(size-1),0);
876 
877  // Search the valey on the right
878  mini = peak.getValue();
879  sumindmini=0;
880  nbmini=0;
881  for (unsigned i=(unsigned int)peak.getLevel()+1; i <= (unsigned int)peakr.getLevel(); i++) {
882  if (histogram[i] < mini) {
883  mini=histogram[i];
884  nbmini=1;
885  sumindmini=i;
886  continue;
887  }
888  if (histogram[i] == mini) {
889  sumindmini += i;
890  nbmini ++;
891  }
892  }
893  if (nbmini == 0) {
894  valeyr.set((unsigned char)(size-1), 0);
895  ret &= 0x10;
896  }
897  else {
898  unsigned int minipos = sumindmini/nbmini; // position of the minimum
899  valeyr.set((unsigned char)minipos, histogram[minipos]);
900  ret &= 0x11;
901  }
902  }
903 
904  return ret;
905 }
906 
915 unsigned vpHistogram::sort(std::list<vpHistogramPeak> & peaks)
916 {
917 
918  if ( peaks.empty() ) {
919  return 0;
920  }
921 
922  peaks.sort(compare_vpHistogramPeak);
923 
924  return (unsigned int)peaks.size();
925 }
926 
939 bool
940 vpHistogram::write(const std::string &filename)
941 {
942  return ( this->write(filename.c_str()) );
943 }
944 
957 bool
958 vpHistogram::write(const char *filename)
959 {
960  std::string opath;
961 
962  FILE *fd = fopen(filename, "w");
963  if (fd == NULL)
964  return false;
965  for (unsigned i=0; i < size; i ++)
966  fprintf(fd, "%d %d\n", i, histogram[i]);
967  fclose(fd);
968 
969  return true;
970 }
971 
972 /*
973  * Local variables:
974  * c-basic-offset: 2
975  * End:
976  */
unsigned getPeaks(std::list< vpHistogramPeak > &peaks)
virtual ~vpHistogram()
Definition: vpHistogram.cpp:99
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
Definition: vpImage.h:161
unsigned getValue() const
Type * bitmap
points toward the bitmap
Definition: vpImage.h:116
#define vpERROR_TRACE
Definition: vpDebug.h:391
vpHistogram & operator=(const vpHistogram &h)
Class to define colors available for display functionnalities.
Definition: vpColor.h:121
error that can be emited by ViSP classes.
Definition: vpException.h:73
Class to compute a gray level image histogram.
Definition: vpHistogram.h:113
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)
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
Definition: vpImage.h:152
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
Declaration of the valey (minimum value) in a gray level image histogram.
unsigned getValey(std::list< vpHistogramValey > &valey)
void calculate(const vpImage< unsigned char > &I, const unsigned int nbins=256)