Visual Servoing Platform  version 3.1.0
vpImage.h
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 
63 class vpDisplay;
64 
115 // Ref: http://en.cppreference.com/w/cpp/language/friend#Template_friends
116 template <class Type> class vpImage; // forward declare to make function declaration possible
117 
118 // declarations
119 template <class Type> std::ostream &operator<<(std::ostream &, const vpImage<Type> &);
120 
121 std::ostream &operator<<(std::ostream &, const vpImage<unsigned char> &);
122 std::ostream &operator<<(std::ostream &, const vpImage<char> &);
123 std::ostream &operator<<(std::ostream &, const vpImage<float> &);
124 std::ostream &operator<<(std::ostream &, const vpImage<double> &);
125 
126 template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second);
127 
128 template <class Type> class vpImage
129 {
130  friend class vpImageConvert;
131 
132 public:
133  Type *bitmap;
135 
137  vpImage();
139  vpImage(const vpImage<Type> &);
140 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
143 #endif
144  vpImage(unsigned int height, unsigned int width);
147  vpImage(unsigned int height, unsigned int width, Type value);
149  vpImage(Type *const array, const unsigned int height, const unsigned int width, const bool copyData = false);
151  virtual ~vpImage();
152 
155 
156  // destructor
157  void destroy();
158 
159  // Returns a new image that's double size of the current image
160  void doubleSizeImage(vpImage<Type> &res);
161 
169  inline unsigned int getCols() const { return width; }
178  inline unsigned int getHeight() const { return height; }
179 
180  // Return the maximum value within the bitmap
181  Type getMaxValue() const;
182  // Return the minumum value within the bitmap
183  Type getMinValue() const;
184  // Look for the minumum and the maximum value within the bitmap
185  void getMinMaxValue(Type &min, Type &max) const;
186 
197  inline unsigned int getNumberOfPixel() const { return npixels; }
198 
207  inline unsigned int getRows() const { return height; }
215  inline unsigned int getSize() const { return width * height; }
216 
217  // Gets the value of a pixel at a location with bilinear interpolation.
218  Type getValue(double i, double j) const;
219  // Gets the value of a pixel at a location with bilinear interpolation.
220  Type getValue(vpImagePoint &ip) const;
229  inline unsigned int getWidth() const { return width; }
230 
231  // Returns a new image that's half size of the current image
232  void halfSizeImage(vpImage<Type> &res) const;
233 
235  void init(unsigned int height, unsigned int width);
237  void init(unsigned int height, unsigned int width, Type value);
239  void init(Type *const array, const unsigned int height, const unsigned int width, const bool copyData = false);
240  void insert(const vpImage<Type> &src, const vpImagePoint &topLeft);
241 
242  //------------------------------------------------------------------
243  // Acces to the image
244 
246  inline Type *operator[](const unsigned int i) { return row[i]; }
247  inline Type *operator[](const int i) { return row[i]; }
248 
250  inline const Type *operator[](unsigned int i) const { return row[i]; }
251  inline const Type *operator[](int i) const { return row[i]; }
252 
260  inline Type operator()(const unsigned int i, const unsigned int j) const { return bitmap[i * width + j]; }
266  inline void operator()(const unsigned int i, const unsigned int j, const Type &v) { bitmap[i * width + j] = v; }
278  inline Type operator()(const vpImagePoint &ip) const
279  {
280  unsigned int i = (unsigned int)ip.get_i();
281  unsigned int j = (unsigned int)ip.get_j();
282 
283  return bitmap[i * width + j];
284  }
294  inline void operator()(const vpImagePoint &ip, const Type &v)
295  {
296  unsigned int i = (unsigned int)ip.get_i();
297  unsigned int j = (unsigned int)ip.get_j();
298 
299  bitmap[i * width + j] = v;
300  }
301 
303 
306 
307  vpImage<Type> &operator=(const Type &v);
308  bool operator==(const vpImage<Type> &I);
309  bool operator!=(const vpImage<Type> &I);
310  friend std::ostream &operator<<<>(std::ostream &s, const vpImage<Type> &I);
311  friend std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I);
312  friend std::ostream &operator<<(std::ostream &s, const vpImage<char> &I);
313  friend std::ostream &operator<<(std::ostream &s, const vpImage<float> &I);
314  friend std::ostream &operator<<(std::ostream &s, const vpImage<double> &I);
315 
316  // Perform a look-up table transformation
317  void performLut(const Type (&lut)[256], const unsigned int nbThreads = 1);
318 
319  // Returns a new image that's a quarter size of the current image
320  void quarterSizeImage(vpImage<Type> &res) const;
321 
322  // set the size of the image without initializing it.
323  void resize(const unsigned int h, const unsigned int w);
324  // set the size of the image and initialize it.
325  void resize(const unsigned int h, const unsigned int w, const Type &val);
326 
327  void sub(const vpImage<Type> &B, vpImage<Type> &C);
328  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
329  void subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const;
330 
331  friend void swap<>(vpImage<Type> &first, vpImage<Type> &second);
332 
334 
335 private:
336  unsigned int npixels;
337  unsigned int width;
338  unsigned int height;
339  Type **row;
340 };
341 
342 template <class Type> std::ostream &operator<<(std::ostream &s, const vpImage<Type> &I)
343 {
344  if (I.bitmap == NULL) {
345  return s;
346  }
347 
348  for (unsigned int i = 0; i < I.getHeight(); i++) {
349  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
350  s << I[i][j] << " ";
351  }
352 
353  // We don't add " " after the last column element
354  s << I[i][I.getWidth() - 1];
355 
356  // We don't add a \n character at the end of the last row line
357  if (i < I.getHeight() - 1) {
358  s << std::endl;
359  }
360  }
361 
362  return s;
363 }
364 
365 inline std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I)
366 {
367  if (I.bitmap == NULL) {
368  return s;
369  }
370 
371  std::ios_base::fmtflags original_flags = s.flags();
372 
373  for (unsigned int i = 0; i < I.getHeight(); i++) {
374  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
375  s << std::setw(3) << static_cast<unsigned>(I[i][j]) << " ";
376  }
377 
378  // We don't add " " after the last column element
379  s << std::setw(3) << static_cast<unsigned>(I[i][I.getWidth() - 1]);
380 
381  // We don't add a \n character at the end of the last row line
382  if (i < I.getHeight() - 1) {
383  s << std::endl;
384  }
385  }
386 
387  s.flags(original_flags); // restore s to standard state
388  return s;
389 }
390 
391 inline std::ostream &operator<<(std::ostream &s, const vpImage<char> &I)
392 {
393  if (I.bitmap == NULL) {
394  return s;
395  }
396 
397  std::ios_base::fmtflags original_flags = s.flags();
398 
399  for (unsigned int i = 0; i < I.getHeight(); i++) {
400  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
401  s << std::setw(4) << static_cast<int>(I[i][j]) << " ";
402  }
403 
404  // We don't add " " after the last column element
405  s << std::setw(4) << static_cast<int>(I[i][I.getWidth() - 1]);
406 
407  // We don't add a \n character at the end of the last row line
408  if (i < I.getHeight() - 1) {
409  s << std::endl;
410  }
411  }
412 
413  s.flags(original_flags); // restore s to standard state
414  return s;
415 }
416 
417 inline std::ostream &operator<<(std::ostream &s, const vpImage<float> &I)
418 {
419  if (I.bitmap == NULL) {
420  return s;
421  }
422 
423  std::ios_base::fmtflags original_flags = s.flags();
424  s.precision(9); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
425 
426  for (unsigned int i = 0; i < I.getHeight(); i++) {
427  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
428  s << I[i][j] << " ";
429  }
430 
431  // We don't add " " after the last column element
432  s << I[i][I.getWidth() - 1];
433 
434  // We don't add a \n character at the end of the last row line
435  if (i < I.getHeight() - 1) {
436  s << std::endl;
437  }
438  }
439 
440  s.flags(original_flags); // restore s to standard state
441  return s;
442 }
443 
444 inline std::ostream &operator<<(std::ostream &s, const vpImage<double> &I)
445 {
446  if (I.bitmap == NULL) {
447  return s;
448  }
449 
450  std::ios_base::fmtflags original_flags = s.flags();
451  s.precision(17); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
452 
453  for (unsigned int i = 0; i < I.getHeight(); i++) {
454  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
455  s << I[i][j] << " ";
456  }
457 
458  // We don't add " " after the last column element
459  s << I[i][I.getWidth() - 1];
460 
461  // We don't add a \n character at the end of the last row line
462  if (i < I.getHeight() - 1) {
463  s << std::endl;
464  }
465  }
466 
467  s.flags(original_flags); // restore s to standard state
468  return s;
469 }
470 
471 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
472 namespace
473 {
474 struct ImageLut_Param_t {
475  unsigned int m_start_index;
476  unsigned int m_end_index;
477 
478  unsigned char m_lut[256];
479  unsigned char *m_bitmap;
480 
481  ImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
482 
483  ImageLut_Param_t(const unsigned int start_index, const unsigned int end_index, unsigned char *bitmap)
484  : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
485  {
486  }
487 };
488 
489 vpThread::Return performLutThread(vpThread::Args args)
490 {
491  ImageLut_Param_t *imageLut_param = static_cast<ImageLut_Param_t *>(args);
492  unsigned int start_index = imageLut_param->m_start_index;
493  unsigned int end_index = imageLut_param->m_end_index;
494 
495  unsigned char *bitmap = imageLut_param->m_bitmap;
496 
497  unsigned char *ptrStart = bitmap + start_index;
498  unsigned char *ptrEnd = bitmap + end_index;
499  unsigned char *ptrCurrent = ptrStart;
500 
501  // while(ptrCurrent != ptrEnd) {
502  // *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
503  // ++ptrCurrent;
504  // }
505 
506  if (end_index - start_index >= 8) {
507  // Unroll loop version
508  for (; ptrCurrent <= ptrEnd - 8;) {
509  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
510  ++ptrCurrent;
511 
512  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
513  ++ptrCurrent;
514 
515  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
516  ++ptrCurrent;
517 
518  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
519  ++ptrCurrent;
520 
521  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
522  ++ptrCurrent;
523 
524  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
525  ++ptrCurrent;
526 
527  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
528  ++ptrCurrent;
529 
530  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
531  ++ptrCurrent;
532  }
533  }
534 
535  for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
536  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
537  }
538 
539  return 0;
540 }
541 
542 struct ImageLutRGBa_Param_t {
543  unsigned int m_start_index;
544  unsigned int m_end_index;
545 
546  vpRGBa m_lut[256];
547  unsigned char *m_bitmap;
548 
549  ImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
550 
551  ImageLutRGBa_Param_t(const unsigned int start_index, const unsigned int end_index, unsigned char *bitmap)
552  : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
553  {
554  }
555 };
556 
557 vpThread::Return performLutRGBaThread(vpThread::Args args)
558 {
559  ImageLutRGBa_Param_t *imageLut_param = static_cast<ImageLutRGBa_Param_t *>(args);
560  unsigned int start_index = imageLut_param->m_start_index;
561  unsigned int end_index = imageLut_param->m_end_index;
562 
563  unsigned char *bitmap = imageLut_param->m_bitmap;
564 
565  unsigned char *ptrStart = bitmap + start_index * 4;
566  unsigned char *ptrEnd = bitmap + end_index * 4;
567  unsigned char *ptrCurrent = ptrStart;
568 
569  if (end_index - start_index >= 4 * 2) {
570  // Unroll loop version
571  for (; ptrCurrent <= ptrEnd - 4 * 2;) {
572  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
573  ptrCurrent++;
574  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
575  ptrCurrent++;
576  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
577  ptrCurrent++;
578  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
579  ptrCurrent++;
580 
581  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
582  ptrCurrent++;
583  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
584  ptrCurrent++;
585  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
586  ptrCurrent++;
587  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
588  ptrCurrent++;
589  }
590  }
591 
592  while (ptrCurrent != ptrEnd) {
593  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
594  ptrCurrent++;
595 
596  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
597  ptrCurrent++;
598 
599  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
600  ptrCurrent++;
601 
602  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
603  ptrCurrent++;
604  }
605 
606  return 0;
607 }
608 }
609 #endif
610 
624 template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
625 {
626  init(h, w);
627 
628  for (unsigned int i = 0; i < npixels; i++)
629  bitmap[i] = value;
630 }
631 
649 template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w)
650 {
651  if (h != this->height) {
652  if (row != NULL) {
653  vpDEBUG_TRACE(10, "Destruction row[]");
654  delete[] row;
655  row = NULL;
656  }
657  }
658 
659  if ((h != this->height) || (w != this->width)) {
660  if (bitmap != NULL) {
661  vpDEBUG_TRACE(10, "Destruction bitmap[]");
662  delete[] bitmap;
663  bitmap = NULL;
664  }
665  }
666 
667  this->width = w;
668  this->height = h;
669 
670  npixels = width * height;
671 
672  if (bitmap == NULL)
673  bitmap = new Type[npixels];
674 
675  if (bitmap == NULL) {
676  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
677  }
678 
679  if (row == NULL)
680  row = new Type *[height];
681  if (row == NULL) {
682  throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
683  }
684 
685  unsigned int i;
686  for (i = 0; i < height; i++)
687  row[i] = bitmap + i * width;
688 }
689 
703 template <class Type>
704 void vpImage<Type>::init(Type *const array, const unsigned int h, const unsigned int w, const bool copyData)
705 {
706  if (h != this->height) {
707  if (row != NULL) {
708  delete[] row;
709  row = NULL;
710  }
711  }
712 
713  // Delete bitmap if copyData==false, otherwise only if the dimension differs
714  if ((copyData && ((h != this->height) || (w != this->width))) || !copyData) {
715  if (bitmap != NULL) {
716  delete[] bitmap;
717  bitmap = NULL;
718  }
719  }
720 
721  this->width = w;
722  this->height = h;
723 
724  npixels = width * height;
725 
726  if (copyData) {
727  if (bitmap == NULL)
728  bitmap = new Type[npixels];
729 
730  if (bitmap == NULL) {
731  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
732  }
733 
734  // Copy the image data
735  memcpy(bitmap, array, (size_t)(npixels * sizeof(Type)));
736  } else {
737  // Copy the address of the array in the bitmap
738  bitmap = array;
739  }
740 
741  if (row == NULL)
742  row = new Type *[height];
743  if (row == NULL) {
744  throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
745  }
746 
747  for (unsigned int i = 0; i < height; i++) {
748  row[i] = bitmap + i * width;
749  }
750 }
751 
770 template <class Type>
771 vpImage<Type>::vpImage(unsigned int h, unsigned int w)
772  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
773 {
774  init(h, w, 0);
775 }
776 
794 template <class Type>
795 vpImage<Type>::vpImage(unsigned int h, unsigned int w, Type value)
796  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
797 {
798  init(h, w, value);
799 }
800 
816 template <class Type>
817 vpImage<Type>::vpImage(Type *const array, const unsigned int h, const unsigned int w, const bool copyData)
818  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
819 {
820  init(array, h, w, copyData);
821 }
822 
832 template <class Type> vpImage<Type>::vpImage() : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
833 {
834 }
835 
856 template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w) { init(h, w); }
857 
877 template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w, const Type &val) { init(h, w, val); }
878 
885 template <class Type> void vpImage<Type>::destroy()
886 {
887  // vpERROR_TRACE("Deallocate ");
888 
889  if (bitmap != NULL) {
890  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap);
891  // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap);
892  delete[] bitmap;
893  bitmap = NULL;
894  }
895 
896  if (row != NULL) {
897  // vpERROR_TRACE("Deallocate row memory %p",row);
898  // vpDEBUG_TRACE(20,"Deallocate row memory %p",row);
899  delete[] row;
900  row = NULL;
901  }
902 }
903 
910 template <class Type> vpImage<Type>::~vpImage() { destroy(); }
911 
915 template <class Type>
916 vpImage<Type>::vpImage(const vpImage<Type> &I) : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
917 {
918  resize(I.getHeight(), I.getWidth());
919  memcpy(bitmap, I.bitmap, I.npixels * sizeof(Type));
920 }
921 
922 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
923 
926 template <class Type>
928  : bitmap(I.bitmap), display(I.display), npixels(I.npixels), width(I.width), height(I.height), row(I.row)
929 {
930  I.bitmap = NULL;
931  I.display = NULL;
932  I.npixels = 0;
933  I.width = 0;
934  I.height = 0;
935  I.row = NULL;
936 }
937 #endif
938 
944 template <class Type> Type vpImage<Type>::getMaxValue() const
945 {
946  Type m = bitmap[0];
947  for (unsigned int i = 0; i < npixels; i++) {
948  if (bitmap[i] > m)
949  m = bitmap[i];
950  }
951  return m;
952 }
953 
959 template <class Type> Type vpImage<Type>::getMinValue() const
960 {
961  Type m = bitmap[0];
962  for (unsigned int i = 0; i < npixels; i++)
963  if (bitmap[i] < m)
964  m = bitmap[i];
965  return m;
966 }
967 
974 template <class Type> void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
975 {
976  min = max = bitmap[0];
977  for (unsigned int i = 0; i < npixels; i++) {
978  if (bitmap[i] < min)
979  min = bitmap[i];
980  if (bitmap[i] > max)
981  max = bitmap[i];
982  }
983 }
984 
989 {
990  swap(*this, other);
991  // Swap back display pointer if it was not null
992  // vpImage<unsigned char> I2(480, 640);
993  // vpDisplayX d(I2);
994  // I2 = I1; //copy only the data
995  if (other.display != NULL)
996  display = other.display;
997 
998  return *this;
999 }
1000 
1007 template <class Type> vpImage<Type> &vpImage<Type>::operator=(const Type &v)
1008 {
1009  for (unsigned int i = 0; i < npixels; i++)
1010  bitmap[i] = v;
1011 
1012  return *this;
1013 }
1014 
1020 template <class Type> bool vpImage<Type>::operator==(const vpImage<Type> &I)
1021 {
1022  if (this->width != I.getWidth())
1023  return false;
1024  if (this->height != I.getHeight())
1025  return false;
1026 
1027  // printf("wxh: %dx%d bitmap: %p I.bitmap %p\n", width, height, bitmap,
1028  // I.bitmap);
1029  for (unsigned int i = 0; i < npixels; i++) {
1030  if (bitmap[i] != I.bitmap[i]) {
1031  // std::cout << "differ for pixel " << i << " (" << i%this->height
1032  // << ", " << i - i%this->height << ")" << std::endl;
1033  return false;
1034  }
1035  }
1036  return true;
1037 }
1043 template <class Type> bool vpImage<Type>::operator!=(const vpImage<Type> &I)
1044 {
1045  // if (this->width != I.getWidth())
1046  // return true;
1047  // if (this->height != I.getHeight())
1048  // return true;
1049 
1050  // for (unsigned int i=0 ; i < npixels ; i++)
1051  // {
1052  // if (bitmap[i] != I.bitmap[i])
1053  // return true;
1054  // }
1055  // return false;
1056  return !(*this == I);
1057 }
1058 
1085 {
1086  vpImage<Type> C;
1087  sub(*this, B, C);
1088  return C;
1089 }
1090 
1102 template <class Type> void vpImage<Type>::insert(const vpImage<Type> &src, const vpImagePoint &topLeft)
1103 {
1104  int itl = (int)topLeft.get_i();
1105  int jtl = (int)topLeft.get_j();
1106 
1107  int dest_ibegin = 0;
1108  int dest_jbegin = 0;
1109  int src_ibegin = 0;
1110  int src_jbegin = 0;
1111  int dest_w = (int)this->getWidth();
1112  int dest_h = (int)this->getHeight();
1113  int src_w = (int)src.getWidth();
1114  int src_h = (int)src.getHeight();
1115  int wsize = (int)src.getWidth();
1116  int hsize = (int)src.getHeight();
1117 
1118  if (itl >= dest_h || jtl >= dest_w)
1119  return;
1120 
1121  if (itl < 0)
1122  src_ibegin = -itl;
1123  else
1124  dest_ibegin = itl;
1125 
1126  if (jtl < 0)
1127  src_jbegin = -jtl;
1128  else
1129  dest_jbegin = jtl;
1130 
1131  if (src_w - src_jbegin > dest_w - dest_jbegin)
1132  wsize = dest_w - dest_jbegin;
1133  else
1134  wsize = src_w - src_jbegin;
1135 
1136  if (src_h - src_ibegin > dest_h - dest_ibegin)
1137  hsize = dest_h - dest_ibegin;
1138  else
1139  hsize = src_h - src_ibegin;
1140 
1141  for (int i = 0; i < hsize; i++) {
1142  Type *srcBitmap = src.bitmap + ((src_ibegin + i) * src_w + src_jbegin);
1143  Type *destBitmap = this->bitmap + ((dest_ibegin + i) * dest_w + dest_jbegin);
1144 
1145  memcpy(destBitmap, srcBitmap, (size_t)wsize * sizeof(Type));
1146  }
1147 }
1148 
1179 template <class Type> void vpImage<Type>::halfSizeImage(vpImage<Type> &res) const
1180 {
1181  unsigned int h = height / 2;
1182  unsigned int w = width / 2;
1183  res.resize(h, w);
1184  for (unsigned int i = 0; i < h; i++)
1185  for (unsigned int j = 0; j < w; j++)
1186  res[i][j] = (*this)[i << 1][j << 1];
1187 }
1188 
1206 template <class Type>
1207 void vpImage<Type>::subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const
1208 {
1209  unsigned int h = height / v_scale;
1210  unsigned int w = width / h_scale;
1211  sampled.resize(h, w);
1212  for (unsigned int i = 0; i < h; i++)
1213  for (unsigned int j = 0; j < w; j++)
1214  sampled[i][j] = (*this)[i * v_scale][j * h_scale];
1215 }
1216 
1241 template <class Type> void vpImage<Type>::quarterSizeImage(vpImage<Type> &res) const
1242 {
1243  unsigned int h = height / 4;
1244  unsigned int w = width / 4;
1245  res.resize(h, w);
1246  for (unsigned int i = 0; i < h; i++)
1247  for (unsigned int j = 0; j < w; j++)
1248  res[i][j] = (*this)[i << 2][j << 2];
1249 }
1250 
1284 template <class Type> void vpImage<Type>::doubleSizeImage(vpImage<Type> &res)
1285 {
1286  int h = height * 2;
1287  int w = width * 2;
1288 
1289  res.resize(h, w);
1290 
1291  for (int i = 0; i < h; i++)
1292  for (int j = 0; j < w; j++)
1293  res[i][j] = (*this)[i >> 1][j >> 1];
1294 
1295  /*
1296  A B C
1297  E F G
1298  H I J
1299  A C H J are pixels from original image
1300  B E G I are interpolated pixels
1301  */
1302 
1303  // interpolate pixels B and I
1304  for (int i = 0; i < h; i += 2)
1305  for (int j = 1; j < w - 1; j += 2)
1306  res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1]));
1307 
1308  // interpolate pixels E and G
1309  for (int i = 1; i < h - 1; i += 2)
1310  for (int j = 0; j < w; j += 2)
1311  res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[(i >> 1) + 1][j >> 1]));
1312 
1313  // interpolate pixel F
1314  for (int i = 1; i < h - 1; i += 2)
1315  for (int j = 1; j < w - 1; j += 2)
1316  res[i][j] = (Type)(0.25 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1] +
1317  (*this)[(i >> 1) + 1][j >> 1] + (*this)[(i >> 1) + 1][(j >> 1) + 1]));
1318 }
1319 
1338 template <class Type> Type vpImage<Type>::getValue(double i, double j) const
1339 {
1340  unsigned int iround, jround;
1341  double rfrac, cfrac;
1342 
1343  iround = (unsigned int)floor(i);
1344  jround = (unsigned int)floor(j);
1345 
1346  if (iround >= height || jround >= width) {
1347  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1348  }
1349 
1350  if (i > height - 1)
1351  i = (double)(height - 1);
1352 
1353  if (j > width - 1)
1354  j = (double)(width - 1);
1355 
1356  double rratio = i - (double)iround;
1357  if (rratio < 0)
1358  rratio = -rratio;
1359  double cratio = j - (double)jround;
1360  if (cratio < 0)
1361  cratio = -cratio;
1362 
1363  rfrac = 1.0f - rratio;
1364  cfrac = 1.0f - cratio;
1365 
1366  double value = ((double)row[iround][jround] * rfrac + (double)row[iround + 1][jround] * rratio) * cfrac +
1367  ((double)row[iround][jround + 1] * rfrac + (double)row[iround + 1][jround + 1] * rratio) * cratio;
1368  return (Type)vpMath::round(value);
1369 }
1370 
1388 template <> inline double vpImage<double>::getValue(double i, double j) const
1389 {
1390  unsigned int iround, jround;
1391  double rfrac, cfrac;
1392 
1393  iround = (unsigned int)floor(i);
1394  jround = (unsigned int)floor(j);
1395 
1396  if (iround >= height || jround >= width) {
1397  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1398  }
1399 
1400  if (i > height - 1)
1401  i = (double)(height - 1);
1402 
1403  if (j > width - 1)
1404  j = (double)(width - 1);
1405 
1406  double rratio = i - (double)iround;
1407  if (rratio < 0)
1408  rratio = -rratio;
1409  double cratio = j - (double)jround;
1410  if (cratio < 0)
1411  cratio = -cratio;
1412 
1413  rfrac = 1.0f - rratio;
1414  cfrac = 1.0f - cratio;
1415 
1416  double value = ((double)row[iround][jround] * rfrac + (double)row[iround + 1][jround] * rratio) * cfrac +
1417  ((double)row[iround][jround + 1] * rfrac + (double)row[iround + 1][jround + 1] * rratio) * cratio;
1418  return value;
1419 }
1420 
1421 template <> inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1422 {
1423  unsigned int iround, jround;
1424  double rfrac, cfrac;
1425 
1426  iround = (unsigned int)floor(i);
1427  jround = (unsigned int)floor(j);
1428 
1429  if (iround >= height || jround >= width) {
1430  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1431  }
1432 
1433  if (i > height - 1)
1434  i = (double)(height - 1);
1435 
1436  if (j > width - 1)
1437  j = (double)(width - 1);
1438 
1439  double rratio = i - (double)iround;
1440  if (rratio < 0)
1441  rratio = -rratio;
1442  double cratio = j - (double)jround;
1443  if (cratio < 0)
1444  cratio = -cratio;
1445 
1446  rfrac = 1.0f - rratio;
1447  cfrac = 1.0f - cratio;
1448 
1449  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround + 1][jround].R * rratio) * cfrac +
1450  ((double)row[iround][jround + 1].R * rfrac + (double)row[iround + 1][jround + 1].R * rratio) * cratio;
1451  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround + 1][jround].G * rratio) * cfrac +
1452  ((double)row[iround][jround + 1].G * rfrac + (double)row[iround + 1][jround + 1].G * rratio) * cratio;
1453  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround + 1][jround].B * rratio) * cfrac +
1454  ((double)row[iround][jround + 1].B * rfrac + (double)row[iround + 1][jround + 1].B * rratio) * cratio;
1455  return vpRGBa((unsigned char)vpMath::round(valueR), (unsigned char)vpMath::round(valueG),
1456  (unsigned char)vpMath::round(valueB));
1457 }
1458 
1476 template <class Type> inline Type vpImage<Type>::getValue(vpImagePoint &ip) const
1477 {
1478  unsigned int iround, jround;
1479  double rfrac, cfrac;
1480 
1481  iround = (unsigned int)floor(ip.get_i());
1482  jround = (unsigned int)floor(ip.get_j());
1483 
1484  if (iround >= height || jround >= width) {
1485  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1486  }
1487 
1488  if (ip.get_i() > height - 1)
1489  ip.set_i((double)(height - 1));
1490 
1491  if (ip.get_j() > width - 1)
1492  ip.set_j((double)(width - 1));
1493 
1494  double rratio = ip.get_i() - (double)iround;
1495  if (rratio < 0)
1496  rratio = -rratio;
1497  double cratio = ip.get_j() - (double)jround;
1498  if (cratio < 0)
1499  cratio = -cratio;
1500 
1501  rfrac = 1.0f - rratio;
1502  cfrac = 1.0f - cratio;
1503 
1504  double value = ((double)row[iround][jround] * rfrac + (double)row[iround + 1][jround] * rratio) * cfrac +
1505  ((double)row[iround][jround + 1] * rfrac + (double)row[iround + 1][jround + 1] * rratio) * cratio;
1506  return (Type)vpMath::round(value);
1507 }
1508 
1509 template <> inline double vpImage<double>::getValue(vpImagePoint &ip) const
1510 {
1511  unsigned int iround, jround;
1512  double rfrac, cfrac;
1513 
1514  iround = (unsigned int)floor(ip.get_i());
1515  jround = (unsigned int)floor(ip.get_j());
1516 
1517  if (iround >= height || jround >= width) {
1518  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1519  }
1520 
1521  if (ip.get_i() > height - 1)
1522  ip.set_i((double)(height - 1));
1523 
1524  if (ip.get_j() > width - 1)
1525  ip.set_j((double)(width - 1));
1526 
1527  double rratio = ip.get_i() - (double)iround;
1528  if (rratio < 0)
1529  rratio = -rratio;
1530  double cratio = ip.get_j() - (double)jround;
1531  if (cratio < 0)
1532  cratio = -cratio;
1533 
1534  rfrac = 1.0f - rratio;
1535  cfrac = 1.0f - cratio;
1536 
1537  double value = ((double)row[iround][jround] * rfrac + (double)row[iround + 1][jround] * rratio) * cfrac +
1538  ((double)row[iround][jround + 1] * rfrac + (double)row[iround + 1][jround + 1] * rratio) * cratio;
1539  return value;
1540 }
1541 
1542 template <> inline vpRGBa vpImage<vpRGBa>::getValue(vpImagePoint &ip) const
1543 {
1544  unsigned int iround, jround;
1545  double rfrac, cfrac;
1546 
1547  iround = (unsigned int)floor(ip.get_i());
1548  jround = (unsigned int)floor(ip.get_j());
1549 
1550  if (iround >= height || jround >= width) {
1551  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1552  }
1553 
1554  if (ip.get_i() > height - 1)
1555  ip.set_i((double)(height - 1));
1556 
1557  if (ip.get_j() > width - 1)
1558  ip.set_j((double)(width - 1));
1559 
1560  double rratio = ip.get_i() - (double)iround;
1561  if (rratio < 0)
1562  rratio = -rratio;
1563  double cratio = ip.get_j() - (double)jround;
1564  if (cratio < 0)
1565  cratio = -cratio;
1566 
1567  rfrac = 1.0f - rratio;
1568  cfrac = 1.0f - cratio;
1569 
1570  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround + 1][jround].R * rratio) * cfrac +
1571  ((double)row[iround][jround + 1].R * rfrac + (double)row[iround + 1][jround + 1].R * rratio) * cratio;
1572  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround + 1][jround].G * rratio) * cfrac +
1573  ((double)row[iround][jround + 1].G * rfrac + (double)row[iround + 1][jround + 1].G * rratio) * cratio;
1574  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround + 1][jround].B * rratio) * cfrac +
1575  ((double)row[iround][jround + 1].B * rfrac + (double)row[iround + 1][jround + 1].B * rratio) * cratio;
1576  return vpRGBa((unsigned char)vpMath::round(valueR), (unsigned char)vpMath::round(valueG),
1577  (unsigned char)vpMath::round(valueB));
1578 }
1579 
1609 template <class Type> void vpImage<Type>::sub(const vpImage<Type> &B, vpImage<Type> &C)
1610 {
1611 
1612  try {
1613  if ((this->getHeight() != C.getHeight()) || (this->getWidth() != C.getWidth()))
1614  C.resize(this->getHeight(), this->getWidth());
1615  } catch (vpException &me) {
1616  std::cout << me << std::endl;
1617  throw;
1618  }
1619 
1620  if ((this->getWidth() != B.getWidth()) || (this->getHeight() != B.getHeight())) {
1621  throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage substraction "));
1622  }
1623 
1624  for (unsigned int i = 0; i < this->getWidth() * this->getHeight(); i++) {
1625  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i);
1626  }
1627 }
1628 
1640 template <class Type> void vpImage<Type>::sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C)
1641 {
1642 
1643  try {
1644  if ((A.getHeight() != C.getHeight()) || (A.getWidth() != C.getWidth()))
1645  C.resize(A.getHeight(), A.getWidth());
1646  } catch (vpException &me) {
1647  std::cout << me << std::endl;
1648  throw;
1649  }
1650 
1651  if ((A.getWidth() != B.getWidth()) || (A.getHeight() != B.getHeight())) {
1652  throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage substraction "));
1653  }
1654 
1655  for (unsigned int i = 0; i < A.getWidth() * A.getHeight(); i++) {
1656  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i);
1657  }
1658 }
1659 
1670 template <class Type> void vpImage<Type>::performLut(const Type (&)[256], const unsigned int)
1671 {
1672  std::cerr << "Not implemented !" << std::endl;
1673 }
1674 
1683 template <>
1684 inline void vpImage<unsigned char>::performLut(const unsigned char (&lut)[256], const unsigned int nbThreads)
1685 {
1686  unsigned int size = getWidth() * getHeight();
1687  unsigned char *ptrStart = (unsigned char *)bitmap;
1688  unsigned char *ptrEnd = ptrStart + size;
1689  unsigned char *ptrCurrent = ptrStart;
1690 
1691  bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1692 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1693  use_single_thread = true;
1694 #endif
1695 
1696  if (!use_single_thread && getSize() <= nbThreads) {
1697  use_single_thread = true;
1698  }
1699 
1700  if (use_single_thread) {
1701  // Single thread
1702 
1703  while (ptrCurrent != ptrEnd) {
1704  *ptrCurrent = lut[*ptrCurrent];
1705  ++ptrCurrent;
1706  }
1707  } else {
1708 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1709  // Multi-threads
1710 
1711  std::vector<vpThread *> threadpool;
1712  std::vector<ImageLut_Param_t *> imageLutParams;
1713 
1714  unsigned int image_size = getSize();
1715  unsigned int step = image_size / nbThreads;
1716  unsigned int last_step = image_size - step * (nbThreads - 1);
1717 
1718  for (unsigned int index = 0; index < nbThreads; index++) {
1719  unsigned int start_index = index * step;
1720  unsigned int end_index = (index + 1) * step;
1721 
1722  if (index == nbThreads - 1) {
1723  end_index = start_index + last_step;
1724  }
1725 
1726  ImageLut_Param_t *imageLut_param = new ImageLut_Param_t(start_index, end_index, bitmap);
1727  memcpy(imageLut_param->m_lut, lut, 256 * sizeof(unsigned char));
1728 
1729  imageLutParams.push_back(imageLut_param);
1730 
1731  // Start the threads
1732  vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutThread, (vpThread::Args)imageLut_param);
1733  threadpool.push_back(imageLut_thread);
1734  }
1735 
1736  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1737  // Wait until thread ends up
1738  threadpool[cpt]->join();
1739  }
1740 
1741  // Delete
1742  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1743  delete threadpool[cpt];
1744  }
1745 
1746  for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1747  delete imageLutParams[cpt];
1748  }
1749 #endif
1750  }
1751 }
1752 
1761 template <> inline void vpImage<vpRGBa>::performLut(const vpRGBa (&lut)[256], const unsigned int nbThreads)
1762 {
1763  unsigned int size = getWidth() * getHeight();
1764  unsigned char *ptrStart = (unsigned char *)bitmap;
1765  unsigned char *ptrEnd = ptrStart + size * 4;
1766  unsigned char *ptrCurrent = ptrStart;
1767 
1768  bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1769 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1770  use_single_thread = true;
1771 #endif
1772 
1773  if (!use_single_thread && getSize() <= nbThreads) {
1774  use_single_thread = true;
1775  }
1776 
1777  if (use_single_thread) {
1778  // Single thread
1779  while (ptrCurrent != ptrEnd) {
1780  *ptrCurrent = lut[*ptrCurrent].R;
1781  ++ptrCurrent;
1782 
1783  *ptrCurrent = lut[*ptrCurrent].G;
1784  ++ptrCurrent;
1785 
1786  *ptrCurrent = lut[*ptrCurrent].B;
1787  ++ptrCurrent;
1788 
1789  *ptrCurrent = lut[*ptrCurrent].A;
1790  ++ptrCurrent;
1791  }
1792  } else {
1793 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1794  // Multi-threads
1795  std::vector<vpThread *> threadpool;
1796  std::vector<ImageLutRGBa_Param_t *> imageLutParams;
1797 
1798  unsigned int image_size = getSize();
1799  unsigned int step = image_size / nbThreads;
1800  unsigned int last_step = image_size - step * (nbThreads - 1);
1801 
1802  for (unsigned int index = 0; index < nbThreads; index++) {
1803  unsigned int start_index = index * step;
1804  unsigned int end_index = (index + 1) * step;
1805 
1806  if (index == nbThreads - 1) {
1807  end_index = start_index + last_step;
1808  }
1809 
1810  ImageLutRGBa_Param_t *imageLut_param = new ImageLutRGBa_Param_t(start_index, end_index, (unsigned char *)bitmap);
1811  memcpy(imageLut_param->m_lut, lut, 256 * sizeof(vpRGBa));
1812 
1813  imageLutParams.push_back(imageLut_param);
1814 
1815  // Start the threads
1816  vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutRGBaThread, (vpThread::Args)imageLut_param);
1817  threadpool.push_back(imageLut_thread);
1818  }
1819 
1820  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1821  // Wait until thread ends up
1822  threadpool[cpt]->join();
1823  }
1824 
1825  // Delete
1826  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1827  delete threadpool[cpt];
1828  }
1829 
1830  for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1831  delete imageLutParams[cpt];
1832  }
1833 #endif
1834  }
1835 }
1836 
1837 template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second)
1838 {
1839  using std::swap;
1840  swap(first.bitmap, second.bitmap);
1841  swap(first.display, second.display);
1842  swap(first.npixels, second.npixels);
1843  swap(first.width, second.width);
1844  swap(first.height, second.height);
1845  swap(first.row, second.row);
1846 }
1847 
1848 #endif
vpDisplay * display
Definition: vpImage.h:134
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1284
double get_i() const
Definition: vpImagePoint.h:204
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:171
void halfSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1179
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:959
void * Return
Definition: vpThread.h:41
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:649
unsigned int getRows() const
Definition: vpImage.h:207
Type * bitmap
points toward the bitmap
Definition: vpImage.h:133
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
Definition: vpImage.h:1207
error that can be emited by ViSP classes.
Definition: vpException.h:71
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:278
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:246
virtual ~vpImage()
destructor
Definition: vpImage.h:910
static int round(const double x)
Definition: vpMath.h:235
vpImage< Type > & operator=(vpImage< Type > other)
Copy operator.
Definition: vpImage.h:988
Definition: vpRGBa.h:66
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:250
void set_i(const double ii)
Definition: vpImagePoint.h:167
Type operator()(const unsigned int i, const unsigned int j) const
Definition: vpImage.h:260
friend void swap(vpImage< Type > &first, vpImage< Type > &second)
Definition: vpImage.h:1837
void *(* Fn)(Args)
Definition: vpThread.h:42
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:1043
void * Args
Definition: vpThread.h:40
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:294
double get_j() const
Definition: vpImagePoint.h:215
unsigned int getCols() const
Definition: vpImage.h:169
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:856
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:944
Type getValue(double i, double j) const
Definition: vpImage.h:1338
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:1102
void destroy()
Destructor : Memory de-allocation.
Definition: vpImage.h:885
const Type * operator[](int i) const
Definition: vpImage.h:251
void quarterSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1241
unsigned int getNumberOfPixel() const
Definition: vpImage.h:197
void set_j(const double jj)
Definition: vpImagePoint.h:178
unsigned int getHeight() const
Definition: vpImage.h:178
unsigned int getSize() const
Definition: vpImage.h:215
Type * operator[](const int i)
Definition: vpImage.h:247
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:1084
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
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:266
void performLut(const Type(&lut)[256], const unsigned int nbThreads=1)
Definition: vpImage.h:1670
vpImage()
constructor
Definition: vpImage.h:832
unsigned int getWidth() const
Definition: vpImage.h:229
Definition of the vpImage class member functions.
Definition: vpImage.h:116
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:1020
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:974
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1609