Visual Servoing Platform  version 3.0.0
vpImage.h
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Image handling.
32  *
33  * Authors:
34  * Eric Marchand
35  *
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 
54 #include <fstream>
55 #include <iostream>
56 #include <math.h>
57 #include <string.h>
58 
59 class vpDisplay;
60 
110 template<class Type>
111 class vpImage
112 {
113  friend class vpImageConvert;
114 
115 public:
116  Type *bitmap ;
118 
120  vpImage() ;
122  vpImage(const vpImage<Type>&);
124  vpImage(unsigned int height, unsigned int width) ;
126  vpImage(unsigned int height, unsigned int width, Type value) ;
128  vpImage(Type * const array, const unsigned int height, const unsigned int width, const bool copyData=false) ;
130  virtual ~vpImage() ;
132  void init(unsigned int height, unsigned int width) ;
134  void init(unsigned int height, unsigned int width, Type value) ;
136  void init(Type * const array, const unsigned int height, const unsigned int width, const bool copyData=false);
138  void resize(const unsigned int h, const unsigned int w) ;
140  void resize(const unsigned int h, const unsigned int w, const Type val) ;
142  void destroy() ;
143 
152  inline unsigned int getHeight() const { return height; }
161  inline unsigned int getWidth() const { return width; }
162 
171  inline unsigned int getRows() const { return height ; }
172 
180  inline unsigned int getCols() const { return width ; }
181 
189  inline unsigned int getSize() const { return width*height ; }
190 
191 
192  // Return the maximum value within the bitmap
193  Type getMaxValue() const ;
194  // Return the minumum value within the bitmap
195  Type getMinValue() const ;
196  //Look for the minumum and the maximum value within the bitmap
197  void getMinMaxValue(Type &min, Type &max) const;
198 
199  // Gets the value of a pixel at a location with bilinear interpolation.
200  Type getValue(double i, double j) const;
201  // Gets the value of a pixel at a location with bilinear interpolation.
202  Type getValue(vpImagePoint &ip) const;
203 
214  inline unsigned int getNumberOfPixel() const{ return npixels; }
215 
216  //------------------------------------------------------------------
217  // Acces to the image
218 
219 
221  inline Type *operator[]( const unsigned int i) { return row[i];}
222  inline Type *operator[]( const int i) { return row[i];}
223 
225  inline const Type *operator[](unsigned int i) const { return row[i];}
226  inline const Type *operator[](int i) const { return row[i];}
227 
237  inline Type operator()(const unsigned int i, const unsigned int j) const
238  {
239  return bitmap[i*width+j] ;
240  }
250  inline void operator()(const unsigned int i, const unsigned int j,
251  const Type &v)
252  {
253  bitmap[i*width+j] = v ;
254  }
266  inline Type operator()(const vpImagePoint &ip) const
267  {
268  unsigned int i = (unsigned int) ip.get_i();
269  unsigned int j = (unsigned int) ip.get_j();
270 
271  return bitmap[i*width+j] ;
272  }
282  inline void operator()(const vpImagePoint &ip,
283  const Type &v)
284  {
285  unsigned int i = (unsigned int) ip.get_i();
286  unsigned int j = (unsigned int) ip.get_j();
287 
288  bitmap[i*width+j] = v ;
289  }
290 
292 
295 
296  vpImage<Type>& operator=(const Type &v);
297  bool operator==(const vpImage<Type> &I);
298  bool operator!=(const vpImage<Type> &I);
299 
300  void insert(const vpImage<Type> &src, const vpImagePoint topLeft);
301 
302 
303  // Returns a new image that's half size of the current image
304  void halfSizeImage(vpImage<Type> &res);
305 
306  // Returns a new image that's a quarter size of the current image
307  void quarterSizeImage(vpImage<Type> &res);
308 
309  // Returns a new image that's double size of the current image
310  void doubleSizeImage(vpImage<Type> &res);
311 
312  void sub(const vpImage<Type> &B, vpImage<Type> &C);
313  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
314 
315  // Perform a look-up table transformation
316  void performLut(const Type (&lut)[256]);
317 
318 private:
319  unsigned int npixels ; //<! number of pixel in the image
320  unsigned int width ; //<! number of columns
321  unsigned int height ; //<! number of rows
322  Type **row ;
323  } ;
324 
325 
339 template<class Type>
340 void
341 vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
342 {
343  try
344  {
345  init(h,w) ;
346  }
347  catch(vpException &)
348  {
349  vpERROR_TRACE(" ") ;
350  throw ;
351  }
352 
353  for (unsigned int i=0 ; i < npixels ; i++)
354  bitmap[i] = value ;
355 }
356 
357 
375 template<class Type>
376 void
377 vpImage<Type>::init(unsigned int h, unsigned int w)
378 {
379  if (h != this->height) {
380  if (row != NULL) {
381  vpDEBUG_TRACE(10,"Destruction row[]");
382  delete [] row;
383  row = NULL;
384  }
385  }
386 
387  if ((h != this->height) || (w != this->width))
388  {
389  if (bitmap != NULL) {
390  vpDEBUG_TRACE(10,"Destruction bitmap[]") ;
391  delete [] bitmap;
392  bitmap = NULL;
393  }
394  }
395 
396  this->width = w ;
397  this->height = h;
398 
399  npixels=width*height;
400 
401  if (bitmap == NULL) bitmap = new Type[npixels] ;
402 
403  // vpERROR_TRACE("Allocate bitmap %p",bitmap) ;
404  if (bitmap == NULL)
405  {
406  vpERROR_TRACE("cannot allocate bitmap ") ;
408  "cannot allocate bitmap ")) ;
409  }
410 
411  if (row == NULL) row = new Type*[height] ;
412 // vpERROR_TRACE("Allocate row %p",row) ;
413  if (row == NULL)
414  {
415  vpERROR_TRACE("cannot allocate row ") ;
417  "cannot allocate row ")) ;
418  }
419 
420  unsigned int i ;
421  for ( i =0 ; i < height ; i++)
422  row[i] = bitmap + i*width ;
423 }
424 
437 template<class Type>
438 void
439 vpImage<Type>::init(Type * const array, const unsigned int h, const unsigned int w, const bool copyData)
440 {
441  if (h != this->height) {
442  if (row != NULL) {
443  delete [] row;
444  row = NULL;
445  }
446  }
447 
448  //Delete bitmap if copyData==false, otherwise only if the dimension differs
449  if ( (copyData && ((h != this->height) || (w != this->width))) || !copyData ) {
450  if (bitmap != NULL) {
451  delete [] bitmap;
452  bitmap = NULL;
453  }
454  }
455 
456  this->width = w ;
457  this->height = h;
458 
459  npixels = width*height;
460 
461  if(copyData) {
462  if (bitmap == NULL) bitmap = new Type[npixels];
463 
464  if (bitmap == NULL) {
466  "cannot allocate bitmap ")) ;
467  }
468 
469  //Copy the image data
470  memcpy(bitmap, array, (size_t) (npixels * sizeof(Type)));
471  } else {
472  //Copy the address of the array in the bitmap
473  bitmap = array;
474  }
475 
476  if (row == NULL) row = new Type*[height];
477  if (row == NULL) {
479  "cannot allocate row ")) ;
480  }
481 
482  for (unsigned int i = 0 ; i < height ; i++) {
483  row[i] = bitmap + i*width;
484  }
485 }
486 
505 template<class Type>
506 vpImage<Type>::vpImage(unsigned int h, unsigned int w)
507  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
508 {
509  try
510  {
511  init(h,w,0) ;
512  }
513  catch(...)
514  {
515  throw ;
516  }
517 }
518 
536 template<class Type>
537 vpImage<Type>::vpImage (unsigned int h, unsigned int w, Type value)
538  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
539 {
540  try
541  {
542  init(h,w,value) ;
543  }
544  catch(vpException &)
545  {
546  vpERROR_TRACE(" ") ;
547  throw ;
548  }
549 }
550 
565 template<class Type>
566 vpImage<Type>::vpImage (Type * const array, const unsigned int h, const unsigned int w, const bool copyData)
567  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
568 {
569  try
570  {
571  init(array, h, w, copyData);
572  }
573  catch(vpException &)
574  {
575  throw ;
576  }
577 }
578 
588 template<class Type>
590  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
591 {
592 }
593 
614 template<class Type>
615 void
616 vpImage<Type>::resize(unsigned int h, unsigned int w)
617 {
618  try
619  {
620  init(h, w) ;
621  }
622  catch(vpException &)
623  {
624  vpERROR_TRACE(" ") ;
625  throw ;
626  }
627 }
628 
648 template<class Type>
649 void
650 vpImage<Type>::resize(unsigned int h, unsigned int w, const Type val)
651 {
652  try
653  {
654  init(h, w, val) ;
655  }
656  catch(vpException &)
657  {
658  vpERROR_TRACE(" ") ;
659  throw ;
660  }
661 }
662 
663 
670 template<class Type>
671 void
673 {
674  // vpERROR_TRACE("Deallocate ") ;
675 
676 
677  if (bitmap!=NULL)
678  {
679  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap) ;
680 // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap) ;
681  delete [] bitmap ;
682  bitmap = NULL;
683  }
684 
685 
686  if (row!=NULL)
687  {
688  // vpERROR_TRACE("Deallocate row memory %p",row) ;
689 // vpDEBUG_TRACE(20,"Deallocate row memory %p",row) ;
690  delete [] row ;
691  row = NULL;
692  }
693 
694 }
695 
702 template<class Type>
704 {
705  destroy() ;
706 }
707 
708 
709 
713 template<class Type>
715  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
716 {
717  try
718  {
719  resize(I.getHeight(),I.getWidth());
720  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
721  for (unsigned int i =0 ; i < this->height ; i++) row[i] = bitmap + i*this->width ;
722  }
723  catch(vpException &)
724  {
725  vpERROR_TRACE(" ") ;
726  throw ;
727  }
728 }
729 
735 template<class Type>
737 {
738  Type m = bitmap[0] ;
739  for (unsigned int i=0 ; i < npixels ; i++)
740  {
741  if (bitmap[i]>m) m = bitmap[i] ;
742  }
743  return m ;
744 }
745 
751 template<class Type>
753 {
754  Type m = bitmap[0];
755  for (unsigned int i=0 ; i < npixels ; i++)
756  if (bitmap[i]<m) m = bitmap[i] ;
757  return m ;
758 }
759 
760 
767 template<class Type>
768 void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
769 {
770  min = max = bitmap[0];
771  for (unsigned int i=0 ; i < npixels ; i++)
772  {
773  if (bitmap[i]<min) min = bitmap[i] ;
774  if (bitmap[i]>max) max = bitmap[i] ;
775  }
776 }
777 
781 template<class Type>
783 {
784  /* we first have to set the initial values of the image because resize function calls init function that test the actual size of the image */
785  if(bitmap != NULL){
786  delete[] bitmap;
787  bitmap = NULL ;
788  }
789 
790  if(row != NULL){
791  delete[] row;
792  row = NULL ;
793  }
794  this->width = I.width;
795  this->height = I.height;
796  this->npixels = I.npixels;
797  try
798  {
799  if(I.npixels != 0)
800  {
801  if (bitmap == NULL){
802  bitmap = new Type[npixels] ;
803  }
804 
805  if (bitmap == NULL){
806  vpERROR_TRACE("cannot allocate bitmap ") ;
808  "cannot allocate bitmap ")) ;
809  }
810 
811  if (row == NULL){
812  row = new Type*[height] ;
813  }
814  if (row == NULL){
815  vpERROR_TRACE("cannot allocate row ") ;
817  "cannot allocate row ")) ;
818  }
819 
820  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
821 
822  for (unsigned int i=0; i<this->height; i++){
823  row[i] = bitmap + i*this->width;
824  }
825  }
826  }
827  catch(vpException &)
828  {
829  vpERROR_TRACE(" ") ;
830  throw ;
831  }
832  return (* this);
833 }
834 
835 
842 template<class Type>
844 {
845  for (unsigned int i=0 ; i < npixels ; i++)
846  bitmap[i] = v ;
847 
848  return *this;
849 }
850 
856 template<class Type>
858 {
859  if (this->width != I.getWidth())
860  return false;
861  if (this->height != I.getHeight())
862  return false;
863 
864  for (unsigned int i=0 ; i < npixels ; i++)
865  {
866  if (bitmap[i] != I.bitmap[i])
867  return false;
868  }
869  return true ;
870 }
876 template<class Type>
878 {
879  if (this->width != I.getWidth())
880  return true;
881  if (this->height != I.getHeight())
882  return true;
883 
884  for (unsigned int i=0 ; i < npixels ; i++)
885  {
886  if (bitmap[i] == I.bitmap[i])
887  return false;
888  }
889  return true ;
890 }
891 
917 template<class Type>
919 {
920  vpImage<Type> C;
921  sub(*this,B,C);
922  return C;
923 }
924 
934 template<class Type>
936  const vpImagePoint topLeft)
937 {
938  Type* srcBitmap;
939  Type* destBitmap;
940 
941  int itl = (int)topLeft.get_i();
942  int jtl = (int)topLeft.get_j();
943 
944  int dest_ibegin = 0;
945  int dest_jbegin = 0;
946  int src_ibegin = 0;
947  int src_jbegin = 0;
948  int dest_w = (int)this->getWidth();
949  int dest_h = (int)this->getHeight();
950  int src_w = (int)src.getWidth();
951  int src_h = (int)src.getHeight();
952  int wsize = (int)src.getWidth();
953  int hsize = (int)src.getHeight();
954 
955  if (itl >= dest_h || jtl >= dest_w)
956  return;
957 
958  if (itl < 0)
959  src_ibegin = -itl;
960  else
961  dest_ibegin = itl;
962 
963  if (jtl < 0)
964  src_jbegin = -jtl;
965  else
966  dest_jbegin = jtl;
967 
968  if (src_w - src_jbegin > dest_w - dest_jbegin)
969  wsize = dest_w - dest_jbegin;
970  else
971  wsize = src_w - src_jbegin;
972 
973  if (src_h - src_ibegin > dest_h - dest_ibegin)
974  hsize = dest_h - dest_ibegin;
975  else
976  hsize = src_h - src_ibegin;
977 
978  for (int i = 0; i < hsize; i++)
979  {
980  srcBitmap = src.bitmap + ((src_ibegin+i)*src_w+src_jbegin);
981  destBitmap = this->bitmap + ((dest_ibegin+i)*dest_w+dest_jbegin);
982 
983  memcpy(destBitmap,srcBitmap,wsize*sizeof(Type));
984  }
985 }
986 
1016 template<class Type>
1017 void
1019 {
1020  unsigned int h = height/2;
1021  unsigned int w = width/2;
1022  res.resize(h, w);
1023  for(unsigned int i = 0; i < h; i++)
1024  for(unsigned int j = 0; j < w; j++)
1025  res[i][j] = (*this)[i<<1][j<<1];
1026 }
1027 
1050 template<class Type>
1051 void
1053 {
1054  unsigned int h = height/4;
1055  unsigned int w = width/4;
1056  res.resize(h, w);
1057  for(unsigned int i = 0; i < h; i++)
1058  for(unsigned int j = 0; j < w; j++)
1059  res[i][j] = (*this)[i<<2][j<<2];
1060 }
1061 
1095 template<class Type>
1096 void
1098 {
1099  int h = height*2;
1100  int w = width*2;
1101 
1102  res.resize(h, w);
1103 
1104  for(int i = 0; i < h; i++)
1105  for(int j = 0; j < w; j++)
1106  res[i][j] = (*this)[i>>1][j>>1];
1107 
1108  /*
1109  A B C
1110  E F G
1111  H I J
1112  A C H J are pixels from original image
1113  B E G I are interpolated pixels
1114  */
1115 
1116  //interpolate pixels B and I
1117  for(int i = 0; i < h; i += 2)
1118  for(int j = 1; j < w - 1; j += 2)
1119  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1120  + (*this)[i>>1][(j>>1) + 1]));
1121 
1122  //interpolate pixels E and G
1123  for(int i = 1; i < h - 1; i += 2)
1124  for(int j = 0; j < w; j += 2)
1125  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1126  + (*this)[(i>>1)+1][j>>1]));
1127 
1128  //interpolate pixel F
1129  for(int i = 1; i < h - 1; i += 2)
1130  for(int j = 1; j < w - 1; j += 2)
1131  res[i][j] = (Type)(0.25 * ((*this)[i>>1][j>>1]
1132  + (*this)[i>>1][(j>>1)+1]
1133  + (*this)[(i>>1)+1][j>>1]
1134  + (*this)[(i>>1)+1][(j>>1)+1]));
1135 }
1136 
1147 template<class Type>
1148 Type vpImage<Type>::getValue(double /* i */, double /* j */) const
1149 {
1150  vpTRACE("Not implemented");
1151 }
1152 
1170 template<>
1171 inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const
1172 {
1173  unsigned int iround, jround;
1174  double rfrac, cfrac;
1175 
1176  iround = (unsigned int)floor(i);
1177  jround = (unsigned int)floor(j);
1178 
1179  if (iround >= height || jround >= width) {
1180  vpERROR_TRACE("Pixel outside the image") ;
1182  "Pixel outside the image"));
1183  }
1184 
1185  if (i > height - 1)
1186  i = (double)(height - 1);
1187 
1188  if (j > width - 1)
1189  j = (double)(width - 1);
1190 
1191  double rratio = i - (double) iround;
1192  if(rratio < 0)
1193  rratio=-rratio;
1194  double cratio = j - (double) jround;
1195  if(cratio < 0)
1196  cratio=-cratio;
1197 
1198  rfrac = 1.0f - rratio;
1199  cfrac = 1.0f - cratio;
1200 
1201 
1202  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1203  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1204  return (unsigned char)vpMath::round(value);
1205 }
1206 
1207 
1225 template<>
1226 inline double vpImage<double>::getValue(double i, double j) const
1227 {
1228  unsigned int iround, jround;
1229  double rfrac, cfrac;
1230 
1231  iround = (unsigned int)floor(i);
1232  jround = (unsigned int)floor(j);
1233 
1234  if (iround >= height || jround >= width) {
1235  vpERROR_TRACE("Pixel outside the image") ;
1237  "Pixel outside the image"));
1238  }
1239 
1240  if (i > height - 1)
1241  i = (double)(height - 1);
1242 
1243  if (j > width - 1)
1244  j = (double)(width - 1);
1245 
1246  double rratio = i - (double) iround;
1247  if(rratio < 0)
1248  rratio=-rratio;
1249  double cratio = j - (double) jround;
1250  if(cratio < 0)
1251  cratio=-cratio;
1252 
1253  rfrac = 1.0f - rratio;
1254  cfrac = 1.0f - cratio;
1255 
1256 
1257  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1258  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1259  return value;
1260 }
1261 
1262 template<>
1263 inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1264 {
1265  unsigned int iround, jround;
1266  double rfrac, cfrac;
1267 
1268  iround = (unsigned int)floor(i);
1269  jround = (unsigned int)floor(j);
1270 
1271  if (iround >= height || jround >= width) {
1272  vpERROR_TRACE("Pixel outside the image") ;
1274  "Pixel outside the image"));
1275  }
1276 
1277  if (i > height - 1)
1278  i = (double)(height - 1);
1279 
1280  if (j > width - 1)
1281  j = (double)(width - 1);
1282 
1283  double rratio = i - (double) iround;
1284  if(rratio < 0)
1285  rratio=-rratio;
1286  double cratio = j - (double) jround;
1287  if(cratio < 0)
1288  cratio=-cratio;
1289 
1290  rfrac = 1.0f - rratio;
1291  cfrac = 1.0f - cratio;
1292 
1293  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1294  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1295  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1296  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1297  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1298  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1299  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1300 }
1301 
1312 template<class Type>
1314 {
1315  vpTRACE("Not implemented");
1316 }
1317 
1318 template<>
1319 inline unsigned char vpImage<unsigned char>::getValue(vpImagePoint &ip) const
1320 {
1321  unsigned int iround, jround;
1322  double rfrac, cfrac;
1323 
1324  iround = (unsigned int)floor(ip.get_i());
1325  jround = (unsigned int)floor(ip.get_j());
1326 
1327  if (iround >= height || jround >= width) {
1328  vpERROR_TRACE("Pixel outside the image") ;
1330  "Pixel outside the image"));
1331  }
1332 
1333  if (ip.get_i() > height - 1)
1334  ip.set_i((double)(height - 1));
1335 
1336  if (ip.get_j() > width - 1)
1337  ip.set_j((double)(width - 1));
1338 
1339  double rratio = ip.get_i() - (double) iround;
1340  if(rratio < 0)
1341  rratio=-rratio;
1342  double cratio = ip.get_j() - (double) jround;
1343  if(cratio < 0)
1344  cratio=-cratio;
1345 
1346  rfrac = 1.0f - rratio;
1347  cfrac = 1.0f - cratio;
1348 
1349 
1350  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1351  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1352  return (unsigned char)vpMath::round(value);
1353 }
1354 
1355 
1356 template<>
1357 inline double vpImage<double>::getValue(vpImagePoint &ip) const
1358 {
1359  unsigned int iround, jround;
1360  double rfrac, cfrac;
1361 
1362  iround = (unsigned int)floor(ip.get_i());
1363  jround = (unsigned int)floor(ip.get_j());
1364 
1365  if (iround >= height || jround >= width) {
1366  vpERROR_TRACE("Pixel outside the image") ;
1368  "Pixel outside the image"));
1369  }
1370 
1371  if (ip.get_i() > height - 1)
1372  ip.set_i((double)(height - 1));
1373 
1374  if (ip.get_j() > width - 1)
1375  ip.set_j((double)(width - 1));
1376 
1377  double rratio = ip.get_i() - (double) iround;
1378  if(rratio < 0)
1379  rratio=-rratio;
1380  double cratio = ip.get_j() - (double) jround;
1381  if(cratio < 0)
1382  cratio=-cratio;
1383 
1384  rfrac = 1.0f - rratio;
1385  cfrac = 1.0f - cratio;
1386 
1387 
1388  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1389  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1390  return value;
1391 }
1392 
1393 template<>
1395 {
1396  unsigned int iround, jround;
1397  double rfrac, cfrac;
1398 
1399  iround = (unsigned int)floor(ip.get_i());
1400  jround = (unsigned int)floor(ip.get_j());
1401 
1402  if (iround >= height || jround >= width) {
1403  vpERROR_TRACE("Pixel outside the image") ;
1405  "Pixel outside the image"));
1406  }
1407 
1408  if (ip.get_i() > height - 1)
1409  ip.set_i((double)(height - 1));
1410 
1411  if (ip.get_j() > width - 1)
1412  ip.set_j((double)(width - 1));
1413 
1414  double rratio = ip.get_i() - (double) iround;
1415  if(rratio < 0)
1416  rratio=-rratio;
1417  double cratio = ip.get_j() - (double) jround;
1418  if(cratio < 0)
1419  cratio=-cratio;
1420 
1421  rfrac = 1.0f - rratio;
1422  cfrac = 1.0f - cratio;
1423 
1424  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1425  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1426  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1427  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1428  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1429  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1430  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1431 }
1432 
1462 template<class Type>
1464 {
1465 
1466  try
1467  {
1468  if ((this->getHeight() != C.getHeight())
1469  || (this->getWidth() != C.getWidth()))
1470  C.resize(this->getHeight(), this->getWidth());
1471  }
1472  catch(vpException &me)
1473  {
1474  vpERROR_TRACE("Error caught") ;
1475  std::cout << me << std::endl ;
1476  throw ;
1477  }
1478 
1479  if ( (this->getWidth() != B.getWidth())||(this->getHeight() != B.getHeight()))
1480  {
1481  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1483  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1484  }
1485 
1486  for (unsigned int i=0;i<this->getWidth()*this->getHeight();i++)
1487  {
1488  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i) ;
1489  }
1490 }
1491 
1503 template<class Type>
1505  vpImage<Type> &C)
1506 {
1507 
1508  try
1509  {
1510  if ((A.getHeight() != C.getHeight())
1511  || (A.getWidth() != C.getWidth()))
1512  C.resize(A.getHeight(), A.getWidth());
1513  }
1514  catch(vpException &me)
1515  {
1516  vpERROR_TRACE("Error caught") ;
1517  std::cout << me << std::endl ;
1518  throw ;
1519  }
1520 
1521  if ( (A.getWidth() != B.getWidth())||(A.getHeight() != B.getHeight()))
1522  {
1523  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1525  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1526  }
1527 
1528  for (unsigned int i=0;i<A.getWidth()*A.getHeight();i++)
1529  {
1530  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i) ;
1531  }
1532 }
1533 
1543 template<class Type>
1544 void vpImage<Type>::performLut(const Type (&)[256])
1545 {
1546 // vpTRACE("Not implemented");
1547  std::cerr << "Not implemented !" << std::endl;
1548 }
1549 
1555 template<>
1556 inline void vpImage<unsigned char>::performLut(const unsigned char (&lut)[256]) {
1557  unsigned int size = getWidth()*getHeight();
1558  unsigned char *ptrStart = (unsigned char*) bitmap;
1559  unsigned char *ptrEnd = ptrStart + size;
1560  unsigned char *ptrCurrent = ptrStart;
1561 
1562  while(ptrCurrent != ptrEnd) {
1563  *ptrCurrent = lut[*ptrCurrent];
1564  ++ptrCurrent;
1565  }
1566 }
1567 
1573 template<>
1574 inline void vpImage<vpRGBa>::performLut(const vpRGBa (&lut)[256]) {
1575  unsigned int size = getWidth()*getHeight();
1576  unsigned char *ptrStart = (unsigned char*) bitmap;
1577  unsigned char *ptrEnd = ptrStart + size*4;
1578  unsigned char *ptrCurrent = ptrStart;
1579 
1580  while(ptrCurrent != ptrEnd) {
1581  *ptrCurrent = lut[*ptrCurrent].R;
1582  ++ptrCurrent;
1583 
1584  *ptrCurrent = lut[*ptrCurrent].G;
1585  ++ptrCurrent;
1586 
1587  *ptrCurrent = lut[*ptrCurrent].B;
1588  ++ptrCurrent;
1589 
1590  *ptrCurrent = lut[*ptrCurrent].A;
1591  ++ptrCurrent;
1592  }
1593 }
1594 
1595 #endif
unsigned int getCols() const
Definition: vpImage.h:180
vpDisplay * display
Definition: vpImage.h:117
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1097
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:170
double get_i() const
Definition: vpImagePoint.h:190
unsigned int getWidth() const
Definition: vpImage.h:161
void init(unsigned int height, unsigned int width)
set the size of the image
Definition: vpImage.h:377
Type operator()(const unsigned int i, const unsigned int j) const
Definition: vpImage.h:237
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:768
void halfSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1018
Type * bitmap
points toward the bitmap
Definition: vpImage.h:116
#define vpERROR_TRACE
Definition: vpDebug.h:391
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:266
error that can be emited by ViSP classes.
Definition: vpException.h:73
Type getValue(double i, double j) const
Definition: vpImage.h:1148
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:752
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:221
virtual ~vpImage()
destructor
Definition: vpImage.h:703
static int round(const double x)
Definition: vpMath.h:248
double get_j() const
Definition: vpImagePoint.h:201
void performLut(const Type(&lut)[256])
Definition: vpImage.h:1544
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:64
void quarterSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1052
unsigned int getRows() const
Definition: vpImage.h:171
void set_i(const double ii)
Definition: vpImagePoint.h:154
vpImage< Type > & operator=(const vpImage< Type > &I)
Copy operator.
Definition: vpImage.h:782
unsigned int getSize() const
Definition: vpImage.h:189
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:877
#define vpTRACE
Definition: vpDebug.h:414
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:282
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:736
const Type * operator[](int i) const
Definition: vpImage.h:226
unsigned int getNumberOfPixel() const
Definition: vpImage.h:214
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
Definition: vpImage.h:616
void destroy()
destructor
Definition: vpImage.h:672
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:225
void set_j(const double jj)
Definition: vpImagePoint.h:165
void insert(const vpImage< Type > &src, const vpImagePoint topLeft)
Definition: vpImage.h:935
Type * operator[](const int i)
Definition: vpImage.h:222
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:918
#define vpDEBUG_TRACE
Definition: vpDebug.h:478
unsigned int getHeight() const
Definition: vpImage.h:152
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void operator()(const unsigned int i, const unsigned int j, const Type &v)
Definition: vpImage.h:250
vpImage()
constructor
Definition: vpImage.h:589
Definition of the vpImage class member functions.
Definition: vpImage.h:111
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:857
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1463