Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
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 
63 // Visual Studio 2010 or previous is missing inttypes.h
64 #if defined(_MSC_VER) && (_MSC_VER < 1700)
65 typedef long long int64_t;
66 typedef unsigned short uint16_t;
67 #else
68 # include <inttypes.h>
69 #endif
70 
71 class vpDisplay;
72 
123 // Ref: http://en.cppreference.com/w/cpp/language/friend#Template_friends
124 template <class Type> class vpImage; // forward declare to make function declaration possible
125 
126 // declarations
127 template <class Type> std::ostream &operator<<(std::ostream &, const vpImage<Type> &);
128 
129 std::ostream &operator<<(std::ostream &, const vpImage<unsigned char> &);
130 std::ostream &operator<<(std::ostream &, const vpImage<char> &);
131 std::ostream &operator<<(std::ostream &, const vpImage<float> &);
132 std::ostream &operator<<(std::ostream &, const vpImage<double> &);
133 
134 template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second);
135 
136 template <class Type> class vpImage
137 {
138  friend class vpImageConvert;
139 
140 public:
141  Type *bitmap;
143 
145  vpImage();
147  vpImage(const vpImage<Type> &);
148 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
151 #endif
152  vpImage(unsigned int height, unsigned int width);
155  vpImage(unsigned int height, unsigned int width, Type value);
157  vpImage(Type *const array, unsigned int height, unsigned int width, bool copyData = false);
159  virtual ~vpImage();
160 
163 
164  // destructor
165  void destroy();
166 
167  // Returns a new image that's double size of the current image
168  void doubleSizeImage(vpImage<Type> &res);
169 
177  inline unsigned int getCols() const { return width; }
186  inline unsigned int getHeight() const { return height; }
187 
188  // Return the maximum value within the bitmap
189  Type getMaxValue() const;
190  // Return the mean value of the bitmap
191  Type getMeanValue() const;
192  // Return the minumum value within the bitmap
193  Type getMinValue() const;
194  // Look for the minumum and the maximum value within the bitmap
195  void getMinMaxValue(Type &min, Type &max) const;
196  // Look for the minumum and the maximum value within the bitmap and get their location
197  void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal = NULL, Type *maxVal = NULL) const;
198 
207  inline unsigned int getNumberOfPixel() const { return npixels; }
208 
216  inline unsigned int getRows() const { return height; }
217 
225  inline unsigned int getSize() const { return width * height; }
226 
227  // Gets the value of a pixel at a location.
228  Type getValue(unsigned int i, unsigned int j) const;
229  // Gets the value of a pixel at a location with bilinear interpolation.
230  Type getValue(double i, double j) const;
231  // Gets the value of a pixel at a location with bilinear interpolation.
232  Type getValue(const vpImagePoint &ip) const;
233 
234  // Get image pixels sum
235  double getSum() const;
236 
244  inline unsigned int getWidth() const { return width; }
245 
246  // Returns a new image that's half size of the current image
247  void halfSizeImage(vpImage<Type> &res) const;
248 
250  void init(unsigned int height, unsigned int width);
252  void init(unsigned int height, unsigned int width, Type value);
254  void init(Type *const array, unsigned int height, unsigned int width, bool copyData = false);
255  void insert(const vpImage<Type> &src, const vpImagePoint &topLeft);
256 
257  //------------------------------------------------------------------
258  // Acces to the image
259 
261  inline Type *operator[](unsigned int i) { return row[i]; }
262  inline Type *operator[](int i) { return row[i]; }
263 
265  inline const Type *operator[](unsigned int i) const { return row[i]; }
266  inline const Type *operator[](int i) const { return row[i]; }
267 
274  inline Type operator()(unsigned int i, unsigned int j) const { return bitmap[i * width + j]; }
275 
280  inline void operator()(unsigned int i, unsigned int j, const Type &v) { bitmap[i * width + j] = v; }
281 
292  inline Type operator()(const vpImagePoint &ip) const
293  {
294  unsigned int i = (unsigned int)ip.get_i();
295  unsigned int j = (unsigned int)ip.get_j();
296 
297  return bitmap[i * width + j];
298  }
299 
308  inline void operator()(const vpImagePoint &ip, const Type &v)
309  {
310  unsigned int i = (unsigned int)ip.get_i();
311  unsigned int j = (unsigned int)ip.get_j();
312 
313  bitmap[i * width + j] = v;
314  }
315 
317 
320 
321  vpImage<Type> &operator=(const Type &v);
322  bool operator==(const vpImage<Type> &I);
323  bool operator!=(const vpImage<Type> &I);
324  friend std::ostream &operator<< <>(std::ostream &s, const vpImage<Type> &I);
325  friend std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I);
326  friend std::ostream &operator<<(std::ostream &s, const vpImage<char> &I);
327  friend std::ostream &operator<<(std::ostream &s, const vpImage<float> &I);
328  friend std::ostream &operator<<(std::ostream &s, const vpImage<double> &I);
329 
330  // Perform a look-up table transformation
331  void performLut(const Type (&lut)[256], unsigned int nbThreads = 1);
332 
333  // Returns a new image that's a quarter size of the current image
334  void quarterSizeImage(vpImage<Type> &res) const;
335 
336  // set the size of the image without initializing it.
337  void resize(unsigned int h, unsigned int w);
338  // set the size of the image and initialize it.
339  void resize(unsigned int h, unsigned int w, const Type &val);
340 
341  void sub(const vpImage<Type> &B, vpImage<Type> &C);
342  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
343  void subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const;
344 
345  friend void swap<>(vpImage<Type> &first, vpImage<Type> &second);
346 
348 
349 private:
350  unsigned int npixels;
351  unsigned int width;
352  unsigned int height;
353  Type **row;
354  bool hasOwnership;
355 };
356 
357 template <class Type> std::ostream &operator<<(std::ostream &s, const vpImage<Type> &I)
358 {
359  if (I.bitmap == NULL) {
360  return s;
361  }
362 
363  for (unsigned int i = 0; i < I.getHeight(); i++) {
364  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
365  s << I[i][j] << " ";
366  }
367 
368  // We don't add " " after the last column element
369  s << I[i][I.getWidth() - 1];
370 
371  // We don't add a \n character at the end of the last row line
372  if (i < I.getHeight() - 1) {
373  s << std::endl;
374  }
375  }
376 
377  return s;
378 }
379 
380 inline std::ostream &operator<<(std::ostream &s, const vpImage<unsigned char> &I)
381 {
382  if (I.bitmap == NULL) {
383  return s;
384  }
385 
386  std::ios_base::fmtflags original_flags = s.flags();
387 
388  for (unsigned int i = 0; i < I.getHeight(); i++) {
389  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
390  s << std::setw(3) << static_cast<unsigned>(I[i][j]) << " ";
391  }
392 
393  // We don't add " " after the last column element
394  s << std::setw(3) << static_cast<unsigned>(I[i][I.getWidth() - 1]);
395 
396  // We don't add a \n character at the end of the last row line
397  if (i < I.getHeight() - 1) {
398  s << std::endl;
399  }
400  }
401 
402  s.flags(original_flags); // restore s to standard state
403  return s;
404 }
405 
406 inline std::ostream &operator<<(std::ostream &s, const vpImage<char> &I)
407 {
408  if (I.bitmap == NULL) {
409  return s;
410  }
411 
412  std::ios_base::fmtflags original_flags = s.flags();
413 
414  for (unsigned int i = 0; i < I.getHeight(); i++) {
415  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
416  s << std::setw(4) << static_cast<int>(I[i][j]) << " ";
417  }
418 
419  // We don't add " " after the last column element
420  s << std::setw(4) << static_cast<int>(I[i][I.getWidth() - 1]);
421 
422  // We don't add a \n character at the end of the last row line
423  if (i < I.getHeight() - 1) {
424  s << std::endl;
425  }
426  }
427 
428  s.flags(original_flags); // restore s to standard state
429  return s;
430 }
431 
432 inline std::ostream &operator<<(std::ostream &s, const vpImage<float> &I)
433 {
434  if (I.bitmap == NULL) {
435  return s;
436  }
437 
438  std::ios_base::fmtflags original_flags = s.flags();
439  s.precision(9); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
440 
441  for (unsigned int i = 0; i < I.getHeight(); i++) {
442  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
443  s << I[i][j] << " ";
444  }
445 
446  // We don't add " " after the last column element
447  s << I[i][I.getWidth() - 1];
448 
449  // We don't add a \n character at the end of the last row line
450  if (i < I.getHeight() - 1) {
451  s << std::endl;
452  }
453  }
454 
455  s.flags(original_flags); // restore s to standard state
456  return s;
457 }
458 
459 inline std::ostream &operator<<(std::ostream &s, const vpImage<double> &I)
460 {
461  if (I.bitmap == NULL) {
462  return s;
463  }
464 
465  std::ios_base::fmtflags original_flags = s.flags();
466  s.precision(17); // http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
467 
468  for (unsigned int i = 0; i < I.getHeight(); i++) {
469  for (unsigned int j = 0; j < I.getWidth() - 1; j++) {
470  s << I[i][j] << " ";
471  }
472 
473  // We don't add " " after the last column element
474  s << I[i][I.getWidth() - 1];
475 
476  // We don't add a \n character at the end of the last row line
477  if (i < I.getHeight() - 1) {
478  s << std::endl;
479  }
480  }
481 
482  s.flags(original_flags); // restore s to standard state
483  return s;
484 }
485 
486 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
487 namespace
488 {
489 struct ImageLut_Param_t {
490  unsigned int m_start_index;
491  unsigned int m_end_index;
492 
493  unsigned char m_lut[256];
494  unsigned char *m_bitmap;
495 
496  ImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
497 
498  ImageLut_Param_t(unsigned int start_index, unsigned int end_index, unsigned char *bitmap)
499  : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
500  {
501  }
502 };
503 
504 vpThread::Return performLutThread(vpThread::Args args)
505 {
506  ImageLut_Param_t *imageLut_param = static_cast<ImageLut_Param_t *>(args);
507  unsigned int start_index = imageLut_param->m_start_index;
508  unsigned int end_index = imageLut_param->m_end_index;
509 
510  unsigned char *bitmap = imageLut_param->m_bitmap;
511 
512  unsigned char *ptrStart = bitmap + start_index;
513  unsigned char *ptrEnd = bitmap + end_index;
514  unsigned char *ptrCurrent = ptrStart;
515 
516  // while(ptrCurrent != ptrEnd) {
517  // *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
518  // ++ptrCurrent;
519  // }
520 
521  if (end_index - start_index >= 8) {
522  // Unroll loop version
523  for (; ptrCurrent <= ptrEnd - 8;) {
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  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
534  ++ptrCurrent;
535 
536  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
537  ++ptrCurrent;
538 
539  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
540  ++ptrCurrent;
541 
542  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
543  ++ptrCurrent;
544 
545  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
546  ++ptrCurrent;
547  }
548  }
549 
550  for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
551  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
552  }
553 
554  return 0;
555 }
556 
557 struct ImageLutRGBa_Param_t {
558  unsigned int m_start_index;
559  unsigned int m_end_index;
560 
561  vpRGBa m_lut[256];
562  unsigned char *m_bitmap;
563 
564  ImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(NULL) {}
565 
566  ImageLutRGBa_Param_t(unsigned int start_index, unsigned int end_index, unsigned char *bitmap)
567  : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
568  {
569  }
570 };
571 
572 vpThread::Return performLutRGBaThread(vpThread::Args args)
573 {
574  ImageLutRGBa_Param_t *imageLut_param = static_cast<ImageLutRGBa_Param_t *>(args);
575  unsigned int start_index = imageLut_param->m_start_index;
576  unsigned int end_index = imageLut_param->m_end_index;
577 
578  unsigned char *bitmap = imageLut_param->m_bitmap;
579 
580  unsigned char *ptrStart = bitmap + start_index * 4;
581  unsigned char *ptrEnd = bitmap + end_index * 4;
582  unsigned char *ptrCurrent = ptrStart;
583 
584  if (end_index - start_index >= 4 * 2) {
585  // Unroll loop version
586  for (; ptrCurrent <= ptrEnd - 4 * 2;) {
587  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
588  ptrCurrent++;
589  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
590  ptrCurrent++;
591  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
592  ptrCurrent++;
593  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
594  ptrCurrent++;
595 
596  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
597  ptrCurrent++;
598  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
599  ptrCurrent++;
600  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
601  ptrCurrent++;
602  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
603  ptrCurrent++;
604  }
605  }
606 
607  while (ptrCurrent != ptrEnd) {
608  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
609  ptrCurrent++;
610 
611  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
612  ptrCurrent++;
613 
614  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
615  ptrCurrent++;
616 
617  *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
618  ptrCurrent++;
619  }
620 
621  return 0;
622 }
623 }
624 #endif
625 
639 template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
640 {
641  init(h, w);
642 
643  // for (unsigned int i = 0; i < npixels; i++)
644  // bitmap[i] = value;
645  std::fill(bitmap, bitmap + npixels, value);
646 }
647 
665 template <class Type> void vpImage<Type>::init(unsigned int h, unsigned int w)
666 {
667  if (h != this->height) {
668  if (row != NULL) {
669  vpDEBUG_TRACE(10, "Destruction row[]");
670  delete[] row;
671  row = NULL;
672  }
673  }
674 
675  if ((h != this->height) || (w != this->width)) {
676  if (bitmap != NULL) {
677  vpDEBUG_TRACE(10, "Destruction bitmap[]");
678  if (hasOwnership) {
679  delete[] bitmap;
680  }
681  bitmap = NULL;
682  }
683  }
684 
685  this->width = w;
686  this->height = h;
687 
688  npixels = width * height;
689 
690  if (bitmap == NULL) {
691  bitmap = new Type[npixels];
692  hasOwnership = true;
693  }
694 
695  if (bitmap == NULL) {
696  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
697  }
698 
699  if (row == NULL)
700  row = new Type *[height];
701  if (row == NULL) {
702  throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
703  }
704 
705  for (unsigned int i = 0; i < height; i++)
706  row[i] = bitmap + i * width;
707 }
708 
722 template <class Type>
723 void vpImage<Type>::init(Type *const array, unsigned int h, unsigned int w, bool copyData)
724 {
725  if (h != this->height) {
726  if (row != NULL) {
727  delete[] row;
728  row = NULL;
729  }
730  }
731 
732  // Delete bitmap if copyData==false, otherwise only if the dimension differs
733  if ((copyData && ((h != this->height) || (w != this->width))) || !copyData) {
734  if (bitmap != NULL) {
735  if (hasOwnership) {
736  delete[] bitmap;
737  }
738  bitmap = NULL;
739  }
740  }
741 
742  hasOwnership = copyData;
743  this->width = w;
744  this->height = h;
745 
746  npixels = width * height;
747 
748  if (copyData) {
749  if (bitmap == NULL)
750  bitmap = new Type[npixels];
751 
752  if (bitmap == NULL) {
753  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
754  }
755 
756  // Copy the image data
757  memcpy(static_cast<void*>(bitmap), static_cast<void*>(array), (size_t)(npixels * sizeof(Type)));
758  } else {
759  // Copy the address of the array in the bitmap
760  bitmap = array;
761  }
762 
763  if (row == NULL)
764  row = new Type *[height];
765  if (row == NULL) {
766  throw(vpException(vpException::memoryAllocationError, "cannot allocate row "));
767  }
768 
769  for (unsigned int i = 0; i < height; i++) {
770  row[i] = bitmap + i * width;
771  }
772 }
773 
792 template <class Type>
793 vpImage<Type>::vpImage(unsigned int h, unsigned int w)
794  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
795 {
796  init(h, w, 0);
797 }
798 
816 template <class Type>
817 vpImage<Type>::vpImage(unsigned int h, unsigned int w, Type value)
818  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
819 {
820  init(h, w, value);
821 }
822 
838 template <class Type>
839 vpImage<Type>::vpImage(Type *const array, unsigned int h, unsigned int w, bool copyData)
840  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
841 {
842  init(array, h, w, copyData);
843 }
844 
854 template <class Type> vpImage<Type>::vpImage() :
855  bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
856 {
857 }
858 
879 template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w) { init(h, w); }
880 
900 template <class Type> void vpImage<Type>::resize(unsigned int h, unsigned int w, const Type &val) { init(h, w, val); }
901 
908 template <class Type> void vpImage<Type>::destroy()
909 {
910  // vpERROR_TRACE("Deallocate ");
911 
912  if (bitmap != NULL) {
913  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap);
914  // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap);
915  if (hasOwnership) {
916  delete[] bitmap;
917  }
918  bitmap = NULL;
919  }
920 
921  if (row != NULL) {
922  // vpERROR_TRACE("Deallocate row memory %p",row);
923  // vpDEBUG_TRACE(20,"Deallocate row memory %p",row);
924  delete[] row;
925  row = NULL;
926  }
927 }
928 
935 template <class Type> vpImage<Type>::~vpImage() { destroy(); }
936 
940 template <class Type>
942  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL), hasOwnership(true)
943 {
944  resize(I.getHeight(), I.getWidth());
945  memcpy(static_cast<void*>(bitmap), static_cast<void*>(I.bitmap), I.npixels * sizeof(Type));
946 }
947 
948 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
949 
952 template <class Type>
954  : bitmap(I.bitmap), display(I.display), npixels(I.npixels), width(I.width), height(I.height), row(I.row), hasOwnership(I.hasOwnership)
955 {
956  I.bitmap = NULL;
957  I.display = NULL;
958  I.npixels = 0;
959  I.width = 0;
960  I.height = 0;
961  I.row = NULL;
962  I.hasOwnership = false;
963 }
964 #endif
965 
971 template <class Type> Type vpImage<Type>::getMaxValue() const
972 {
973  if (npixels == 0)
974  throw(vpException(vpException::fatalError, "Cannot compute maximum value of an empty image"));
975  Type m = bitmap[0];
976  for (unsigned int i = 0; i < npixels; i++) {
977  if (bitmap[i] > m)
978  m = bitmap[i];
979  }
980  return m;
981 }
982 
986 template <class Type> Type vpImage<Type>::getMeanValue() const
987 {
988  if ((height == 0) || (width == 0))
989  return 0.0;
990 
991  return getSum() / (height * width);
992 }
993 
999 template <class Type> Type vpImage<Type>::getMinValue() const
1000 {
1001  if (npixels == 0)
1002  throw(vpException(vpException::fatalError, "Cannot compute minimum value of an empty image"));
1003  Type m = bitmap[0];
1004  for (unsigned int i = 0; i < npixels; i++)
1005  if (bitmap[i] < m)
1006  m = bitmap[i];
1007  return m;
1008 }
1009 
1017 template <class Type> void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
1018 {
1019  if (npixels == 0)
1020  throw(vpException(vpException::fatalError, "Cannot get minimum/maximum values of an empty image"));
1021 
1022  min = max = bitmap[0];
1023  for (unsigned int i = 0; i < npixels; i++) {
1024  if (bitmap[i] < min)
1025  min = bitmap[i];
1026  if (bitmap[i] > max)
1027  max = bitmap[i];
1028  }
1029 }
1030 
1052 template <class Type>
1053 void vpImage<Type>::getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal, Type *maxVal) const
1054 {
1055  if (npixels == 0)
1056  throw(vpException(vpException::fatalError, "Cannot get location of minimum/maximum "
1057  "values of an empty image"));
1058 
1059  Type min = bitmap[0], max = bitmap[0];
1060  vpImagePoint minLoc_, maxLoc_;
1061  for (unsigned int i = 0; i < height; i++) {
1062  for (unsigned int j = 0; j < width; j++) {
1063  if (row[i][j] < min) {
1064  min = row[i][j];
1065  minLoc_.set_ij(i, j);
1066  }
1067 
1068  if (row[i][j] > max) {
1069  max = row[i][j];
1070  maxLoc_.set_ij(i, j);
1071  }
1072  }
1073  }
1074 
1075  if (minLoc != NULL)
1076  *minLoc = minLoc_;
1077 
1078  if (maxLoc != NULL)
1079  *maxLoc = maxLoc_;
1080 
1081  if (minVal != NULL)
1082  *minVal = min;
1083 
1084  if (maxVal != NULL)
1085  *maxVal = max;
1086 }
1087 
1092 {
1093  swap(*this, other);
1094  // Swap back display pointer if it was not null
1095  // vpImage<unsigned char> I2(480, 640);
1096  // vpDisplayX d(I2);
1097  // I2 = I1; //copy only the data
1098  if (other.display != NULL)
1099  display = other.display;
1100 
1101  return *this;
1102 }
1103 
1110 template <class Type> vpImage<Type> &vpImage<Type>::operator=(const Type &v)
1111 {
1112  for (unsigned int i = 0; i < npixels; i++)
1113  bitmap[i] = v;
1114 
1115  return *this;
1116 }
1117 
1123 template <class Type> bool vpImage<Type>::operator==(const vpImage<Type> &I)
1124 {
1125  if (this->width != I.getWidth())
1126  return false;
1127  if (this->height != I.getHeight())
1128  return false;
1129 
1130  // printf("wxh: %dx%d bitmap: %p I.bitmap %p\n", width, height, bitmap,
1131  // I.bitmap);
1132  for (unsigned int i = 0; i < npixels; i++) {
1133  if (bitmap[i] != I.bitmap[i]) {
1134  // std::cout << "differ for pixel " << i << " (" << i%this->height
1135  // << ", " << i - i%this->height << ")" << std::endl;
1136  return false;
1137  }
1138  }
1139  return true;
1140 }
1146 template <class Type> bool vpImage<Type>::operator!=(const vpImage<Type> &I)
1147 {
1148  return !(*this == I);
1149 }
1150 
1177 {
1178  vpImage<Type> C;
1179  sub(*this, B, C);
1180  return C;
1181 }
1182 
1194 template <class Type> void vpImage<Type>::insert(const vpImage<Type> &src, const vpImagePoint &topLeft)
1195 {
1196  int itl = (int)topLeft.get_i();
1197  int jtl = (int)topLeft.get_j();
1198 
1199  int dest_ibegin = 0;
1200  int dest_jbegin = 0;
1201  int src_ibegin = 0;
1202  int src_jbegin = 0;
1203  int dest_w = (int)this->getWidth();
1204  int dest_h = (int)this->getHeight();
1205  int src_w = (int)src.getWidth();
1206  int src_h = (int)src.getHeight();
1207  int wsize = (int)src.getWidth();
1208  int hsize = (int)src.getHeight();
1209 
1210  if (itl >= dest_h || jtl >= dest_w)
1211  return;
1212 
1213  if (itl < 0)
1214  src_ibegin = -itl;
1215  else
1216  dest_ibegin = itl;
1217 
1218  if (jtl < 0)
1219  src_jbegin = -jtl;
1220  else
1221  dest_jbegin = jtl;
1222 
1223  if (src_w - src_jbegin > dest_w - dest_jbegin)
1224  wsize = dest_w - dest_jbegin;
1225  else
1226  wsize = src_w - src_jbegin;
1227 
1228  if (src_h - src_ibegin > dest_h - dest_ibegin)
1229  hsize = dest_h - dest_ibegin;
1230  else
1231  hsize = src_h - src_ibegin;
1232 
1233  for (int i = 0; i < hsize; i++) {
1234  Type *srcBitmap = src.bitmap + ((src_ibegin + i) * src_w + src_jbegin);
1235  Type *destBitmap = this->bitmap + ((dest_ibegin + i) * dest_w + dest_jbegin);
1236 
1237  memcpy(static_cast<void*>(destBitmap), static_cast<void*>(srcBitmap), (size_t)wsize * sizeof(Type));
1238  }
1239 }
1240 
1271 template <class Type> void vpImage<Type>::halfSizeImage(vpImage<Type> &res) const
1272 {
1273  unsigned int h = height / 2;
1274  unsigned int w = width / 2;
1275  res.resize(h, w);
1276  for (unsigned int i = 0; i < h; i++)
1277  for (unsigned int j = 0; j < w; j++)
1278  res[i][j] = (*this)[i << 1][j << 1];
1279 }
1280 
1298 template <class Type>
1299 void vpImage<Type>::subsample(unsigned int v_scale, unsigned int h_scale, vpImage<Type> &sampled) const
1300 {
1301  unsigned int h = height / v_scale;
1302  unsigned int w = width / h_scale;
1303  sampled.resize(h, w);
1304  for (unsigned int i = 0; i < h; i++)
1305  for (unsigned int j = 0; j < w; j++)
1306  sampled[i][j] = (*this)[i * v_scale][j * h_scale];
1307 }
1308 
1331 template <class Type> void vpImage<Type>::quarterSizeImage(vpImage<Type> &res) const
1332 {
1333  unsigned int h = height / 4;
1334  unsigned int w = width / 4;
1335  res.resize(h, w);
1336  for (unsigned int i = 0; i < h; i++)
1337  for (unsigned int j = 0; j < w; j++)
1338  res[i][j] = (*this)[i << 2][j << 2];
1339 }
1340 
1373 template <class Type> void vpImage<Type>::doubleSizeImage(vpImage<Type> &res)
1374 {
1375  int h = height * 2;
1376  int w = width * 2;
1377 
1378  res.resize(h, w);
1379 
1380  for (int i = 0; i < h; i++)
1381  for (int j = 0; j < w; j++)
1382  res[i][j] = (*this)[i >> 1][j >> 1];
1383 
1384  /*
1385  A B C
1386  E F G
1387  H I J
1388  A C H J are pixels from original image
1389  B E G I are interpolated pixels
1390  */
1391 
1392  // interpolate pixels B and I
1393  for (int i = 0; i < h; i += 2)
1394  for (int j = 1; j < w - 1; j += 2)
1395  res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1]));
1396 
1397  // interpolate pixels E and G
1398  for (int i = 1; i < h - 1; i += 2)
1399  for (int j = 0; j < w; j += 2)
1400  res[i][j] = (Type)(0.5 * ((*this)[i >> 1][j >> 1] + (*this)[(i >> 1) + 1][j >> 1]));
1401 
1402  // interpolate pixel F
1403  for (int i = 1; i < h - 1; i += 2)
1404  for (int j = 1; j < w - 1; j += 2)
1405  res[i][j] = (Type)(0.25 * ((*this)[i >> 1][j >> 1] + (*this)[i >> 1][(j >> 1) + 1] +
1406  (*this)[(i >> 1) + 1][j >> 1] + (*this)[(i >> 1) + 1][(j >> 1) + 1]));
1407 }
1408 
1422 template <class Type> inline Type vpImage<Type>::getValue(unsigned int i, unsigned int j) const
1423 {
1424  if (i >= height || j >= width) {
1425  throw(vpException(vpImageException::notInTheImage, "Pixel outside the image"));
1426  }
1427 
1428  return row[i][j];
1429 }
1430 
1448 template <class Type> Type vpImage<Type>::getValue(double i, double j) const
1449 {
1450  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1451  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1452  }
1453  if (height * width == 0) {
1454  throw vpException(vpImageException::notInitializedError, "Empty image!");
1455  }
1456 
1457  unsigned int iround = static_cast<unsigned int>(floor(i));
1458  unsigned int jround = static_cast<unsigned int>(floor(j));
1459 
1460  double rratio = i - static_cast<double>(iround);
1461  double cratio = j - static_cast<double>(jround);
1462 
1463  double rfrac = 1.0 - rratio;
1464  double cfrac = 1.0 - cratio;
1465 
1466  unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1467  unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1468 
1469  double value = (static_cast<double>(row[iround][jround]) * rfrac + static_cast<double>(row[iround_1][jround]) * rratio) * cfrac +
1470  (static_cast<double>(row[iround][jround_1]) * rfrac + static_cast<double>(row[iround_1][jround_1]) * rratio) * cratio;
1471 
1472  return static_cast<Type>(vpMath::round(value));
1473 }
1474 
1491 template <> inline double vpImage<double>::getValue(double i, double j) const
1492 {
1493  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1494  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1495  }
1496  if (height * width == 0) {
1497  throw vpException(vpImageException::notInitializedError, "Empty image!");
1498  }
1499 
1500  unsigned int iround = static_cast<unsigned int>(floor(i));
1501  unsigned int jround = static_cast<unsigned int>(floor(j));
1502 
1503  double rratio = i - static_cast<double>(iround);
1504  double cratio = j - static_cast<double>(jround);
1505 
1506  double rfrac = 1.0 - rratio;
1507  double cfrac = 1.0 - cratio;
1508 
1509  unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1510  unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1511 
1512  return (row[iround][jround] * rfrac + row[iround_1][jround] * rratio) * cfrac +
1513  (row[iround][jround_1] * rfrac + row[iround_1][jround_1] * rratio) * cratio;
1514 }
1515 
1516 template <> inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const {
1517  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1518  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1519  }
1520  if (height * width == 0) {
1521  throw vpException(vpImageException::notInitializedError, "Empty image!");
1522  }
1523 
1524  //Fixed-point arithmetic
1525  const int precision = 1 << 16;
1526  int64_t y = static_cast<int64_t>(i * precision);
1527  int64_t x = static_cast<int64_t>(j * precision);
1528 
1529  int64_t iround = y & (~0xFFFF);
1530  int64_t jround = x & (~0xFFFF);
1531 
1532  int64_t rratio = y - iround;
1533  int64_t cratio = x - jround;
1534 
1535  int64_t rfrac = precision - rratio;
1536  int64_t cfrac = precision - cratio;
1537 
1538  int64_t x_ = x >> 16;
1539  int64_t y_ = y >> 16;
1540 
1541  if (y_ + 1 < height && x_ + 1 < width) {
1542  uint16_t up = *reinterpret_cast<uint16_t *>(bitmap + y_ * width + x_);
1543  uint16_t down = *reinterpret_cast<uint16_t *>(bitmap + (y_ + 1) * width + x_);
1544 
1545  return static_cast<unsigned char>((((up & 0x00FF) * rfrac + (down & 0x00FF) * rratio) * cfrac +
1546  ((up >> 8) * rfrac + (down >> 8) * rratio) * cratio) >> 32);
1547  } else if (y_ + 1 < height) {
1548  return static_cast<unsigned char>(((row[y_][x_] * rfrac + row[y_ + 1][x_] * rratio)) >> 16);
1549  } else if (x_ + 1 < width) {
1550  uint16_t up = *reinterpret_cast<uint16_t *>(bitmap + y_ * width + x_);
1551  return static_cast<unsigned char>(((up & 0x00FF) * cfrac + (up >> 8) * cratio) >> 16);
1552  } else {
1553  return row[y_][x_];
1554  }
1555 }
1556 
1557 template <> inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1558 {
1559  if (i < 0 || j < 0 || i+1 > height || j+1 > width) {
1560  throw(vpException(vpImageException::notInTheImage, "Pixel outside of the image"));
1561  }
1562  if (height * width == 0) {
1563  throw vpException(vpImageException::notInitializedError, "Empty image!");
1564  }
1565 
1566  unsigned int iround = static_cast<unsigned int>(floor(i));
1567  unsigned int jround = static_cast<unsigned int>(floor(j));
1568 
1569  double rratio = i - static_cast<double>(iround);
1570  double cratio = j - static_cast<double>(jround);
1571 
1572  double rfrac = 1.0 - rratio;
1573  double cfrac = 1.0 - cratio;
1574 
1575  unsigned int iround_1 = (std::min)(height - 1, iround + 1);
1576  unsigned int jround_1 = (std::min)(width - 1, jround + 1);
1577 
1578  double valueR = (static_cast<double>(row[iround][jround].R) * rfrac + static_cast<double>(row[iround_1][jround].R) * rratio) * cfrac +
1579  (static_cast<double>(row[iround][jround_1].R) * rfrac + static_cast<double>(row[iround_1][jround_1].R) * rratio) * cratio;
1580  double valueG = (static_cast<double>(row[iround][jround].G) * rfrac + static_cast<double>(row[iround_1][jround].G) * rratio) * cfrac +
1581  (static_cast<double>(row[iround][jround_1].G) * rfrac + static_cast<double>(row[iround_1][jround_1].G) * rratio) * cratio;
1582  double valueB = (static_cast<double>(row[iround][jround].B) * rfrac + static_cast<double>(row[iround_1][jround].B) * rratio) * cfrac +
1583  (static_cast<double>(row[iround][jround_1].B) * rfrac + static_cast<double>(row[iround_1][jround_1].B) * rratio) * cratio;
1584 
1585  return vpRGBa(static_cast<unsigned char>(vpMath::round(valueR)),
1586  static_cast<unsigned char>(vpMath::round(valueG)),
1587  static_cast<unsigned char>(vpMath::round(valueB)));
1588 }
1589 
1606 template <class Type> inline Type vpImage<Type>::getValue(const vpImagePoint &ip) const
1607 {
1608  return getValue(ip.get_i(), ip.get_j());
1609 }
1610 
1611 template <> inline double vpImage<double>::getValue(const vpImagePoint &ip) const
1612 {
1613  return getValue(ip.get_i(), ip.get_j());
1614 }
1615 
1616 template <> inline unsigned char vpImage<unsigned char>::getValue(const vpImagePoint &ip) const
1617 {
1618  return getValue(ip.get_i(), ip.get_j());
1619 }
1620 
1621 template <> inline vpRGBa vpImage<vpRGBa>::getValue(const vpImagePoint &ip) const
1622 {
1623  return getValue(ip.get_i(), ip.get_j());
1624 }
1625 
1629 template <class Type> inline double vpImage<Type>::getSum() const
1630 {
1631  if ((height == 0) || (width == 0))
1632  return 0.0;
1633 
1634  double res = 0.0;
1635  for (unsigned int i = 0; i < height * width; ++i) {
1636  res += static_cast<double>(bitmap[i]);
1637  }
1638  return res;
1639 }
1640 
1670 template <class Type> void vpImage<Type>::sub(const vpImage<Type> &B, vpImage<Type> &C)
1671 {
1672 
1673  try {
1674  if ((this->getHeight() != C.getHeight()) || (this->getWidth() != C.getWidth()))
1675  C.resize(this->getHeight(), this->getWidth());
1676  } catch (const vpException &me) {
1677  std::cout << me << std::endl;
1678  throw;
1679  }
1680 
1681  if ((this->getWidth() != B.getWidth()) || (this->getHeight() != B.getHeight())) {
1682  throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage substraction "));
1683  }
1684 
1685  for (unsigned int i = 0; i < this->getWidth() * this->getHeight(); i++) {
1686  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i);
1687  }
1688 }
1689 
1701 template <class Type> void vpImage<Type>::sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C)
1702 {
1703 
1704  try {
1705  if ((A.getHeight() != C.getHeight()) || (A.getWidth() != C.getWidth()))
1706  C.resize(A.getHeight(), A.getWidth());
1707  } catch (const vpException &me) {
1708  std::cout << me << std::endl;
1709  throw;
1710  }
1711 
1712  if ((A.getWidth() != B.getWidth()) || (A.getHeight() != B.getHeight())) {
1713  throw(vpException(vpException::memoryAllocationError, "vpImage mismatch in vpImage/vpImage substraction "));
1714  }
1715 
1716  for (unsigned int i = 0; i < A.getWidth() * A.getHeight(); i++) {
1717  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i);
1718  }
1719 }
1720 
1731 template <class Type> void vpImage<Type>::performLut(const Type (&)[256], const unsigned int)
1732 {
1733  std::cerr << "Not implemented !" << std::endl;
1734 }
1735 
1744 template <>
1745 inline void vpImage<unsigned char>::performLut(const unsigned char (&lut)[256], unsigned int nbThreads)
1746 {
1747  unsigned int size = getWidth() * getHeight();
1748  unsigned char *ptrStart = (unsigned char *)bitmap;
1749  unsigned char *ptrEnd = ptrStart + size;
1750  unsigned char *ptrCurrent = ptrStart;
1751 
1752  bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1753 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1754  use_single_thread = true;
1755 #endif
1756 
1757  if (!use_single_thread && getSize() <= nbThreads) {
1758  use_single_thread = true;
1759  }
1760 
1761  if (use_single_thread) {
1762  // Single thread
1763 
1764  while (ptrCurrent != ptrEnd) {
1765  *ptrCurrent = lut[*ptrCurrent];
1766  ++ptrCurrent;
1767  }
1768  } else {
1769 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1770  // Multi-threads
1771 
1772  std::vector<vpThread *> threadpool;
1773  std::vector<ImageLut_Param_t *> imageLutParams;
1774 
1775  unsigned int image_size = getSize();
1776  unsigned int step = image_size / nbThreads;
1777  unsigned int last_step = image_size - step * (nbThreads - 1);
1778 
1779  for (unsigned int index = 0; index < nbThreads; index++) {
1780  unsigned int start_index = index * step;
1781  unsigned int end_index = (index + 1) * step;
1782 
1783  if (index == nbThreads - 1) {
1784  end_index = start_index + last_step;
1785  }
1786 
1787  ImageLut_Param_t *imageLut_param = new ImageLut_Param_t(start_index, end_index, bitmap);
1788  memcpy(imageLut_param->m_lut, lut, 256 * sizeof(unsigned char));
1789 
1790  imageLutParams.push_back(imageLut_param);
1791 
1792  // Start the threads
1793  vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutThread, (vpThread::Args)imageLut_param);
1794  threadpool.push_back(imageLut_thread);
1795  }
1796 
1797  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1798  // Wait until thread ends up
1799  threadpool[cpt]->join();
1800  }
1801 
1802  // Delete
1803  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1804  delete threadpool[cpt];
1805  }
1806 
1807  for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1808  delete imageLutParams[cpt];
1809  }
1810 #endif
1811  }
1812 }
1813 
1822 template <> inline void vpImage<vpRGBa>::performLut(const vpRGBa (&lut)[256], unsigned int nbThreads)
1823 {
1824  unsigned int size = getWidth() * getHeight();
1825  unsigned char *ptrStart = (unsigned char *)bitmap;
1826  unsigned char *ptrEnd = ptrStart + size * 4;
1827  unsigned char *ptrCurrent = ptrStart;
1828 
1829  bool use_single_thread = (nbThreads == 0 || nbThreads == 1);
1830 #if !defined(VISP_HAVE_PTHREAD) && !defined(_WIN32)
1831  use_single_thread = true;
1832 #endif
1833 
1834  if (!use_single_thread && getSize() <= nbThreads) {
1835  use_single_thread = true;
1836  }
1837 
1838  if (use_single_thread) {
1839  // Single thread
1840  while (ptrCurrent != ptrEnd) {
1841  *ptrCurrent = lut[*ptrCurrent].R;
1842  ++ptrCurrent;
1843 
1844  *ptrCurrent = lut[*ptrCurrent].G;
1845  ++ptrCurrent;
1846 
1847  *ptrCurrent = lut[*ptrCurrent].B;
1848  ++ptrCurrent;
1849 
1850  *ptrCurrent = lut[*ptrCurrent].A;
1851  ++ptrCurrent;
1852  }
1853  } else {
1854 #if defined(VISP_HAVE_PTHREAD) || (defined(_WIN32) && !defined(WINRT_8_0))
1855  // Multi-threads
1856  std::vector<vpThread *> threadpool;
1857  std::vector<ImageLutRGBa_Param_t *> imageLutParams;
1858 
1859  unsigned int image_size = getSize();
1860  unsigned int step = image_size / nbThreads;
1861  unsigned int last_step = image_size - step * (nbThreads - 1);
1862 
1863  for (unsigned int index = 0; index < nbThreads; index++) {
1864  unsigned int start_index = index * step;
1865  unsigned int end_index = (index + 1) * step;
1866 
1867  if (index == nbThreads - 1) {
1868  end_index = start_index + last_step;
1869  }
1870 
1871  ImageLutRGBa_Param_t *imageLut_param = new ImageLutRGBa_Param_t(start_index, end_index, (unsigned char *)bitmap);
1872  memcpy(imageLut_param->m_lut, lut, 256 * sizeof(vpRGBa));
1873 
1874  imageLutParams.push_back(imageLut_param);
1875 
1876  // Start the threads
1877  vpThread *imageLut_thread = new vpThread((vpThread::Fn)performLutRGBaThread, (vpThread::Args)imageLut_param);
1878  threadpool.push_back(imageLut_thread);
1879  }
1880 
1881  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1882  // Wait until thread ends up
1883  threadpool[cpt]->join();
1884  }
1885 
1886  // Delete
1887  for (size_t cpt = 0; cpt < threadpool.size(); cpt++) {
1888  delete threadpool[cpt];
1889  }
1890 
1891  for (size_t cpt = 0; cpt < imageLutParams.size(); cpt++) {
1892  delete imageLutParams[cpt];
1893  }
1894 #endif
1895  }
1896 }
1897 
1898 template <class Type> void swap(vpImage<Type> &first, vpImage<Type> &second)
1899 {
1900  using std::swap;
1901  swap(first.bitmap, second.bitmap);
1902  swap(first.display, second.display);
1903  swap(first.npixels, second.npixels);
1904  swap(first.width, second.width);
1905  swap(first.height, second.height);
1906  swap(first.row, second.row);
1907 }
1908 
1909 #endif
Type * operator[](int i)
Definition: vpImage.h:262
vpDisplay * display
Definition: vpImage.h:142
void performLut(const Type(&lut)[256], unsigned int nbThreads=1)
Definition: vpImage.h:1731
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1373
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:1271
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:1053
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:999
void * Return
Definition: vpThread.h:78
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:665
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:879
Type getValue(unsigned int i, unsigned int j) const
Definition: vpImage.h:1422
unsigned int getRows() const
Definition: vpImage.h:216
Type * bitmap
points toward the bitmap
Definition: vpImage.h:141
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
Definition: vpImage.h:1299
void operator()(unsigned int i, unsigned int j, const Type &v)
Definition: vpImage.h:280
error that can be emited by ViSP classes.
Definition: vpException.h:71
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:292
double getSum() const
Definition: vpImage.h:1629
virtual ~vpImage()
destructor
Definition: vpImage.h:935
vpImage< Type > & operator=(vpImage< Type > other)
Copy operator.
Definition: vpImage.h:1091
Definition: vpRGBa.h:66
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:265
friend void swap(vpImage< Type > &first, vpImage< Type > &second)
Definition: vpImage.h:1898
void *(* Fn)(Args)
Definition: vpThread.h:79
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:1146
void * Args
Definition: vpThread.h:77
Memory allocation error.
Definition: vpException.h:88
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:308
double get_j() const
Definition: vpImagePoint.h:215
unsigned int getCols() const
Definition: vpImage.h:177
Type operator()(unsigned int i, unsigned int j) const
Definition: vpImage.h:274
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:971
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:1194
void destroy()
Destructor : Memory de-allocation.
Definition: vpImage.h:908
const Type * operator[](int i) const
Definition: vpImage.h:266
void quarterSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1331
Type * operator[](unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:261
unsigned int getNumberOfPixel() const
Definition: vpImage.h:207
Type getMeanValue() const
Return the mean value of the bitmap.
Definition: vpImage.h:986
static int round(double x)
Definition: vpMath.h:241
void set_ij(double ii, double jj)
Definition: vpImagePoint.h:189
unsigned int getHeight() const
Definition: vpImage.h:186
unsigned int getSize() const
Definition: vpImage.h:225
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:1176
#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
vpImage()
constructor
Definition: vpImage.h:854
unsigned int getWidth() const
Definition: vpImage.h:244
Definition of the vpImage class member functions.
Definition: vpImage.h:124
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:1123
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:1017
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1670