ViSP  2.8.0
vpImage.h
1 /****************************************************************************
2  *
3  * $Id: vpImage.h 4323 2013-07-18 09:24:01Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Image handling.
36  *
37  * Authors:
38  * Eric Marchand
39  *
40  *****************************************************************************/
41 
42 
48 #ifndef vpImage_H
49 #define vpImage_H
50 
51 #include <visp/vpConfig.h>
52 #include <visp/vpDebug.h>
53 #include <visp/vpException.h>
54 #include <visp/vpImageException.h>
55 #include <visp/vpImagePoint.h>
56 #include <visp/vpRGBa.h>
57 
58 #include <fstream>
59 #include <iostream>
60 #include <math.h>
61 #include <string.h>
62 
63 class vpDisplay;
64 
114 template<class Type>
115 class vpImage
116 {
117  friend class vpImageConvert;
118 
119 public:
120  Type *bitmap ;
122 
124  vpImage() ;
126  vpImage(const vpImage<Type>&);
128  vpImage(unsigned int height, unsigned int width) ;
130  vpImage(unsigned int height, unsigned int width, Type value) ;
132  virtual ~vpImage() ;
134  void init(unsigned int height, unsigned int width) ;
136  void init(unsigned int height, unsigned int width, Type value) ;
138  void resize(const unsigned int height, const unsigned int width) ;
140  void destroy() ;
141 
150  inline unsigned int getHeight() const { return height; }
159  inline unsigned int getWidth() const { return width; }
160 
169  inline unsigned int getRows() const { return height ; }
170 
178  inline unsigned int getCols() const { return width ; }
179 
187  inline unsigned int getSize() const { return width*height ; }
188 
189 
190  // Return the maximum value within the bitmap
191  Type getMaxValue() 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 
197  // Gets the value of a pixel at a location with bilinear interpolation.
198  Type getValue(double i, double j) const;
199  // Gets the value of a pixel at a location with bilinear interpolation.
200  Type getValue(vpImagePoint &ip) const;
201 
212  inline unsigned int getNumberOfPixel() const{ return npixels; }
213 
214  //------------------------------------------------------------------
215  // Acces to the image
216 
217 
219  inline Type *operator[]( const unsigned int i) { return row[i];}
220 
222  inline const Type *operator[](unsigned int i) const { return row[i];}
223 
233  inline Type operator()(const unsigned int i, const unsigned int j) const
234  {
235  return bitmap[i*width+j] ;
236  }
246  inline void operator()(const unsigned int i, const unsigned int j,
247  const Type &v)
248  {
249  bitmap[i*width+j] = v ;
250  }
262  inline Type operator()(const vpImagePoint &ip) const
263  {
264  unsigned int i = (unsigned int) ip.get_i();
265  unsigned int j = (unsigned int) ip.get_j();
266 
267  return bitmap[i*width+j] ;
268  }
278  inline void operator()(const vpImagePoint &ip,
279  const Type &v)
280  {
281  unsigned int i = (unsigned int) ip.get_i();
282  unsigned int j = (unsigned int) ip.get_j();
283 
284  bitmap[i*width+j] = v ;
285  }
286 
288 
290  void operator=(const vpImage<Type> &I) ;
291 
292  void operator=(const Type &v);
293  bool operator==(const vpImage<Type> &I);
294  bool operator!=(const vpImage<Type> &I);
295 
296  void insert(const vpImage<Type> &src, const vpImagePoint topLeft);
297 
298 
299  // Returns a new image that's half size of the current image
300  void halfSizeImage(vpImage<Type> &res);
301 
302  // Returns a new image that's a quarter size of the current image
303  void quarterSizeImage(vpImage<Type> &res);
304 
305  // Returns a new image that's double size of the current image
306  void doubleSizeImage(vpImage<Type> &res);
307 
308  void sub(const vpImage<Type> &B, vpImage<Type> &C);
309  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
310 
311 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
312 
315  vp_deprecated void sub(vpImage<Type>* im2, vpImage<Type>* dst);
316  // Returns a new image that's half size of the current image
317  vp_deprecated void halfSizeImage(vpImage<Type>* res);
318  // Returns a new image that's a quarter size of the current image
319  vp_deprecated void quarterSizeImage(vpImage<Type>* res);
320  // Returns a new image that's double size of the current image
321  vp_deprecated void doubleSizeImage(vpImage<Type>* res);
322 #endif
323 private:
324  unsigned int npixels ; //<! number of pixel in the image
325  unsigned int width ; //<! number of columns
326  unsigned int height ; //<! number of rows
327  Type **row ;
328  } ;
329 
330 
342 template<class Type>
343 void
344 vpImage<Type>::init(unsigned int height, unsigned int width, Type value)
345 {
346  try
347  {
348  init(height,width) ;
349  }
350  catch(vpException me)
351  {
352  vpERROR_TRACE(" ") ;
353  throw ;
354  }
355 
356  for (unsigned int i=0 ; i < npixels ; i++)
357  bitmap[i] = value ;
358 }
359 
360 
375 template<class Type>
376 void
377 vpImage<Type>::init(unsigned int height, unsigned int width)
378 {
379 
380  if (height != this->height) {
381  if (row != NULL) {
382  vpDEBUG_TRACE(10,"Destruction row[]");
383  delete [] row;
384  row = NULL;
385  }
386  }
387 
388  if ((height != this->height) || (width != this->width))
389  {
390  if (bitmap != NULL) {
391  vpDEBUG_TRACE(10,"Destruction bitmap[]") ;
392  delete [] bitmap;
393  bitmap = NULL;
394  }
395  }
396 
397 
398 
399  this->width = width ;
400  this->height = height ;
401 
402  npixels=width*height;
403 
404 
405  if (bitmap == NULL) bitmap = new Type[npixels] ;
406 
407  // vpERROR_TRACE("Allocate bitmap %p",bitmap) ;
408  if (bitmap == NULL)
409  {
410  vpERROR_TRACE("cannot allocate bitmap ") ;
412  "cannot allocate bitmap ")) ;
413  }
414 
415  if (row == NULL) row = new Type*[height] ;
416 // vpERROR_TRACE("Allocate row %p",row) ;
417  if (row == NULL)
418  {
419  vpERROR_TRACE("cannot allocate row ") ;
421  "cannot allocate row ")) ;
422  }
423 
424  unsigned int i ;
425  for ( i =0 ; i < height ; i++)
426  row[i] = bitmap + i*width ;
427 }
428 
444 template<class Type>
445 vpImage<Type>::vpImage(unsigned int height, unsigned int width)
446 {
447  bitmap = NULL ;
448  row = NULL ;
449 
450  display = NULL ;
451  this->height = this->width = 0 ;
452  try
453  {
454  init(height,width,0) ;
455  }
456  catch(vpException me)
457  {
458  vpERROR_TRACE(" ") ;
459  throw ;
460  }
461 }
462 
478 template<class Type>
479 vpImage<Type>::vpImage (unsigned int height, unsigned int width, Type value)
480 {
481  bitmap = NULL ;
482  row = NULL ;
483 
484  display = NULL ;
485  this->height = this->width = 0 ;
486  try
487  {
488  init(height,width,value) ;
489  }
490  catch(vpException me)
491  {
492  vpERROR_TRACE(" ") ;
493  throw ;
494  }
495 }
496 
506 template<class Type>
508 {
509  bitmap = NULL ;
510  row = NULL ;
511 
512  display = NULL ;
513 
514  this->height = this->width = 0 ;
515  this->npixels = 0;
516 }
517 
533 template<class Type>
534 void
535 vpImage<Type>::resize(unsigned int height, unsigned int width)
536 {
537  try
538  {
539  init(height, width) ;
540  }
541  catch(vpException me)
542  {
543  vpERROR_TRACE(" ") ;
544  throw ;
545  }
546 }
547 
554 template<class Type>
555 void
557 {
558  // vpERROR_TRACE("Deallocate ") ;
559 
560 
561  if (bitmap!=NULL)
562  {
563  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap) ;
564 // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap) ;
565  delete [] bitmap ;
566  bitmap = NULL;
567  }
568 
569 
570  if (row!=NULL)
571  {
572  // vpERROR_TRACE("Deallocate row memory %p",row) ;
573 // vpDEBUG_TRACE(20,"Deallocate row memory %p",row) ;
574  delete [] row ;
575  row = NULL;
576  }
577 
578 }
579 
586 template<class Type>
588 {
589  destroy() ;
590 }
591 
592 
593 
597 template<class Type>
599 {
600  bitmap = NULL ;
601  row = NULL ;
602  /* 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 */
603  this->width = 0;
604  this->height = 0;
605  this->npixels = 0;
606  try
607  {
608  //if (I.bitmap!=NULL)
609 // if(I.getHeight() != 0 || I.getWidth() != 0)
610  {
611  resize(I.getHeight(),I.getWidth());
612  unsigned int i;
613  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
614  for (i =0 ; i < this->height ; i++) row[i] = bitmap + i*this->width ;
615  }
616  }
617  catch(vpException me)
618  {
619  vpERROR_TRACE(" ") ;
620  throw ;
621  }
622 }
623 
629 template<class Type>
631 {
632  Type m = bitmap[0] ;
633  for (unsigned int i=0 ; i < npixels ; i++)
634  {
635  if (bitmap[i]>m) m = bitmap[i] ;
636  }
637  return m ;
638 }
639 
645 template<class Type>
647 {
648  Type m = bitmap[0];
649  for (unsigned int i=0 ; i < npixels ; i++)
650  if (bitmap[i]<m) m = bitmap[i] ;
651  return m ;
652 }
653 
654 
661 template<class Type>
662 void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
663 {
664  min = max = bitmap[0];
665  for (unsigned int i=0 ; i < npixels ; i++)
666  {
667  if (bitmap[i]<min) min = bitmap[i] ;
668  if (bitmap[i]>max) max = bitmap[i] ;
669  }
670 }
671 
675 template<class Type>
677 {
678  /* 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 */
679  if(bitmap != NULL){
680  delete[] bitmap;
681  bitmap = NULL ;
682  }
683 
684  if(row != NULL){
685  delete[] row;
686  row = NULL ;
687  }
688  this->width = I.width;
689  this->height = I.height;
690  this->npixels = I.npixels;
691  try
692  {
693  if(I.npixels != 0)
694  {
695  if (bitmap == NULL){
696  bitmap = new Type[npixels] ;
697  }
698 
699  if (bitmap == NULL){
700  vpERROR_TRACE("cannot allocate bitmap ") ;
702  "cannot allocate bitmap ")) ;
703  }
704 
705  if (row == NULL){
706  row = new Type*[height] ;
707  }
708  if (row == NULL){
709  vpERROR_TRACE("cannot allocate row ") ;
711  "cannot allocate row ")) ;
712  }
713 
714  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
715 
716  for (unsigned int i=0; i<this->height; i++){
717  row[i] = bitmap + i*this->width;
718  }
719  }
720  }
721  catch(vpException me)
722  {
723  vpERROR_TRACE(" ") ;
724  throw ;
725  }
726 }
727 
728 
735 template<class Type>
736 void vpImage<Type>::operator=(const Type &v)
737 {
738  for (unsigned int i=0 ; i < npixels ; i++)
739  bitmap[i] = v ;
740 }
741 
747 template<class Type>
749 {
750  if (this->width != I.getWidth())
751  return false;
752  if (this->height != I.getHeight())
753  return false;
754 
755  for (unsigned int i=0 ; i < npixels ; i++)
756  {
757  if (bitmap[i] != I.bitmap[i])
758  return false;
759  }
760  return true ;
761 }
767 template<class Type>
769 {
770  if (this->width != I.getWidth())
771  return true;
772  if (this->height != I.getHeight())
773  return true;
774 
775  for (unsigned int i=0 ; i < npixels ; i++)
776  {
777  if (bitmap[i] == I.bitmap[i])
778  return false;
779  }
780  return true ;
781 }
782 
808 template<class Type>
810 {
811  vpImage<Type> C;
812  sub(*this,B,C);
813  return C;
814 }
815 
825 template<class Type>
827  const vpImagePoint topLeft)
828 {
829  Type* srcBitmap;
830  Type* destBitmap;
831 
832  int itl = (int)topLeft.get_i();
833  int jtl = (int)topLeft.get_j();
834 
835  int dest_ibegin = 0;
836  int dest_jbegin = 0;
837  int src_ibegin = 0;
838  int src_jbegin = 0;
839  int dest_w = this->getWidth();
840  int dest_h = this->getHeight();
841  int src_w = src.getWidth();
842  int src_h = src.getHeight();
843  int wsize = src.getWidth();
844  int hsize = src.getHeight();
845 
846  if (itl >= dest_h || jtl >= dest_w)
847  return;
848 
849  if (itl < 0)
850  src_ibegin = -itl;
851  else
852  dest_ibegin = itl;
853 
854  if (jtl < 0)
855  src_jbegin = -jtl;
856  else
857  dest_jbegin = jtl;
858 
859  if (src_w - src_jbegin > dest_w - dest_jbegin)
860  wsize = dest_w - dest_jbegin;
861  else
862  wsize = src_w - src_jbegin;
863 
864  if (src_h - src_ibegin > dest_h - dest_ibegin)
865  hsize = dest_h - dest_ibegin;
866  else
867  hsize = src_h - src_ibegin;
868 
869  for (int i = 0; i < hsize; i++)
870  {
871  srcBitmap = src.bitmap + ((src_ibegin+i)*src_w+src_jbegin);
872  destBitmap = this->bitmap + ((dest_ibegin+i)*dest_w+dest_jbegin);
873 
874  memcpy(destBitmap,srcBitmap,wsize*sizeof(Type));
875  }
876 }
877 
907 template<class Type>
908 void
910 {
911  unsigned int h = height/2;
912  unsigned int w = width/2;
913  res.resize(h, w);
914  for(unsigned int i = 0; i < h; i++)
915  for(unsigned int j = 0; j < w; j++)
916  res[i][j] = (*this)[i<<1][j<<1];
917 }
918 
941 template<class Type>
942 void
944 {
945  unsigned int h = height/4;
946  unsigned int w = width/4;
947  res.resize(h, w);
948  for(unsigned int i = 0; i < h; i++)
949  for(unsigned int j = 0; j < w; j++)
950  res[i][j] = (*this)[i<<2][j<<2];
951 }
952 
986 template<class Type>
987 void
989 {
990  int h = height*2;
991  int w = width*2;
992 
993  res.resize(h, w);
994 
995  for(int i = 0; i < h; i++)
996  for(int j = 0; j < w; j++)
997  res[i][j] = (*this)[i>>1][j>>1];
998 
999  /*
1000  A B C
1001  E F G
1002  H I J
1003  A C H J are pixels from original image
1004  B E G I are interpolated pixels
1005  */
1006 
1007  //interpolate pixels B and I
1008  for(int i = 0; i < h; i += 2)
1009  for(int j = 1; j < w - 1; j += 2)
1010  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1011  + (*this)[i>>1][(j>>1) + 1]));
1012 
1013  //interpolate pixels E and G
1014  for(int i = 1; i < h - 1; i += 2)
1015  for(int j = 0; j < w; j += 2)
1016  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1017  + (*this)[(i>>1)+1][j>>1]));
1018 
1019  //interpolate pixel F
1020  for(int i = 1; i < h - 1; i += 2)
1021  for(int j = 1; j < w - 1; j += 2)
1022  res[i][j] = (Type)(0.25 * ((*this)[i>>1][j>>1]
1023  + (*this)[i>>1][(j>>1)+1]
1024  + (*this)[(i>>1)+1][j>>1]
1025  + (*this)[(i>>1)+1][(j>>1)+1]));
1026 }
1027 
1038 template<class Type>
1039 Type vpImage<Type>::getValue(double /* i */, double /* j */) const
1040 {
1041  vpTRACE("Not implemented");
1042 }
1043 
1061 template<>
1062 inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const
1063 {
1064  unsigned int iround, jround;
1065  double rfrac, cfrac;
1066 
1067  iround = (unsigned int)floor(i);
1068  jround = (unsigned int)floor(j);
1069 
1070  if (iround >= height || jround >= width) {
1071  vpERROR_TRACE("Pixel outside the image") ;
1073  "Pixel outside the image"));
1074  }
1075 
1076  if (i > height - 1)
1077  i = (double)(height - 1);
1078 
1079  if (j > width - 1)
1080  j = (double)(width - 1);
1081 
1082  double rratio = i - (double) iround;
1083  if(rratio < 0)
1084  rratio=-rratio;
1085  double cratio = j - (double) jround;
1086  if(cratio < 0)
1087  cratio=-cratio;
1088 
1089  rfrac = 1.0f - rratio;
1090  cfrac = 1.0f - cratio;
1091 
1092 
1093  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1094  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1095  return (unsigned char)vpMath::round(value);
1096 }
1097 
1098 
1116 template<>
1117 inline double vpImage<double>::getValue(double i, double j) const
1118 {
1119  unsigned int iround, jround;
1120  double rfrac, cfrac;
1121 
1122  iround = (unsigned int)floor(i);
1123  jround = (unsigned int)floor(j);
1124 
1125  if (iround >= height || jround >= width) {
1126  vpERROR_TRACE("Pixel outside the image") ;
1128  "Pixel outside the image"));
1129  }
1130 
1131  if (i > height - 1)
1132  i = (double)(height - 1);
1133 
1134  if (j > width - 1)
1135  j = (double)(width - 1);
1136 
1137  double rratio = i - (double) iround;
1138  if(rratio < 0)
1139  rratio=-rratio;
1140  double cratio = j - (double) jround;
1141  if(cratio < 0)
1142  cratio=-cratio;
1143 
1144  rfrac = 1.0f - rratio;
1145  cfrac = 1.0f - cratio;
1146 
1147 
1148  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1149  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1150  return value;
1151 }
1152 
1153 template<>
1154 inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1155 {
1156  unsigned int iround, jround;
1157  double rfrac, cfrac;
1158 
1159  iround = (unsigned int)floor(i);
1160  jround = (unsigned int)floor(j);
1161 
1162  if (iround >= height || jround >= width) {
1163  vpERROR_TRACE("Pixel outside the image") ;
1165  "Pixel outside the image"));
1166  }
1167 
1168  if (i > height - 1)
1169  i = (double)(height - 1);
1170 
1171  if (j > width - 1)
1172  j = (double)(width - 1);
1173 
1174  double rratio = i - (double) iround;
1175  if(rratio < 0)
1176  rratio=-rratio;
1177  double cratio = j - (double) jround;
1178  if(cratio < 0)
1179  cratio=-cratio;
1180 
1181  rfrac = 1.0f - rratio;
1182  cfrac = 1.0f - cratio;
1183 
1184  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1185  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1186  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1187  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1188  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1189  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1190  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1191 }
1192 
1203 template<class Type>
1205 {
1206  vpTRACE("Not implemented");
1207 }
1208 
1209 template<>
1210 inline unsigned char vpImage<unsigned char>::getValue(vpImagePoint &ip) const
1211 {
1212  unsigned int iround, jround;
1213  double rfrac, cfrac;
1214 
1215  iround = (unsigned int)floor(ip.get_i());
1216  jround = (unsigned int)floor(ip.get_j());
1217 
1218  if (iround >= height || jround >= width) {
1219  vpERROR_TRACE("Pixel outside the image") ;
1221  "Pixel outside the image"));
1222  }
1223 
1224  if (ip.get_i() > height - 1)
1225  ip.set_i((double)(height - 1));
1226 
1227  if (ip.get_j() > width - 1)
1228  ip.set_j((double)(width - 1));
1229 
1230  double rratio = ip.get_i() - (double) iround;
1231  if(rratio < 0)
1232  rratio=-rratio;
1233  double cratio = ip.get_j() - (double) jround;
1234  if(cratio < 0)
1235  cratio=-cratio;
1236 
1237  rfrac = 1.0f - rratio;
1238  cfrac = 1.0f - cratio;
1239 
1240 
1241  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1242  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1243  return (unsigned char)vpMath::round(value);
1244 }
1245 
1246 
1247 template<>
1248 inline double vpImage<double>::getValue(vpImagePoint &ip) const
1249 {
1250  unsigned int iround, jround;
1251  double rfrac, cfrac;
1252 
1253  iround = (unsigned int)floor(ip.get_i());
1254  jround = (unsigned int)floor(ip.get_j());
1255 
1256  if (iround >= height || jround >= width) {
1257  vpERROR_TRACE("Pixel outside the image") ;
1259  "Pixel outside the image"));
1260  }
1261 
1262  if (ip.get_i() > height - 1)
1263  ip.set_i((double)(height - 1));
1264 
1265  if (ip.get_j() > width - 1)
1266  ip.set_j((double)(width - 1));
1267 
1268  double rratio = ip.get_i() - (double) iround;
1269  if(rratio < 0)
1270  rratio=-rratio;
1271  double cratio = ip.get_j() - (double) jround;
1272  if(cratio < 0)
1273  cratio=-cratio;
1274 
1275  rfrac = 1.0f - rratio;
1276  cfrac = 1.0f - cratio;
1277 
1278 
1279  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1280  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1281  return value;
1282 }
1283 
1284 template<>
1286 {
1287  unsigned int iround, jround;
1288  double rfrac, cfrac;
1289 
1290  iround = (unsigned int)floor(ip.get_i());
1291  jround = (unsigned int)floor(ip.get_j());
1292 
1293  if (iround >= height || jround >= width) {
1294  vpERROR_TRACE("Pixel outside the image") ;
1296  "Pixel outside the image"));
1297  }
1298 
1299  if (ip.get_i() > height - 1)
1300  ip.set_i((double)(height - 1));
1301 
1302  if (ip.get_j() > width - 1)
1303  ip.set_j((double)(width - 1));
1304 
1305  double rratio = ip.get_i() - (double) iround;
1306  if(rratio < 0)
1307  rratio=-rratio;
1308  double cratio = ip.get_j() - (double) jround;
1309  if(cratio < 0)
1310  cratio=-cratio;
1311 
1312  rfrac = 1.0f - rratio;
1313  cfrac = 1.0f - cratio;
1314 
1315  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1316  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1317  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1318  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1319  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1320  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1321  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1322 }
1323 
1353 template<class Type>
1355 {
1356 
1357  try
1358  {
1359  if ((this->getHeight() != C.getHeight())
1360  || (this->getWidth() != C.getWidth()))
1361  C.resize(this->getHeight(), this->getWidth());
1362  }
1363  catch(vpException me)
1364  {
1365  vpERROR_TRACE("Error caught") ;
1366  std::cout << me << std::endl ;
1367  throw ;
1368  }
1369 
1370  if ( (this->getWidth() != B.getWidth())||(this->getHeight() != B.getHeight()))
1371  {
1372  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1374  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1375  }
1376 
1377  for (unsigned int i=0;i<this->getWidth()*this->getHeight();i++)
1378  {
1379  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i) ;
1380  }
1381 }
1382 
1394 template<class Type>
1396  vpImage<Type> &C)
1397 {
1398 
1399  try
1400  {
1401  if ((A.getHeight() != C.getHeight())
1402  || (A.getWidth() != C.getWidth()))
1403  C.resize(A.getHeight(), A.getWidth());
1404  }
1405  catch(vpException me)
1406  {
1407  vpERROR_TRACE("Error caught") ;
1408  std::cout << me << std::endl ;
1409  throw ;
1410  }
1411 
1412  if ( (A.getWidth() != B.getWidth())||(A.getHeight() != B.getHeight()))
1413  {
1414  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1416  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1417  }
1418 
1419  for (unsigned int i=0;i<A.getWidth()*A.getHeight();i++)
1420  {
1421  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i) ;
1422  }
1423 }
1424 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1425 
1436 template<class Type>
1437 void
1439 {
1440  if (B == NULL || C == NULL) {
1442  "Images are not allocated in vpImage<>::sub()")) ;
1443  }
1444  if ( (this->getWidth() != B->getWidth())
1445  || (this->getHeight() != B->getHeight())
1446  || (this->getWidth() != C->getWidth())
1447  || (this->getHeight() != C->getHeight()))
1448  {
1449  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1451  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1452  }
1453 
1454  for(unsigned int i = 0; i < height * width; i++)
1455  C->bitmap[i] = this->bitmap[i] - B->bitmap[i];
1456 }
1457 
1471 template<class Type>
1472 void
1474 {
1475  unsigned int r = height/2;
1476  unsigned int c = width/2;
1477  if(res == NULL) {
1479  "Images are not allocated in vpImage<>::sub()")) ;
1480  }
1481  if((res->getWidth() != c) || (res->getHeight()!= r))
1482  res->resize(r,c);
1483  for(unsigned int y = 0; y < r; y++)
1484  for(unsigned int x = 0; x < c; x++)
1485  (*res)[y][x] = (*this)[y*2][x*2];
1486 }
1487 
1499 template<class Type>
1500 void
1502 {
1503  unsigned int r = height/4;
1504  unsigned int c = width/4;
1505  if(res == NULL) {
1507  "Images are not allocated in vpImage<>::sub()")) ;
1508  }
1509  if((res->getWidth() != c) || (res->getHeight()!= r))
1510  res->resize(r,c);
1511  for(unsigned int y = 0; y < r; y++)
1512  for(unsigned int x = 0; x < c; x++)
1513  (*res)[y][x] = (*this)[y*4][x*4];
1514 }
1515 
1527 template<class Type>
1528 void
1530 {
1531  int h = height*2;
1532  int w = width*2;
1533 
1534  if(res == NULL) {
1536  "Images are not allocated in vpImage<>::sub()")) ;
1537  }
1538  if((res->getWidth() != w) || (res->getHeight()!= h))
1539  res->resize(h, w);
1540 
1541  for(int j = 0; j < h; j++)
1542  for(int i = 0; i < w; i++)
1543  (*res)[j][i] = (*this)[j/2][i/2];
1544 
1545  /*
1546  A B C
1547  E F G
1548  H I J
1549  A C H J are pixels from original image
1550  B E G I are interpolated pixels
1551  */
1552 
1553  //interpolate pixels B and I
1554  for(int j = 0; j < h; j += 2)
1555  for(int i = 1; i < w - 1; i += 2)
1556  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2][i/2 + 1]));
1557 
1558  //interpolate pixels E and G
1559  for(int j = 1; j < h - 1; j += 2)
1560  for(int i = 0; i < w; i += 2)
1561  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2+1][i/2]));
1562 
1563  //interpolate pixel F
1564  for(int j = 1; j < h - 1; j += 2)
1565  for(int i = 1; i < w - 1; i += 2)
1566  (*res)[j][i] = (Type)(0.25 * ((*this)[j/2][i/2] + (*this)[j/2][i/2+1] +
1567  (*this)[j/2+1][i/2] + (*this)[j/2+1][i/2+1]));
1568 }
1569 
1570 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1571 
1572 #endif
1573 
1574 
1575 /*
1576  * Local variables:
1577  * c-basic-offset: 2
1578  * End:
1579  */
unsigned int getCols() const
Definition: vpImage.h:178
void set_j(const double j)
Definition: vpImagePoint.h:156
vpDisplay * display
Definition: vpImage.h:121
#define vpDEBUG_TRACE
Definition: vpDebug.h:454
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:988
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:175
double get_i() const
Definition: vpImagePoint.h:181
unsigned int getWidth() const
Definition: vpImage.h:159
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:233
#define vpERROR_TRACE
Definition: vpDebug.h:379
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:662
#define vpTRACE
Definition: vpDebug.h:401
void halfSizeImage(vpImage< Type > &res)
Definition: vpImage.h:909
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:262
void resize(const unsigned int height, const unsigned int width)
set the size of the image
Definition: vpImage.h:535
void set_i(const double i)
Definition: vpImagePoint.h:145
error that can be emited by ViSP classes.
Definition: vpException.h:75
Type getValue(double i, double j) const
Definition: vpImage.h:1039
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:646
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:219
virtual ~vpImage()
destructor
Definition: vpImage.h:587
static int round(const double x)
Definition: vpMath.h:228
double get_j() const
Definition: vpImagePoint.h:192
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:68
void quarterSizeImage(vpImage< Type > &res)
Definition: vpImage.h:943
unsigned int getRows() const
Definition: vpImage.h:169
unsigned int getSize() const
Definition: vpImage.h:187
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:768
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:278
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:630
unsigned int getNumberOfPixel() const
Definition: vpImage.h:212
void operator=(const vpImage< Type > &I)
Copy operator.
Definition: vpImage.h:676
void destroy()
destructor
Definition: vpImage.h:556
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:222
void insert(const vpImage< Type > &src, const vpImagePoint topLeft)
Definition: vpImage.h:826
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:809
unsigned int getHeight() const
Definition: vpImage.h:150
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
void operator()(const unsigned int i, const unsigned int j, const Type &v)
Definition: vpImage.h:246
vpImage()
constructor
Definition: vpImage.h:507
Definition of the vpImage class member functions.
Definition: vpImage.h:115
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:748
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1354