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) {}
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 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));
409 if (histogram == NULL) {
417 int hsize = (int)fsize / 2;
419 for (
unsigned i = 0; i < size; i++) {
420 unsigned int sum = 0;
422 for (
int j = -hsize; j <= hsize; j++) {
424 if ( (i + (
unsigned int)j) < size) {
425 sum += h.histogram[i + (
unsigned int)j];
429 histogram[i] = sum / nb;
449 if (histogram == NULL) {
462 unsigned sum_level = 0;
466 for (
unsigned i = 0; i < size - 1; i++) {
467 int next_slope = (int)histogram[i + 1] - (
int)histogram[i];
475 if ((prev_slope > 0) && (next_slope == 0)) {
482 if ((prev_slope > 0) && (next_slope < 0)) {
486 unsigned int level = sum_level / cpt;
487 p.
set((
unsigned char)level, histogram[level]);
494 prev_slope = next_slope;
498 if (prev_slope > 0) {
499 p.
set((
unsigned char)size - 1u, histogram[size - 1]);
527 std::list<vpHistogramPeak> peaks;
540 peak1 = peaks.front();
547 peak1 = peaks.front();
548 for (std::list<vpHistogramPeak>::const_iterator it = peaks.begin(); it != peaks.end(); ++it) {
581 unsigned index_highest_peak;
582 unsigned index_second_peak;
585 unsigned int maxprof;
587 unsigned int sumindmini;
589 unsigned int nbpeaks;
595 peak =
new unsigned char[size];
600 for (
unsigned i = 0; i < size - 1; i++) {
601 int next_slope = (int)histogram[i + 1] - (
int)histogram[i];
605 if ((prev_slope > 0) && (next_slope < 0))
606 peak[nbpeaks++] = (
unsigned char)i;
608 prev_slope = next_slope;
611 peak[nbpeaks++] = (
unsigned char)(size - 1);
619 index_highest_peak = 0;
620 for (
unsigned int i = 0; i < nbpeaks; i++) {
621 if (histogram[peak[i]] > histogram[peak[index_highest_peak]]) {
622 index_highest_peak = i;
631 index_second_peak = index_highest_peak;
634 for (
unsigned i = 0; i < index_highest_peak; i++) {
635 if (peak[index_highest_peak] - peak[i] > dist) {
637 for (
int j = peak[i]; j <= peak[index_highest_peak] - dist; j++)
638 if ((histogram[peak[i]] - histogram[j]) > prof)
639 prof = histogram[peak[i]] - histogram[j];
641 if (prof > maxprof) {
643 index_second_peak = i;
649 for (
unsigned i = index_highest_peak + 1; i < nbpeaks; i++) {
650 if (peak[i] - peak[index_highest_peak] > dist) {
652 for (
int j = peak[index_highest_peak] + dist; j <= peak[i]; j++)
653 if ((histogram[peak[i]] - histogram[j]) > prof)
654 prof = histogram[peak[i]] - histogram[j];
656 if (prof > maxprof) {
658 index_second_peak = i;
667 if (peak[index_highest_peak] < peak[index_second_peak]) {
668 peakr.
set(peak[index_second_peak], histogram[peak[index_second_peak]]);
669 peakl.
set(peak[index_highest_peak], histogram[peak[index_highest_peak]]);
671 peakl.
set(peak[index_second_peak], histogram[peak[index_second_peak]]);
672 peakr.
set(peak[index_highest_peak], histogram[peak[index_highest_peak]]);
675 if (peakl == peakr) {
687 if (histogram[i] < mini) {
693 if (histogram[i] == mini) {
710 mini = sumindmini / nbmini;
711 valey.
set((
unsigned char)mini, histogram[mini]);
732 if (histogram == NULL) {
745 unsigned sum_level = 0;
749 for (
unsigned i = 0; i < size - 1; i++) {
750 int next_slope = (int)histogram[i + 1] - (
int)histogram[i];
752 if ((prev_slope < 0) && (next_slope == 0)) {
759 if ((prev_slope < 0) && (next_slope > 0)) {
763 unsigned int level = sum_level / cpt;
764 p.
set((
unsigned char)level, histogram[level]);
771 prev_slope = next_slope;
775 if (prev_slope < 0) {
776 p.
set((
unsigned char)size - 1u, histogram[size - 1]);
814 unsigned int sumindmini;
821 if (histogram[i] < mini) {
827 if (histogram[i] == mini) {
839 unsigned int minipos = sumindmini / nbmini;
841 valey.
set((
unsigned char)minipos, histogram[minipos]);
866 unsigned int ret = 0x11;
868 unsigned int sumindmini;
871 std::list<vpHistogramPeak> peaks;
880 valeyr.
set((
unsigned char)(size - 1), 0);
902 std::list<vpHistogramPeak>::const_iterator it;
904 for (it = peaks.begin(); it != peaks.end(); ++it) {
919 std::list<vpHistogramPeak>::const_iterator lit;
920 for (lit = peaks.begin(); lit != it; ++lit) {
921 if (abs((*lit).getLevel() - peak.
getLevel()) > dist) {
937 if (histogram[i] < mini) {
943 if (histogram[i] == mini) {
952 unsigned int minipos = sumindmini / nbmini;
953 valeyl.
set((
unsigned char)minipos, histogram[minipos]);
964 std::list<vpHistogramPeak>::const_iterator it;
966 for (it = peaks.begin(); it != peaks.end(); ++it) {
976 std::list<vpHistogramPeak>::const_iterator rit;
977 for (rit = it; rit != peaks.end(); ++rit)
979 if (abs((*rit).getLevel() - peak.
getLevel()) > dist) {
987 peakr.
set((
unsigned char)(size - 1), 0);
993 for (
unsigned i = (
unsigned int)peak.
getLevel() + 1; i <= (
unsigned int)peakr.
getLevel(); i++) {
994 if (histogram[i] < mini) {
1000 if (histogram[i] == mini) {
1006 valeyr.
set((
unsigned char)(size - 1), 0);
1009 unsigned int minipos = sumindmini / nbmini;
1010 valeyr.
set((
unsigned char)minipos, histogram[minipos]);
1029 if (peaks.empty()) {
1033 peaks.sort(compare_vpHistogramPeak);
1035 return (
unsigned int)peaks.size();
1066 FILE *fd = fopen(filename,
"w");
1069 for (
unsigned i = 0; i < size; i++)
1070 fprintf(fd,
"%u %u\n", i, histogram[i]);
Class to define RGB colors available for display functionnalities.
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
error that can be emited by ViSP classes.
@ divideByZeroError
Division by zero.
Declaration of the peak (maximum value) in a gray level image histogram.
void set(unsigned char lvl, unsigned val)
unsigned getValue() const
unsigned char getLevel() const
Declaration of the valey (minimum value) in a gray level image histogram.
void set(unsigned char lvl, unsigned val)
Class to compute a gray level image histogram.
unsigned getPeaks(std::list< vpHistogramPeak > &peaks)
void smooth(unsigned int fsize=3)
void calculate(const vpImage< unsigned char > &I, unsigned int nbins=256, unsigned int nbThreads=1)
vpHistogram & operator=(const vpHistogram &h)
unsigned sort(std::list< vpHistogramPeak > &peaks)
unsigned getValey(std::list< vpHistogramValey > &valey)
bool write(const std::string &filename)
void display(const vpImage< unsigned char > &I, const vpColor &color=vpColor::white, unsigned int thickness=2, unsigned int maxValue_=0)
Error that can be emited by the vpImage class and its derivates.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getWidth() const
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const