Visual Servoing Platform  version 3.2.1 under development (2019-05-26)
vpImage.h
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Image handling.
33  *
34  * Authors:
35  * Eric Marchand
36  *
37  *****************************************************************************/
38 
44 #ifndef vpImage_H
45 #define vpImage_H
46 
47 #include <visp3/core/vpConfig.h>
48 #include <visp3/core/vpDebug.h>
49 #include <visp3/core/vpException.h>
50 #include <visp3/core/vpImageException.h>
51 #include <visp3/core/vpImagePoint.h>
52 #include <visp3/core/vpRGBa.h>
53 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
54 #include <visp3/core/vpThread.h>
55 #endif
56 
57 #include <fstream>
58 #include <iomanip> // std::setw
59 #include <iostream>
60 #include <math.h>
61 #include <string.h>
62 #include <inttypes.h>
63 
64 class vpDisplay;
65 
116 // Ref: http://en.cppreference.com/w/cpp/language/friend#Template_friends
117 template <class Type> class vpImage; // forward declare to make function declaration possible
118 
119 // declarations
120 template <class Type> std::ostream &operator<<(std::ostream &, const vpImage<Type> &);
121 
122 std::ostream &operator<<(std::ostream &, const vpImage<unsigned char> &);
123 std::ostream &operator<<(std::ostream &, const vpImage<char> &);
124 std::ostream &operator<<(std::ostream &, const vpImage<float> &);
125 std::ostream &operator<<(std::ostream &, const vpImage<double> &);
126 
127 template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second);
128 
129 template <class Type> class vpImage
130 {
131  friend class vpImageConvert;
132 
133 public:
134  Type *bitmap;
136 
138  vpImage();
140  vpImage(const vpImage<Type> &);
141 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
144 #endif
145  vpImage(unsigned int height, unsigned int width);
148  vpImage(unsigned int height, unsigned int width, Type value);
150  vpImage(Type *const array, const unsigned int height, const unsigned int width, const bool copyData = false);
152  virtual ~vpImage();
153 
156 
157  // destructor
158  void destroy();
159 
160  // Returns a new image that's double size of the current image
161  void doubleSizeImage(vpImage<Type> &res);
162 
170  inline unsigned int getCols() const { return width; }
179  inline unsigned int getHeight() const { return height; }
180 
181  // Return the maximum value within the bitmap
182  Type getMaxValue() const;
183  // Return the mean value of the bitmap
184  Type getMeanValue() const;
185  // Return the minumum value within the bitmap
186  Type getMinValue() const;
187  // Look for the minumum and the maximum value within the bitmap
188  void getMinMaxValue(Type &min, Type &max) const;
189  // Look for the minumum and the maximum value within the bitmap and get their location
190  void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal = NULL, Type *maxVal = NULL) const;
191 
200  inline unsigned int getNumberOfPixel() const { return npixels; }
201 
209  inline unsigned int getRows() const { return height; }
210 
218  inline unsigned int getSize() const { return width * height; }
219 
220  // Gets the value of a pixel at a location.
221  Type getValue(unsigned int i, unsigned int j) const;
222  // Gets the value of a pixel at a location with bilinear interpolation.
223  Type getValue(double i, double j) const;
224  // Gets the value of a pixel at a location with bilinear interpolation.
225  Type getValue(const vpImagePoint &ip) const;
226 
227  // Get image pixels sum
228  double getSum() const;
229 
237  inline unsigned int getWidth() const { return width; }
238 
239  // Returns a new image that's half size of the current image
240  void halfSizeImage(vpImage<Type> &res) const;
241 
243  void init(unsigned int height, unsigned int width);
245  void init(unsigned int height, unsigned int width, Type value);
247  void init(Type *const array, const unsigned int height, const unsigned int width, const bool copyData = false);
248  void insert(const vpImage<Type> &src, const vpImagePoint &topLeft);
249 
250  //------------------------------------------------------------------
251  // Acces to the image
252 
254  inline Type *operator[](const unsigned int i) { return row[i]; }
255  inline Type *operator[](const int i) { return row[i]; }
256 
258  inline const Type *operator[](unsigned int i) const { return row[i]; }
259  inline const Type *operator[](int i) const { return row[i]; }
260 
267  inline Type operator()(const unsigned int i, const unsigned int j) const { return bitmap[i * width + j]; }
268 
273  inline void operator()(const unsigned int i, const unsigned int j, const Type &v) { bitmap[i * width + j] = v; }
274 
285  inline Type operator()(const vpImagePoint &ip) const
286  {
287  unsigned int i = (unsigned int)ip.get_i();
288  unsigned int j = (unsigned int)ip.get_j();
289 
290  return bitmap[i * width + j];
291  }
292 
301  inline void operator()(const vpImagePoint &ip, const Type &v)
302  {
303  unsigned int i = (unsigned int)ip.get_i();
304  unsigned int j = (unsigned int)ip.get_j();
305 
306  bitmap[i * width + j] = v;
307  }
308 
310 
313 
314  vpImage<Type> &operator=(const Type &v);
315  bool operator==(const vpImage<Type> &I);
316  bool operator!=(const vpImage<Type> &I);
317  friend std::ostream &operator<< <>(std::ostream &s, const vpImage<Type> &I);
318  friend std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I);
319  friend std::ostream &operator<<(std::ostream &s, const vpImage<char> &I);
320  friend std::ostream &operator<<(std::ostream &s, const vpImage<float> &I);
321  friend std::ostream &operator<<(std::ostream &s, const vpImage<double> &I);
322 
323  // Perform a look-up table transformation
324  void performLut(const Type (&lut)[256], const unsigned int nbThreads = 1);
325 
326  // Returns a new image that's a quarter size of the current image
327  void quarterSizeImage(vpImage<Type> &res) const;
328 
329  // set the size of the image without initializing it.
330  void resize(const unsigned int h, const unsigned int w);
331  // set the size of the image and initialize it.
332  void resize(const unsigned int h, const unsigned int w, const Type &val);
333 
334  void sub(const vpImage<Type> &B, vpImage<Type> &C);
335  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
336  void subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const;
337 
338  friend void swap<>(vpImage<Type> &first, vpImage<Type> &second);
339 
341 
342 private:
343  unsigned int npixels;
344  unsigned int width;
345  unsigned int height;
346  Type **row;
347 };
348 
349 template <class Type> std::ostream &operator<<(std::ostream &s, const vpImage<Type> &I)
350 {
351  if (I.bitmap == NULL) {
352  return s;
353  }
354 
355  for (unsigned int i = 0; i < I.getHeight(); i++) {
356  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
357  s << I[i][j] << " ";
358  }
359 
360  // We don't add " " after the last column element
361  s << I[i][I.getWidth() - 1];
362 
363  // We don't add a \n character at the end of the last row line
364  if (i < I.getHeight() - 1) {
365  s << std::endl;
366  }
367  }
368 
369  return s;
370 }
371 
372 inline std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I)
373 {
374  if (I.bitmap == NULL) {
375  return s;
376  }
377 
378  std::ios_base::fmtflags original_flags = s.flags();
379 
380  for (unsigned int i = 0; i < I.getHeight(); i++) {
381  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
382  s << std::setw(3) << static_cast<unsigned>(I[i][j]) << " ";
383  }
384 
385  // We don't add " " after the last column element
386  s << std::setw(3) << static_cast<unsigned>(I[i][I.getWidth() - 1]);
387 
388  // We don't add a \n character at the end of the last row line
389  if (i < I.getHeight() - 1) {
390  s << std::endl;
391  }
392  }
393 
394  s.flags(original_flags); // restore s to standard state
395  return s;
396 }
397 
398 inline std::ostream &operator<<(std::ostream &s, const vpImage<char> &I)
399 {
400  if (I.bitmap == NULL) {
401  return s;
402  }
403 
404  std::ios_base::fmtflags original_flags = s.flags();
405 
406  for (unsigned int i = 0; i < I.getHeight(); i++) {
407  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
408  s << std::setw(4) << static_cast<int>(I[i][j]) << " ";
409  }
410 
411  // We don't add " " after the last column element
412  s << std::setw(4) << static_cast<int>(I[i][I.getWidth() - 1]);
413 
414  // We don't add a \n character at the end of the last row line
415  if (i < I.getHeight() - 1) {
416  s << std::endl;
417  }
418  }
419 
420  s.flags(original_flags); // restore s to standard state
421  return s;
422 }
423 
424 inline std::ostream &operator<<(std::ostream &s, const vpImage<float> &I)
425 {
426  if (I.bitmap == NULL) {
427  return s;
428  }
429 
430  std::ios_base::fmtflags original_flags = s.flags();
431  s.precision(9); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
432 
433  for (unsigned int i = 0; i < I.getHeight(); i++) {
434  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
435  s << I[i][j] << " ";
436  }
437 
438  // We don't add " " after the last column element
439  s << I[i][I.getWidth() - 1];
440 
441  // We don't add a \n character at the end of the last row line
442  if (i < I.getHeight() - 1) {
443  s << std::endl;
444  }
445  }
446 
447  s.flags(original_flags); // restore s to standard state
448  return s;
449 }
450 
451 inline std::ostream &operator<<(std::ostream &s, const vpImage<double> &I)
452 {
453  if (I.bitmap == NULL) {
454  return s;
455  }
456 
457  std::ios_base::fmtflags original_flags = s.flags();
458  s.precision(17); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
459 
460  for (unsigned int i = 0; i < I.getHeight(); i++) {
461  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
462  s << I[i][j] << " ";
463  }
464 
465  // We don't add " " after the last column element
466  s << I[i][I.getWidth() - 1];
467 
468  // We don't add a \n character at the end of the last row line
469  if (i < I.getHeight() - 1) {
470  s << std::endl;
471  }
472  }
473 
474  s.flags(original_flags); // restore s to standard state
475  return s;
476 }
477 
478 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
479 namespace
480 {
481 struct ImageLut_Param_t {
482  unsigned int m_start_index;
483  unsigned int m_end_index;
484 
485  unsigned char m_lut[256];
486  unsigned char *m_bitmap;
487 
488  ImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
489 
490  ImageLut_Param_t(const unsigned int start_index, const unsigned int end_index, unsigned char *bitmap)
491  : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
492  {
493  }
494 };
495 
496 vpThread::Return performLutThread(vpThread::Args args)
497 {
498  ImageLut_Param_t *imageLut_param = static_cast<ImageLut_Param_t *>(args);
499  unsigned int start_index = imageLut_param->m_start_index;
500  unsigned int end_index = imageLut_param->m_end_index;
501 
502  unsigned char *bitmap = imageLut_param->m_bitmap;
503 
504  unsigned char *ptrStart = bitmap + start_index;
505  unsigned char *ptrEnd = bitmap + end_index;
506  unsigned char *ptrCurrent = ptrStart;
507 
508  // while(ptrCurrent != ptrEnd) {
509  // *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
510  // ++ptrCurrent;
511  // }
512 
513  if (end_index - start_index >= 8) {
514  // Unroll loop version
515  for (; ptrCurrent <= ptrEnd - 8;) {
516  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
517  ++ptrCurrent;
518 
519  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
520  ++ptrCurrent;
521 
522  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
523  ++ptrCurrent;
524 
525  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
526  ++ptrCurrent;
527 
528  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
529  ++ptrCurrent;
530 
531  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
532  ++ptrCurrent;
533 
534  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
535  ++ptrCurrent;
536 
537  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
538  ++ptrCurrent;
539  }
540  }
541 
542  for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
543  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
544  }
545 
546  return 0;
547 }
548 
549 struct ImageLutRGBa_Param_t {
550  unsigned int m_start_index;
551  unsigned int m_end_index;
552 
553  vpRGBa m_lut[256];
554  unsigned char *m_bitmap;
555 
556  ImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
557 
558  ImageLutRGBa_Param_t(const unsigned int start_index, const unsigned int end_index, unsigned char *bitmap)
559  : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
560  {
561  }
562 };
563 
564 vpThread::Return performLutRGBaThread(vpThread::Args args)
565 {
566  ImageLutRGBa_Param_t *imageLut_param = static_cast<ImageLutRGBa_Param_t *>(args);
567  unsigned int start_index = imageLut_param->m_start_index;
568  unsigned int end_index = imageLut_param->m_end_index;
569 
570  unsigned char *bitmap = imageLut_param->m_bitmap;
571 
572  unsigned char *ptrStart = bitmap + start_index * 4;
573  unsigned char *ptrEnd = bitmap + end_index * 4;
574  unsigned char *ptrCurrent = ptrStart;
575 
576  if (end_index - start_index >= 4 * 2) {
577  // Unroll loop version
578  for (; ptrCurrent <= ptrEnd - 4 * 2;) {
579  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
580  ptrCurrent++;
581  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
582  ptrCurrent++;
583  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
584  ptrCurrent++;
585  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
586  ptrCurrent++;
587 
588  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
589  ptrCurrent++;
590  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
591  ptrCurrent++;
592  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
593  ptrCurrent++;
594  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
595  ptrCurrent++;
596  }
597  }
598 
599  while (ptrCurrent != ptrEnd) {
600  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
601  ptrCurrent++;
602 
603  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
604  ptrCurrent++;
605 
606  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
607  ptrCurrent++;
608 
609  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
610  ptrCurrent++;
611  }
612 
613  return 0;
614 }
615 }
616 #endif
617 
631 template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
632 {
633  init(h, w);
634 
635  // for (unsigned int i = 0; i < npixels; i++)
636  // bitmap[i] = value;
637  std::fill(bitmap, bitmap + npixels, value);
638 }
639 
657 template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w)
658 {
659  if (h != this->height) {
660  if (row != NULL) {
661  vpDEBUG_TRACE(10, "Destruction row[]");
662  delete[] row;
663  row = NULL;
664  }
665  }
666 
667  if ((h != this->height) || (w != this->width)) {
668  if (bitmap != NULL) {
669  vpDEBUG_TRACE(10, "Destruction bitmap[]");
670  delete[] bitmap;
671  bitmap = NULL;
672  }
673  }
674 
675  this->width = w;
676  this->height = h;
677 
678  npixels = width * height;
679 
680  if (bitmap == NULL)
681  bitmap = new Type[npixels];
682 
683  if (bitmap == NULL) {
684  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
685  }
686 
687  if (row == NULL)
688  row = new Type *[height];
689  if (row == NULL) {
690  throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
691  }
692 
693  for (unsigned int i = 0; i < height; i++)
694  row[i] = bitmap + i * width;
695 }
696 
710 template <class Type>
711 void vpImage<Type>::init(Type *const array, const unsigned int h, const unsigned int w, const bool copyData)
712 {
713  if (h != this->height) {
714  if (row != NULL) {
715  delete[] row;
716  row = NULL;
717  }
718  }
719 
720  // Delete bitmap if copyData==false, otherwise only if the dimension differs
721  if ((copyData && ((h != this->height) || (w != this->width))) || !copyData) {
722  if (bitmap != NULL) {
723  delete[] bitmap;
724  bitmap = NULL;
725  }
726  }
727 
728  this->width = w;
729  this->height = h;
730 
731  npixels = width * height;
732 
733  if (copyData) {
734  if (bitmap == NULL)
735  bitmap = new Type[npixels];
736 
737  if (bitmap == NULL) {
738  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
739  }
740 
741  // Copy the image data
742  memcpy(static_cast<void*>(bitmap), static_cast<void*>(array), (size_t)(npixels * sizeof(Type)));
743  } else {
744  // Copy the address of the array in the bitmap
745  bitmap = array;
746  }
747 
748  if (row == NULL)
749  row = new Type *[height];
750  if (row == NULL) {
751  throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
752  }
753 
754  for (unsigned int i = 0; i < height; i++) {
755  row[i] = bitmap + i * width;
756  }
757 }
758 
777 template <class Type>
778 vpImage<Type>::vpImage(unsigned int h, unsigned int w)
779  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
780 {
781  init(h, w, 0);
782 }
783 
801 template <class Type>
802 vpImage<Type>::vpImage(unsigned int h, unsigned int w, Type value)
803  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
804 {
805  init(h, w, value);
806 }
807 
823 template <class Type>
824 vpImage<Type>::vpImage(Type *const array, const unsigned int h, const unsigned int w, const bool copyData)
825  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
826 {
827  init(array, h, w, copyData);
828 }
829 
839 template <class Type> vpImage<Type>::vpImage() : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
840 {
841 }
842 
863 template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w) { init(h, w); }
864 
884 template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w, const Type &val) { init(h, w, val); }
885 
892 template <class Type> void vpImage<Type>::destroy()
893 {
894  // vpERROR_TRACE("Deallocate ");
895 
896  if (bitmap != NULL) {
897  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap);
898  // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap);
899  delete[] bitmap;
900  bitmap = NULL;
901  }
902 
903  if (row != NULL) {
904  // vpERROR_TRACE("Deallocate row memory %p",row);
905  // vpDEBUG_TRACE(20,"Deallocate row memory %p",row);
906  delete[] row;
907  row = NULL;
908  }
909 }
910 
917 template <class Type> vpImage<Type>::~vpImage() { destroy(); }
918 
922 template <class Type>
923 vpImage<Type>::vpImage(const vpImage<Type> &I) : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
924 {
925  resize(I.getHeight(), I.getWidth());
926  memcpy(static_cast<void*>(bitmap), static_cast<void*>(I.bitmap), I.npixels * sizeof(Type));
927 }
928 
929 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
930 
933 template <class Type>
935  : bitmap(I.bitmap), display(I.display), npixels(I.npixels), width(I.width), height(I.height), row(I.row)
936 {
937  I.bitmap = NULL;
938  I.display = NULL;
939  I.npixels = 0;
940  I.width = 0;
941  I.height = 0;
942  I.row = NULL;
943 }
944 #endif
945 
951 template <class Type> Type vpImage<Type>::getMaxValue() const
952 {
953  if (npixels == 0)
954  throw(vpException(vpException::fatalError, "Cannot compute maximum value of an empty image"));
955  Type m = bitmap[0];
956  for (unsigned int i = 0; i < npixels; i++) {
957  if (bitmap[i] > m)
958  m = bitmap[i];
959  }
960  return m;
961 }
962 
966 template <class Type> Type vpImage<Type>::getMeanValue() const
967 {
968  if ((height == 0) || (width == 0))
969  return 0.0;
970 
971  return getSum() / (height * width);
972 }
973 
979 template <class Type> Type vpImage<Type>::getMinValue() const
980 {
981  if (npixels == 0)
982  throw(vpException(vpException::fatalError, "Cannot compute minimum value of an empty image"));
983  Type m = bitmap[0];
984  for (unsigned int i = 0; i < npixels; i++)
985  if (bitmap[i] < m)
986  m = bitmap[i];
987  return m;
988 }
989 
997 template <class Type> void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
998 {
999  if (npixels == 0)
1000  throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
1001 
1002  min = max = bitmap[0];
1003  for (unsigned int i = 0; i < npixels; i++) {
1004  if (bitmap[i] < min)
1005  min = bitmap[i];
1006  if (bitmap[i] > max)
1007  max = bitmap[i];
1008  }
1009 }
1010 
1032 template <class Type>
1033 void vpImage<Type>::getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal, Type *maxVal) const
1034 {
1035  if (npixels == 0)
1036  throw(vpException(vpException::fatalError, "Cannot get location of minimum/maximum "
1037  "values of an empty image"));
1038 
1039  Type min = bitmap[0], max = bitmap[0];
1040  vpImagePoint minLoc_, maxLoc_;
1041  for (unsigned int i = 0; i < height; i++) {
1042  for (unsigned int j = 0; j < width; j++) {
1043  if (row[i][j] < min) {
1044  min = row[i][j];
1045  minLoc_.set_ij(i, j);
1046  }
1047 
1048  if (row[i][j] > max) {
1049  max = row[i][j];
1050  maxLoc_.set_ij(i, j);
1051  }
1052  }
1053  }
1054 
1055  if (minLoc != NULL)
1056  *minLoc = minLoc_;
1057 
1058  if (maxLoc != NULL)
1059  *maxLoc = maxLoc_;
1060 
1061  if (minVal != NULL)
1062  *minVal = min;
1063 
1064  if (maxVal != NULL)
1065  *maxVal = max;
1066 }
1067 
1072 {
1073  swap(*this, other);
1074  // Swap back display pointer if it was not null
1075  // vpImage<unsigned char> I2(480, 640);
1076  // vpDisplayX d(I2);
1077  // I2 = I1; //copy only the data
1078  if (other.display != NULL)
1079  display = other.display;
1080 
1081  return *this;
1082 }
1083 
1090 template <class Type> vpImage<Type> &vpImage<Type>::operator=(const Type &v)
1091 {
1092  for (unsigned int i = 0; i < npixels; i++)
1093  bitmap[i] = v;
1094 
1095  return *this;
1096 }
1097 
1103 template <class Type> bool vpImage<Type>::operator==(const vpImage<Type> &I)
1104 {
1105  if (this->width != I.getWidth())
1106  return false;
1107  if (this->height != I.getHeight())
1108  return false;
1109 
1110  // printf("wxh: %dx%d bitmap: %p I.bitmap %p\n", width, height, bitmap,
1111  // I.bitmap);
1112  for (unsigned int i = 0; i < npixels; i++) {
1113  if (bitmap[i] != I.bitmap[i]) {
1114  // std::cout << "differ for pixel " << i << " (" << i%this->height
1115  // << ", " << i - i%this->height << ")" << std::endl;
1116  return false;
1117  }
1118  }
1119  return true;
1120 }
1126 template <class Type> bool vpImage<Type>::operator!=(const vpImage<Type> &I)
1127 {
1128  return !(*this == I);
1129 }
1130 
1157 {
1158  vpImage<Type> C;
1159  sub(*this, B, C);
1160  return C;
1161 }
1162 
1174 template <class Type> void vpImage<Type>::insert(const vpImage<Type> &src, const vpImagePoint &topLeft)
1175 {
1176  int itl = (int)topLeft.get_i();
1177  int jtl = (int)topLeft.get_j();
1178 
1179  int dest_ibegin = 0;
1180  int dest_jbegin = 0;
1181  int src_ibegin = 0;
1182  int src_jbegin = 0;
1183  int dest_w = (int)this->getWidth();
1184  int dest_h = (int)this->getHeight();
1185  int src_w = (int)src.getWidth();
1186  int src_h = (int)src.getHeight();
1187  int wsize = (int)src.getWidth();
1188  int hsize = (int)src.getHeight();
1189 
1190  if (itl >= dest_h || jtl >= dest_w)
1191  return;
1192 
1193  if (itl < 0)
1194  src_ibegin = -itl;
1195  else
1196  dest_ibegin = itl;
1197 
1198  if (jtl < 0)
1199  src_jbegin = -jtl;
1200  else
1201  dest_jbegin = jtl;
1202 
1203  if (src_w - src_jbegin > dest_w - dest_jbegin)
1204  wsize = dest_w - dest_jbegin;
1205  else
1206  wsize = src_w - src_jbegin;
1207 
1208  if (src_h - src_ibegin > dest_h - dest_ibegin)
1209  hsize = dest_h - dest_ibegin;
1210  else
1211  hsize = src_h - src_ibegin;
1212 
1213  for (int i = 0; i < hsize; i++) {
1214  Type *srcBitmap = src.bitmap + ((src_ibegin + i) * src_w + src_jbegin);
1215  Type *destBitmap = this->bitmap + ((dest_ibegin + i) * dest_w + dest_jbegin);
1216 
1217  memcpy(static_cast<void*>(destBitmap), static_cast<void*>(srcBitmap), (size_t)wsize * sizeof(Type));
1218  }
1219 }
1220 
1251 template <class Type> void vpImage<Type>::halfSizeImage(vpImage<Type> &res) const
1252 {
1253  unsigned int h = height / 2;
1254  unsigned int w = width / 2;
1255  res.resize(h, w);
1256  for (unsigned int i = 0; i < h; i++)
1257  for (unsigned int j = 0; j < w; j++)
1258  res[i][j] = (*this)[i << 1][j << 1];
1259 }
1260 
1278 template <class Type>
1279 void vpImage<Type>::subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const
1280 {
1281  unsigned int h = height / v_scale;
1282  unsigned int w = width / h_scale;
1283  sampled.resize(h, w);
1284  for (unsigned int i = 0; i < h; i++)
1285  for (unsigned int j = 0; j < w; j++)
1286  sampled[i][j] = (*this)[i * v_scale][j * h_scale];
1287 }
1288 
1311 template <class Type> void vpImage<Type>::quarterSizeImage(vpImage<Type> &res) const
1312 {
1313  unsigned int h = height / 4;
1314  unsigned int w = width / 4;
1315  res.resize(h, w);
1316  for (unsigned int i = 0; i < h; i++)
1317  for (unsigned int j = 0; j < w; j++)
1318  res[i][j] = (*this)[i << 2][j << 2];
1319 }
1320 
1353 template <class Type> void vpImage<Type>::doubleSizeImage(vpImage<Type> &res)
1354 {
1355  int h = height * 2;
1356  int w = width * 2;
1357 
1358  res.resize(h, w);
1359 
1360  for (int i = 0; i < h; i++)
1361  for (int j = 0; j < w; j++)
1362  res[i][j] = (*this)[i >> 1][j >> 1];
1363 
1364  /*
1365  A B C
1366  E F G
1367  H I J
1368  A C H J are pixels from original image
1369  B E G I are interpolated pixels
1370  */
1371 
1372  // interpolate pixels B and I
1373  for (int i = 0; i < h; i += 2)
1374  for (int j = 1; j < w - 1; j += 2)
1375  res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1]));
1376 
1377  // interpolate pixels E and G
1378  for (int i = 1; i < h - 1; i += 2)
1379  for (int j = 0; j < w; j += 2)
1380  res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[(i >> 1) + 1][j >> 1]));
1381 
1382  // interpolate pixel F
1383  for (int i = 1; i < h - 1; i += 2)
1384  for (int j = 1; j < w - 1; j += 2)
1385  res[i][j] = (Type)(0.25 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1] +
1386  (*this)[(i >> 1) + 1][j >> 1] + (*this)[(i >> 1) + 1][(j >> 1) + 1]));
1387 }
1388 
1402 template <class Type> inline Type vpImage<Type>::getValue(unsigned int i, unsigned int j) const
1403 {
1404  if (i >= height || j >= width) {
1405  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1406  }
1407 
1408  return row[i][j];
1409 }
1410 
1428 template <class Type> Type vpImage<Type>::getValue(double i, double j) const
1429 {
1430  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1431  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1432  }
1433  if (height * width == 0) {
1434  throw vpException(vpImageException::notInitializedError, "Empty image!");
1435  }
1436 
1437  unsigned int iround = static_cast<unsigned int>(floor(i));
1438  unsigned int jround = static_cast<unsigned int>(floor(j));
1439 
1440  double rratio = i - static_cast<double>(iround);
1441  double cratio = j - static_cast<double>(jround);
1442 
1443  double rfrac = 1.0 - rratio;
1444  double cfrac = 1.0 - cratio;
1445 
1446  unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1447  unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1448 
1449  double value = (static_cast<double>(row[iround][jround]) * rfrac + static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1450  (static_cast<double>(row[iround][jround_1]) * rfrac + static_cast<double>(row[iround_1][jround_1]) * rratio) * cratio;
1451 
1452  return static_cast<Type>(vpMath::round(value));
1453 }
1454 
1471 template <> inline double vpImage<double>::getValue(double i, double j) const
1472 {
1473  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1474  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1475  }
1476  if (height * width == 0) {
1477  throw vpException(vpImageException::notInitializedError, "Empty image!");
1478  }
1479 
1480  unsigned int iround = static_cast<unsigned int>(floor(i));
1481  unsigned int jround = static_cast<unsigned int>(floor(j));
1482 
1483  double rratio = i - static_cast<double>(iround);
1484  double cratio = j - static_cast<double>(jround);
1485 
1486  double rfrac = 1.0 - rratio;
1487  double cfrac = 1.0 - cratio;
1488 
1489  unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1490  unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1491 
1492  return (row[iround][jround] * rfrac + row[iround_1][jround] * rratio) * cfrac +
1493  (row[iround][jround_1] * rfrac + row[iround_1][jround_1] * rratio) * cratio;
1494 }
1495 
1496 template <> inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const {
1497  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1498  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1499  }
1500  if (height * width == 0) {
1501  throw vpException(vpImageException::notInitializedError, "Empty image!");
1502  }
1503 
1504  //Fixed-point arithmetic
1505  const int precision = 1 << 16;
1506  int64_t y = static_cast<int64_t>(i * precision);
1507  int64_t x = static_cast<int64_t>(j * precision);
1508 
1509  int64_t iround = y & (~0xFFFF);
1510  int64_t jround = x & (~0xFFFF);
1511 
1512  int64_t rratio = y - iround;
1513  int64_t cratio = x - jround;
1514 
1515  int64_t rfrac = precision - rratio;
1516  int64_t cfrac = precision - cratio;
1517 
1518  int64_t x_ = x >> 16;
1519  int64_t y_ = y >> 16;
1520 
1521  if (y_ + 1 < height && x_ + 1 < width) {
1522  uint16_t up = *reinterpret_cast<uint16_t *>(bitmap + y_ * width + x_);
1523  uint16_t down = *reinterpret_cast<uint16_t *>(bitmap + (y_ + 1) * width + x_);
1524 
1525  return static_cast<unsigned char>((((up & 0x00FF) * rfrac + (down & 0x00FF) * rratio) * cfrac +
1526  ((up >> 8) * rfrac + (down >> 8) * rratio) * cratio) >> 32);
1527  } else if (y_ + 1 < height) {
1528  return static_cast<unsigned char>(((row[y_][x_] * rfrac + row[y_ + 1][x_] * rratio)) >> 16);
1529  } else if (x_ + 1 < width) {
1530  uint16_t up = *reinterpret_cast<uint16_t *>(bitmap + y_ * width + x_);
1531  return static_cast<unsigned char>(((up & 0x00FF) * cfrac + (up >> 8) * cratio) >> 16);
1532  } else {
1533  return row[y_][x_];
1534  }
1535 }
1536 
1537 template <> inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1538 {
1539  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1540  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1541  }
1542  if (height * width == 0) {
1543  throw vpException(vpImageException::notInitializedError, "Empty image!");
1544  }
1545 
1546  unsigned int iround = static_cast<unsigned int>(floor(i));
1547  unsigned int jround = static_cast<unsigned int>(floor(j));
1548 
1549  double rratio = i - static_cast<double>(iround);
1550  double cratio = j - static_cast<double>(jround);
1551 
1552  double rfrac = 1.0 - rratio;
1553  double cfrac = 1.0 - cratio;
1554 
1555  unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1556  unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1557 
1558  double valueR = (static_cast<double>(row[iround][jround].R) * rfrac + static_cast<double>(row[iround_1][jround].R) * rratio) * cfrac +
1559  (static_cast<double>(row[iround][jround_1].R) * rfrac + static_cast<double>(row[iround_1][jround_1].R) * rratio) * cratio;
1560  double valueG = (static_cast<double>(row[iround][jround].G) * rfrac + static_cast<double>(row[iround_1][jround].G) * rratio) * cfrac +
1561  (static_cast<double>(row[iround][jround_1].G) * rfrac + static_cast<double>(row[iround_1][jround_1].G) * rratio) * cratio;
1562  double valueB = (static_cast<double>(row[iround][jround].B) * rfrac + static_cast<double>(row[iround_1][jround].B) * rratio) * cfrac +
1563  (static_cast<double>(row[iround][jround_1].B) * rfrac + static_cast<double>(row[iround_1][jround_1].B) * rratio) * cratio;
1564 
1565  return vpRGBa(static_cast<unsigned char>(vpMath::round(valueR)),
1566  static_cast<unsigned char>(vpMath::round(valueG)),
1567  static_cast<unsigned char>(vpMath::round(valueB)));
1568 }
1569 
1586 template <class Type> inline Type vpImage<Type>::getValue(const vpImagePoint &ip) const
1587 {
1588  return getValue(ip.get_i(), ip.get_j());
1589 }
1590 
1591 template <> inline double vpImage<double>::getValue(const vpImagePoint &ip) const
1592 {
1593  return getValue(ip.get_i(), ip.get_j());
1594 }
1595 
1596 template <> inline unsigned char vpImage<unsigned char>::getValue(const vpImagePoint &ip) const
1597 {
1598  return getValue(ip.get_i(), ip.get_j());
1599 }
1600 
1601 template <> inline vpRGBa vpImage<vpRGBa>::getValue(const vpImagePoint &ip) const
1602 {
1603  return getValue(ip.get_i(), ip.get_j());
1604 }
1605 
1609 template <class Type> inline double vpImage<Type>::getSum() const
1610 {
1611  if ((height == 0) || (width == 0))
1612  return 0.0;
1613 
1614  double res = 0.0;
1615  for (unsigned int i = 0; i < height * width; ++i) {
1616  res += static_cast<double>(bitmap[i]);
1617  }
1618  return res;
1619 }
1620 
1650 template <class Type> void vpImage<Type>::sub(const vpImage<Type> &B, vpImage<Type> &C)
1651 {
1652 
1653  try {
1654  if ((this->getHeight() != C.getHeight()) || (this->getWidth() != C.getWidth()))
1655  C.resize(this->getHeight(), this->getWidth());
1656  } catch (const vpException &me) {
1657  std::cout << me << std::endl;
1658  throw;
1659  }
1660 
1661  if ((this->getWidth() != B.getWidth()) || (this->getHeight() != B.getHeight())) {
1662  throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage substraction "));
1663  }
1664 
1665  for (unsigned int i = 0; i < this->getWidth() * this->getHeight(); i++) {
1666  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i);
1667  }
1668 }
1669 
1681 template <class Type> void vpImage<Type>::sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C)
1682 {
1683 
1684  try {
1685  if ((A.getHeight() != C.getHeight()) || (A.getWidth() != C.getWidth()))
1686  C.resize(A.getHeight(), A.getWidth());
1687  } catch (const vpException &me) {
1688  std::cout << me << std::endl;
1689  throw;
1690  }
1691 
1692  if ((A.getWidth() != B.getWidth()) || (A.getHeight() != B.getHeight())) {
1693  throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage substraction "));
1694  }
1695 
1696  for (unsigned int i = 0; i < A.getWidth() * A.getHeight(); i++) {
1697  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i);
1698  }
1699 }
1700 
1711 template <class Type> void vpImage<Type>::performLut(const Type (&)[256], const unsigned int)
1712 {
1713  std::cerr << "Not implemented !" << std::endl;
1714 }
1715 
1724 template <>
1725 inline void vpImage<unsigned char>::performLut(const unsigned char (&lut)[256], const unsigned int nbThreads)
1726 {
1727  unsigned int size = getWidth() * getHeight();
1728  unsigned char *ptrStart = (unsigned char *)bitmap;
1729  unsigned char *ptrEnd = ptrStart + size;
1730  unsigned char *ptrCurrent = ptrStart;
1731 
1732  bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1733 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1734  use_single_thread = true;
1735 #endif
1736 
1737  if (!use_single_thread && getSize() <= nbThreads) {
1738  use_single_thread = true;
1739  }
1740 
1741  if (use_single_thread) {
1742  // Single thread
1743 
1744  while (ptrCurrent != ptrEnd) {
1745  *ptrCurrent = lut[*ptrCurrent];
1746  ++ptrCurrent;
1747  }
1748  } else {
1749 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1750  // Multi-threads
1751 
1752  std::vector<vpThread *> threadpool;
1753  std::vector<ImageLut_Param_t *> imageLutParams;
1754 
1755  unsigned int image_size = getSize();
1756  unsigned int step = image_size / nbThreads;
1757  unsigned int last_step = image_size - step * (nbThreads - 1);
1758 
1759  for (unsigned int index = 0; index < nbThreads; index++) {
1760  unsigned int start_index = index * step;
1761  unsigned int end_index = (index + 1) * step;
1762 
1763  if (index == nbThreads - 1) {
1764  end_index = start_index + last_step;
1765  }
1766 
1767  ImageLut_Param_t *imageLut_param = new ImageLut_Param_t(start_index, end_index, bitmap);
1768  memcpy(imageLut_param->m_lut, lut, 256 * sizeof(unsigned char));
1769 
1770  imageLutParams.push_back(imageLut_param);
1771 
1772  // Start the threads
1773  vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutThread, (vpThread::Args)imageLut_param);
1774  threadpool.push_back(imageLut_thread);
1775  }
1776 
1777  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1778  // Wait until thread ends up
1779  threadpool[cpt]->join();
1780  }
1781 
1782  // Delete
1783  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1784  delete threadpool[cpt];
1785  }
1786 
1787  for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1788  delete imageLutParams[cpt];
1789  }
1790 #endif
1791  }
1792 }
1793 
1802 template <> inline void vpImage<vpRGBa>::performLut(const vpRGBa (&lut)[256], const unsigned int nbThreads)
1803 {
1804  unsigned int size = getWidth() * getHeight();
1805  unsigned char *ptrStart = (unsigned char *)bitmap;
1806  unsigned char *ptrEnd = ptrStart + size * 4;
1807  unsigned char *ptrCurrent = ptrStart;
1808 
1809  bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1810 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1811  use_single_thread = true;
1812 #endif
1813 
1814  if (!use_single_thread && getSize() <= nbThreads) {
1815  use_single_thread = true;
1816  }
1817 
1818  if (use_single_thread) {
1819  // Single thread
1820  while (ptrCurrent != ptrEnd) {
1821  *ptrCurrent = lut[*ptrCurrent].R;
1822  ++ptrCurrent;
1823 
1824  *ptrCurrent = lut[*ptrCurrent].G;
1825  ++ptrCurrent;
1826 
1827  *ptrCurrent = lut[*ptrCurrent].B;
1828  ++ptrCurrent;
1829 
1830  *ptrCurrent = lut[*ptrCurrent].A;
1831  ++ptrCurrent;
1832  }
1833  } else {
1834 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1835  // Multi-threads
1836  std::vector<vpThread *> threadpool;
1837  std::vector<ImageLutRGBa_Param_t *> imageLutParams;
1838 
1839  unsigned int image_size = getSize();
1840  unsigned int step = image_size / nbThreads;
1841  unsigned int last_step = image_size - step * (nbThreads - 1);
1842 
1843  for (unsigned int index = 0; index < nbThreads; index++) {
1844  unsigned int start_index = index * step;
1845  unsigned int end_index = (index + 1) * step;
1846 
1847  if (index == nbThreads - 1) {
1848  end_index = start_index + last_step;
1849  }
1850 
1851  ImageLutRGBa_Param_t *imageLut_param = new ImageLutRGBa_Param_t(start_index, end_index, (unsigned char *)bitmap);
1852  memcpy(imageLut_param->m_lut, lut, 256 * sizeof(vpRGBa));
1853 
1854  imageLutParams.push_back(imageLut_param);
1855 
1856  // Start the threads
1857  vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutRGBaThread, (vpThread::Args)imageLut_param);
1858  threadpool.push_back(imageLut_thread);
1859  }
1860 
1861  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1862  // Wait until thread ends up
1863  threadpool[cpt]->join();
1864  }
1865 
1866  // Delete
1867  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1868  delete threadpool[cpt];
1869  }
1870 
1871  for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1872  delete imageLutParams[cpt];
1873  }
1874 #endif
1875  }
1876 }
1877 
1878 template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second)
1879 {
1880  using std::swap;
1881  swap(first.bitmap, second.bitmap);
1882  swap(first.display, second.display);
1883  swap(first.npixels, second.npixels);
1884  swap(first.width, second.width);
1885  swap(first.height, second.height);
1886  swap(first.row, second.row);
1887 }
1888 
1889 #endif
void quarterSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1311
unsigned int getCols() const
Definition: vpImage.h:170
vpDisplay * display
Definition: vpImage.h:135
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1353
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:171
void * Return
Definition: vpThread.h:78
double get_i() const
Definition: vpImagePoint.h:204
unsigned int getWidth() const
Definition: vpImage.h:237
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:657
Type operator()(const unsigned int i, const unsigned int j) const
Definition: vpImage.h:267
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:997
Type * bitmap
points toward the bitmap
Definition: vpImage.h:134
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:285
error that can be emited by ViSP classes.
Definition: vpException.h:71
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:979
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:254
virtual ~vpImage()
destructor
Definition: vpImage.h:917
static int round(const double x)
Definition: vpMath.h:241
double get_j() const
Definition: vpImagePoint.h:215
vpImage< Type > & operator=(vpImage< Type > other)
Copy operator.
Definition: vpImage.h:1071
Definition: vpRGBa.h:66
double getSum() const
Definition: vpImage.h:1609
unsigned int getRows() const
Definition: vpImage.h:209
Type getValue(unsigned int i, unsigned int j) const
Definition: vpImage.h:1402
friend void swap(vpImage< Type > &first, vpImage< Type > &second)
Definition: vpImage.h:1878
void *(* Fn)(Args)
Definition: vpThread.h:79
unsigned int getSize() const
Definition: vpImage.h:218
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:1126
void * Args
Definition: vpThread.h:77
Memory allocation error.
Definition: vpException.h:88
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:301
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:951
const Type * operator[](int i) const
Definition: vpImage.h:259
unsigned int getNumberOfPixel() const
Definition: vpImage.h:200
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:863
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:1174
void destroy()
Destructor : Memory de-allocation.
Definition: vpImage.h:892
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:258
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
Definition: vpImage.h:1279
void halfSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1251
Type * operator[](const int i)
Definition: vpImage.h:255
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:1156
Type getMeanValue() const
Return the mean value of the bitmap.
Definition: vpImage.h:966
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
unsigned int getHeight() const
Definition: vpImage.h:179
void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal=NULL, Type *maxVal=NULL) const
Get the position of the minimum and/or the maximum pixel value within the bitmap and the correspondin...
Definition: vpImage.h:1033
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void operator()(const unsigned int i, const unsigned int j, const Type &v)
Definition: vpImage.h:273
void performLut(const Type(&lut)[256], const unsigned int nbThreads=1)
Definition: vpImage.h:1711
vpImage()
constructor
Definition: vpImage.h:839
Definition of the vpImage class member functions.
Definition: vpImage.h:117
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:1103
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1650
void set_ij(const double ii, const double jj)
Definition: vpImagePoint.h:189