ViSP  2.9.0
vpImage.h
1 /****************************************************************************
2  *
3  * $Id: vpImage.h 4649 2014-02-07 14:57:11Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 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 h, const unsigned int w) ;
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  inline Type *operator[]( const int i) { return row[i];}
221 
223  inline const Type *operator[](unsigned int i) const { return row[i];}
224  inline const Type *operator[](int i) const { return row[i];}
225 
235  inline Type operator()(const unsigned int i, const unsigned int j) const
236  {
237  return bitmap[i*width+j] ;
238  }
248  inline void operator()(const unsigned int i, const unsigned int j,
249  const Type &v)
250  {
251  bitmap[i*width+j] = v ;
252  }
264  inline Type operator()(const vpImagePoint &ip) const
265  {
266  unsigned int i = (unsigned int) ip.get_i();
267  unsigned int j = (unsigned int) ip.get_j();
268 
269  return bitmap[i*width+j] ;
270  }
280  inline void operator()(const vpImagePoint &ip,
281  const Type &v)
282  {
283  unsigned int i = (unsigned int) ip.get_i();
284  unsigned int j = (unsigned int) ip.get_j();
285 
286  bitmap[i*width+j] = v ;
287  }
288 
290 
293 
294  vpImage<Type>& operator=(const Type &v);
295  bool operator==(const vpImage<Type> &I);
296  bool operator!=(const vpImage<Type> &I);
297 
298  void insert(const vpImage<Type> &src, const vpImagePoint topLeft);
299 
300 
301  // Returns a new image that's half size of the current image
302  void halfSizeImage(vpImage<Type> &res);
303 
304  // Returns a new image that's a quarter size of the current image
305  void quarterSizeImage(vpImage<Type> &res);
306 
307  // Returns a new image that's double size of the current image
308  void doubleSizeImage(vpImage<Type> &res);
309 
310  void sub(const vpImage<Type> &B, vpImage<Type> &C);
311  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
312 
313 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
314 
317  vp_deprecated void sub(vpImage<Type>* im2, vpImage<Type>* dst);
318  // Returns a new image that's half size of the current image
319  vp_deprecated void halfSizeImage(vpImage<Type>* res);
320  // Returns a new image that's a quarter size of the current image
321  vp_deprecated void quarterSizeImage(vpImage<Type>* res);
322  // Returns a new image that's double size of the current image
323  vp_deprecated void doubleSizeImage(vpImage<Type>* res);
324 #endif
325 private:
326  unsigned int npixels ; //<! number of pixel in the image
327  unsigned int width ; //<! number of columns
328  unsigned int height ; //<! number of rows
329  Type **row ;
330  } ;
331 
332 
346 template<class Type>
347 void
348 vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
349 {
350  try
351  {
352  init(h,w) ;
353  }
354  catch(vpException me)
355  {
356  vpERROR_TRACE(" ") ;
357  throw ;
358  }
359 
360  for (unsigned int i=0 ; i < npixels ; i++)
361  bitmap[i] = value ;
362 }
363 
364 
382 template<class Type>
383 void
384 vpImage<Type>::init(unsigned int h, unsigned int w)
385 {
386 
387  if (h != this->height) {
388  if (row != NULL) {
389  vpDEBUG_TRACE(10,"Destruction row[]");
390  delete [] row;
391  row = NULL;
392  }
393  }
394 
395  if ((h != this->height) || (w != this->width))
396  {
397  if (bitmap != NULL) {
398  vpDEBUG_TRACE(10,"Destruction bitmap[]") ;
399  delete [] bitmap;
400  bitmap = NULL;
401  }
402  }
403 
404  this->width = w ;
405  this->height = h;
406 
407  npixels=width*height;
408 
409  if (bitmap == NULL) bitmap = new Type[npixels] ;
410 
411  // vpERROR_TRACE("Allocate bitmap %p",bitmap) ;
412  if (bitmap == NULL)
413  {
414  vpERROR_TRACE("cannot allocate bitmap ") ;
416  "cannot allocate bitmap ")) ;
417  }
418 
419  if (row == NULL) row = new Type*[height] ;
420 // vpERROR_TRACE("Allocate row %p",row) ;
421  if (row == NULL)
422  {
423  vpERROR_TRACE("cannot allocate row ") ;
425  "cannot allocate row ")) ;
426  }
427 
428  unsigned int i ;
429  for ( i =0 ; i < height ; i++)
430  row[i] = bitmap + i*width ;
431 }
432 
451 template<class Type>
452 vpImage<Type>::vpImage(unsigned int h, unsigned int w)
453  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
454 {
455  try
456  {
457  init(h,w,0) ;
458  }
459  catch(...)
460  {
461  throw ;
462  }
463 }
464 
482 template<class Type>
483 vpImage<Type>::vpImage (unsigned int h, unsigned int w, Type value)
484  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
485 {
486  try
487  {
488  init(h,w,value) ;
489  }
490  catch(vpException me)
491  {
492  vpERROR_TRACE(" ") ;
493  throw ;
494  }
495 }
496 
506 template<class Type>
508  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
509 {
510 }
511 
530 template<class Type>
531 void
532 vpImage<Type>::resize(unsigned int h, unsigned int w)
533 {
534  try
535  {
536  init(h, w) ;
537  }
538  catch(vpException me)
539  {
540  vpERROR_TRACE(" ") ;
541  throw ;
542  }
543 }
544 
551 template<class Type>
552 void
554 {
555  // vpERROR_TRACE("Deallocate ") ;
556 
557 
558  if (bitmap!=NULL)
559  {
560  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap) ;
561 // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap) ;
562  delete [] bitmap ;
563  bitmap = NULL;
564  }
565 
566 
567  if (row!=NULL)
568  {
569  // vpERROR_TRACE("Deallocate row memory %p",row) ;
570 // vpDEBUG_TRACE(20,"Deallocate row memory %p",row) ;
571  delete [] row ;
572  row = NULL;
573  }
574 
575 }
576 
583 template<class Type>
585 {
586  destroy() ;
587 }
588 
589 
590 
594 template<class Type>
596  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
597 {
598  try
599  {
600  resize(I.getHeight(),I.getWidth());
601  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
602  for (unsigned int i =0 ; i < this->height ; i++) row[i] = bitmap + i*this->width ;
603  }
604  catch(vpException me)
605  {
606  vpERROR_TRACE(" ") ;
607  throw ;
608  }
609 }
610 
616 template<class Type>
618 {
619  Type m = bitmap[0] ;
620  for (unsigned int i=0 ; i < npixels ; i++)
621  {
622  if (bitmap[i]>m) m = bitmap[i] ;
623  }
624  return m ;
625 }
626 
632 template<class Type>
634 {
635  Type m = bitmap[0];
636  for (unsigned int i=0 ; i < npixels ; i++)
637  if (bitmap[i]<m) m = bitmap[i] ;
638  return m ;
639 }
640 
641 
648 template<class Type>
649 void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
650 {
651  min = max = bitmap[0];
652  for (unsigned int i=0 ; i < npixels ; i++)
653  {
654  if (bitmap[i]<min) min = bitmap[i] ;
655  if (bitmap[i]>max) max = bitmap[i] ;
656  }
657 }
658 
662 template<class Type>
664 {
665  /* 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 */
666  if(bitmap != NULL){
667  delete[] bitmap;
668  bitmap = NULL ;
669  }
670 
671  if(row != NULL){
672  delete[] row;
673  row = NULL ;
674  }
675  this->width = I.width;
676  this->height = I.height;
677  this->npixels = I.npixels;
678  try
679  {
680  if(I.npixels != 0)
681  {
682  if (bitmap == NULL){
683  bitmap = new Type[npixels] ;
684  }
685 
686  if (bitmap == NULL){
687  vpERROR_TRACE("cannot allocate bitmap ") ;
689  "cannot allocate bitmap ")) ;
690  }
691 
692  if (row == NULL){
693  row = new Type*[height] ;
694  }
695  if (row == NULL){
696  vpERROR_TRACE("cannot allocate row ") ;
698  "cannot allocate row ")) ;
699  }
700 
701  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
702 
703  for (unsigned int i=0; i<this->height; i++){
704  row[i] = bitmap + i*this->width;
705  }
706  }
707  }
708  catch(vpException me)
709  {
710  vpERROR_TRACE(" ") ;
711  throw ;
712  }
713  return (* this);
714 }
715 
716 
723 template<class Type>
725 {
726  for (unsigned int i=0 ; i < npixels ; i++)
727  bitmap[i] = v ;
728 
729  return *this;
730 }
731 
737 template<class Type>
739 {
740  if (this->width != I.getWidth())
741  return false;
742  if (this->height != I.getHeight())
743  return false;
744 
745  for (unsigned int i=0 ; i < npixels ; i++)
746  {
747  if (bitmap[i] != I.bitmap[i])
748  return false;
749  }
750  return true ;
751 }
757 template<class Type>
759 {
760  if (this->width != I.getWidth())
761  return true;
762  if (this->height != I.getHeight())
763  return true;
764 
765  for (unsigned int i=0 ; i < npixels ; i++)
766  {
767  if (bitmap[i] == I.bitmap[i])
768  return false;
769  }
770  return true ;
771 }
772 
798 template<class Type>
800 {
801  vpImage<Type> C;
802  sub(*this,B,C);
803  return C;
804 }
805 
815 template<class Type>
817  const vpImagePoint topLeft)
818 {
819  Type* srcBitmap;
820  Type* destBitmap;
821 
822  int itl = (int)topLeft.get_i();
823  int jtl = (int)topLeft.get_j();
824 
825  int dest_ibegin = 0;
826  int dest_jbegin = 0;
827  int src_ibegin = 0;
828  int src_jbegin = 0;
829  int dest_w = this->getWidth();
830  int dest_h = this->getHeight();
831  int src_w = src.getWidth();
832  int src_h = src.getHeight();
833  int wsize = src.getWidth();
834  int hsize = src.getHeight();
835 
836  if (itl >= dest_h || jtl >= dest_w)
837  return;
838 
839  if (itl < 0)
840  src_ibegin = -itl;
841  else
842  dest_ibegin = itl;
843 
844  if (jtl < 0)
845  src_jbegin = -jtl;
846  else
847  dest_jbegin = jtl;
848 
849  if (src_w - src_jbegin > dest_w - dest_jbegin)
850  wsize = dest_w - dest_jbegin;
851  else
852  wsize = src_w - src_jbegin;
853 
854  if (src_h - src_ibegin > dest_h - dest_ibegin)
855  hsize = dest_h - dest_ibegin;
856  else
857  hsize = src_h - src_ibegin;
858 
859  for (int i = 0; i < hsize; i++)
860  {
861  srcBitmap = src.bitmap + ((src_ibegin+i)*src_w+src_jbegin);
862  destBitmap = this->bitmap + ((dest_ibegin+i)*dest_w+dest_jbegin);
863 
864  memcpy(destBitmap,srcBitmap,wsize*sizeof(Type));
865  }
866 }
867 
897 template<class Type>
898 void
900 {
901  unsigned int h = height/2;
902  unsigned int w = width/2;
903  res.resize(h, w);
904  for(unsigned int i = 0; i < h; i++)
905  for(unsigned int j = 0; j < w; j++)
906  res[i][j] = (*this)[i<<1][j<<1];
907 }
908 
931 template<class Type>
932 void
934 {
935  unsigned int h = height/4;
936  unsigned int w = width/4;
937  res.resize(h, w);
938  for(unsigned int i = 0; i < h; i++)
939  for(unsigned int j = 0; j < w; j++)
940  res[i][j] = (*this)[i<<2][j<<2];
941 }
942 
976 template<class Type>
977 void
979 {
980  int h = height*2;
981  int w = width*2;
982 
983  res.resize(h, w);
984 
985  for(int i = 0; i < h; i++)
986  for(int j = 0; j < w; j++)
987  res[i][j] = (*this)[i>>1][j>>1];
988 
989  /*
990  A B C
991  E F G
992  H I J
993  A C H J are pixels from original image
994  B E G I are interpolated pixels
995  */
996 
997  //interpolate pixels B and I
998  for(int i = 0; i < h; i += 2)
999  for(int j = 1; j < w - 1; j += 2)
1000  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1001  + (*this)[i>>1][(j>>1) + 1]));
1002 
1003  //interpolate pixels E and G
1004  for(int i = 1; i < h - 1; i += 2)
1005  for(int j = 0; j < w; j += 2)
1006  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1007  + (*this)[(i>>1)+1][j>>1]));
1008 
1009  //interpolate pixel F
1010  for(int i = 1; i < h - 1; i += 2)
1011  for(int j = 1; j < w - 1; j += 2)
1012  res[i][j] = (Type)(0.25 * ((*this)[i>>1][j>>1]
1013  + (*this)[i>>1][(j>>1)+1]
1014  + (*this)[(i>>1)+1][j>>1]
1015  + (*this)[(i>>1)+1][(j>>1)+1]));
1016 }
1017 
1028 template<class Type>
1029 Type vpImage<Type>::getValue(double /* i */, double /* j */) const
1030 {
1031  vpTRACE("Not implemented");
1032 }
1033 
1051 template<>
1052 inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const
1053 {
1054  unsigned int iround, jround;
1055  double rfrac, cfrac;
1056 
1057  iround = (unsigned int)floor(i);
1058  jround = (unsigned int)floor(j);
1059 
1060  if (iround >= height || jround >= width) {
1061  vpERROR_TRACE("Pixel outside the image") ;
1063  "Pixel outside the image"));
1064  }
1065 
1066  if (i > height - 1)
1067  i = (double)(height - 1);
1068 
1069  if (j > width - 1)
1070  j = (double)(width - 1);
1071 
1072  double rratio = i - (double) iround;
1073  if(rratio < 0)
1074  rratio=-rratio;
1075  double cratio = j - (double) jround;
1076  if(cratio < 0)
1077  cratio=-cratio;
1078 
1079  rfrac = 1.0f - rratio;
1080  cfrac = 1.0f - cratio;
1081 
1082 
1083  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1084  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1085  return (unsigned char)vpMath::round(value);
1086 }
1087 
1088 
1106 template<>
1107 inline double vpImage<double>::getValue(double i, double j) const
1108 {
1109  unsigned int iround, jround;
1110  double rfrac, cfrac;
1111 
1112  iround = (unsigned int)floor(i);
1113  jround = (unsigned int)floor(j);
1114 
1115  if (iround >= height || jround >= width) {
1116  vpERROR_TRACE("Pixel outside the image") ;
1118  "Pixel outside the image"));
1119  }
1120 
1121  if (i > height - 1)
1122  i = (double)(height - 1);
1123 
1124  if (j > width - 1)
1125  j = (double)(width - 1);
1126 
1127  double rratio = i - (double) iround;
1128  if(rratio < 0)
1129  rratio=-rratio;
1130  double cratio = j - (double) jround;
1131  if(cratio < 0)
1132  cratio=-cratio;
1133 
1134  rfrac = 1.0f - rratio;
1135  cfrac = 1.0f - cratio;
1136 
1137 
1138  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1139  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1140  return value;
1141 }
1142 
1143 template<>
1144 inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1145 {
1146  unsigned int iround, jround;
1147  double rfrac, cfrac;
1148 
1149  iround = (unsigned int)floor(i);
1150  jround = (unsigned int)floor(j);
1151 
1152  if (iround >= height || jround >= width) {
1153  vpERROR_TRACE("Pixel outside the image") ;
1155  "Pixel outside the image"));
1156  }
1157 
1158  if (i > height - 1)
1159  i = (double)(height - 1);
1160 
1161  if (j > width - 1)
1162  j = (double)(width - 1);
1163 
1164  double rratio = i - (double) iround;
1165  if(rratio < 0)
1166  rratio=-rratio;
1167  double cratio = j - (double) jround;
1168  if(cratio < 0)
1169  cratio=-cratio;
1170 
1171  rfrac = 1.0f - rratio;
1172  cfrac = 1.0f - cratio;
1173 
1174  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1175  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1176  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1177  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1178  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1179  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1180  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1181 }
1182 
1193 template<class Type>
1195 {
1196  vpTRACE("Not implemented");
1197 }
1198 
1199 template<>
1200 inline unsigned char vpImage<unsigned char>::getValue(vpImagePoint &ip) const
1201 {
1202  unsigned int iround, jround;
1203  double rfrac, cfrac;
1204 
1205  iround = (unsigned int)floor(ip.get_i());
1206  jround = (unsigned int)floor(ip.get_j());
1207 
1208  if (iround >= height || jround >= width) {
1209  vpERROR_TRACE("Pixel outside the image") ;
1211  "Pixel outside the image"));
1212  }
1213 
1214  if (ip.get_i() > height - 1)
1215  ip.set_i((double)(height - 1));
1216 
1217  if (ip.get_j() > width - 1)
1218  ip.set_j((double)(width - 1));
1219 
1220  double rratio = ip.get_i() - (double) iround;
1221  if(rratio < 0)
1222  rratio=-rratio;
1223  double cratio = ip.get_j() - (double) jround;
1224  if(cratio < 0)
1225  cratio=-cratio;
1226 
1227  rfrac = 1.0f - rratio;
1228  cfrac = 1.0f - cratio;
1229 
1230 
1231  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1232  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1233  return (unsigned char)vpMath::round(value);
1234 }
1235 
1236 
1237 template<>
1238 inline double vpImage<double>::getValue(vpImagePoint &ip) const
1239 {
1240  unsigned int iround, jround;
1241  double rfrac, cfrac;
1242 
1243  iround = (unsigned int)floor(ip.get_i());
1244  jround = (unsigned int)floor(ip.get_j());
1245 
1246  if (iround >= height || jround >= width) {
1247  vpERROR_TRACE("Pixel outside the image") ;
1249  "Pixel outside the image"));
1250  }
1251 
1252  if (ip.get_i() > height - 1)
1253  ip.set_i((double)(height - 1));
1254 
1255  if (ip.get_j() > width - 1)
1256  ip.set_j((double)(width - 1));
1257 
1258  double rratio = ip.get_i() - (double) iround;
1259  if(rratio < 0)
1260  rratio=-rratio;
1261  double cratio = ip.get_j() - (double) jround;
1262  if(cratio < 0)
1263  cratio=-cratio;
1264 
1265  rfrac = 1.0f - rratio;
1266  cfrac = 1.0f - cratio;
1267 
1268 
1269  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1270  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1271  return value;
1272 }
1273 
1274 template<>
1276 {
1277  unsigned int iround, jround;
1278  double rfrac, cfrac;
1279 
1280  iround = (unsigned int)floor(ip.get_i());
1281  jround = (unsigned int)floor(ip.get_j());
1282 
1283  if (iround >= height || jround >= width) {
1284  vpERROR_TRACE("Pixel outside the image") ;
1286  "Pixel outside the image"));
1287  }
1288 
1289  if (ip.get_i() > height - 1)
1290  ip.set_i((double)(height - 1));
1291 
1292  if (ip.get_j() > width - 1)
1293  ip.set_j((double)(width - 1));
1294 
1295  double rratio = ip.get_i() - (double) iround;
1296  if(rratio < 0)
1297  rratio=-rratio;
1298  double cratio = ip.get_j() - (double) jround;
1299  if(cratio < 0)
1300  cratio=-cratio;
1301 
1302  rfrac = 1.0f - rratio;
1303  cfrac = 1.0f - cratio;
1304 
1305  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1306  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1307  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1308  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1309  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1310  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1311  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1312 }
1313 
1343 template<class Type>
1345 {
1346 
1347  try
1348  {
1349  if ((this->getHeight() != C.getHeight())
1350  || (this->getWidth() != C.getWidth()))
1351  C.resize(this->getHeight(), this->getWidth());
1352  }
1353  catch(vpException me)
1354  {
1355  vpERROR_TRACE("Error caught") ;
1356  std::cout << me << std::endl ;
1357  throw ;
1358  }
1359 
1360  if ( (this->getWidth() != B.getWidth())||(this->getHeight() != B.getHeight()))
1361  {
1362  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1364  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1365  }
1366 
1367  for (unsigned int i=0;i<this->getWidth()*this->getHeight();i++)
1368  {
1369  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i) ;
1370  }
1371 }
1372 
1384 template<class Type>
1386  vpImage<Type> &C)
1387 {
1388 
1389  try
1390  {
1391  if ((A.getHeight() != C.getHeight())
1392  || (A.getWidth() != C.getWidth()))
1393  C.resize(A.getHeight(), A.getWidth());
1394  }
1395  catch(vpException me)
1396  {
1397  vpERROR_TRACE("Error caught") ;
1398  std::cout << me << std::endl ;
1399  throw ;
1400  }
1401 
1402  if ( (A.getWidth() != B.getWidth())||(A.getHeight() != B.getHeight()))
1403  {
1404  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1406  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1407  }
1408 
1409  for (unsigned int i=0;i<A.getWidth()*A.getHeight();i++)
1410  {
1411  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i) ;
1412  }
1413 }
1414 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1415 
1426 template<class Type>
1427 void
1429 {
1430  if (B == NULL || C == NULL) {
1432  "Images are not allocated in vpImage<>::sub()")) ;
1433  }
1434  if ( (this->getWidth() != B->getWidth())
1435  || (this->getHeight() != B->getHeight())
1436  || (this->getWidth() != C->getWidth())
1437  || (this->getHeight() != C->getHeight()))
1438  {
1439  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1441  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1442  }
1443 
1444  for(unsigned int i = 0; i < height * width; i++)
1445  C->bitmap[i] = this->bitmap[i] - B->bitmap[i];
1446 }
1447 
1461 template<class Type>
1462 void
1464 {
1465  unsigned int r = height/2;
1466  unsigned int c = width/2;
1467  if(res == NULL) {
1469  "Images are not allocated in vpImage<>::sub()")) ;
1470  }
1471  if((res->getWidth() != c) || (res->getHeight()!= r))
1472  res->resize(r,c);
1473  for(unsigned int y = 0; y < r; y++)
1474  for(unsigned int x = 0; x < c; x++)
1475  (*res)[y][x] = (*this)[y*2][x*2];
1476 }
1477 
1489 template<class Type>
1490 void
1492 {
1493  unsigned int r = height/4;
1494  unsigned int c = width/4;
1495  if(res == NULL) {
1497  "Images are not allocated in vpImage<>::sub()")) ;
1498  }
1499  if((res->getWidth() != c) || (res->getHeight()!= r))
1500  res->resize(r,c);
1501  for(unsigned int y = 0; y < r; y++)
1502  for(unsigned int x = 0; x < c; x++)
1503  (*res)[y][x] = (*this)[y*4][x*4];
1504 }
1505 
1517 template<class Type>
1518 void
1520 {
1521  int h = height*2;
1522  int w = width*2;
1523 
1524  if(res == NULL) {
1526  "Images are not allocated in vpImage<>::sub()")) ;
1527  }
1528  if((res->getWidth() != w) || (res->getHeight()!= h))
1529  res->resize(h, w);
1530 
1531  for(int j = 0; j < h; j++)
1532  for(int i = 0; i < w; i++)
1533  (*res)[j][i] = (*this)[j/2][i/2];
1534 
1535  /*
1536  A B C
1537  E F G
1538  H I J
1539  A C H J are pixels from original image
1540  B E G I are interpolated pixels
1541  */
1542 
1543  //interpolate pixels B and I
1544  for(int j = 0; j < h; j += 2)
1545  for(int i = 1; i < w - 1; i += 2)
1546  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2][i/2 + 1]));
1547 
1548  //interpolate pixels E and G
1549  for(int j = 1; j < h - 1; j += 2)
1550  for(int i = 0; i < w; i += 2)
1551  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2+1][i/2]));
1552 
1553  //interpolate pixel F
1554  for(int j = 1; j < h - 1; j += 2)
1555  for(int i = 1; i < w - 1; i += 2)
1556  (*res)[j][i] = (Type)(0.25 * ((*this)[j/2][i/2] + (*this)[j/2][i/2+1] +
1557  (*this)[j/2+1][i/2] + (*this)[j/2+1][i/2+1]));
1558 }
1559 
1560 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1561 
1562 #endif
1563 
1564 
1565 /*
1566  * Local variables:
1567  * c-basic-offset: 2
1568  * End:
1569  */
unsigned int getCols() const
Definition: vpImage.h:178
vpDisplay * display
Definition: vpImage.h:121
#define vpDEBUG_TRACE
Definition: vpDebug.h:482
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:978
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:176
double get_i() const
Definition: vpImagePoint.h:194
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:384
Type operator()(const unsigned int i, const unsigned int j) const
Definition: vpImage.h:235
#define vpERROR_TRACE
Definition: vpDebug.h:395
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:649
#define vpTRACE
Definition: vpDebug.h:418
void halfSizeImage(vpImage< Type > &res)
Definition: vpImage.h:899
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:264
error that can be emited by ViSP classes.
Definition: vpException.h:76
Type getValue(double i, double j) const
Definition: vpImage.h:1029
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:633
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:219
virtual ~vpImage()
destructor
Definition: vpImage.h:584
static int round(const double x)
Definition: vpMath.h:228
double get_j() const
Definition: vpImagePoint.h:205
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:68
void quarterSizeImage(vpImage< Type > &res)
Definition: vpImage.h:933
unsigned int getRows() const
Definition: vpImage.h:169
void set_i(const double ii)
Definition: vpImagePoint.h:158
vpImage< Type > & operator=(const vpImage< Type > &I)
Copy operator.
Definition: vpImage.h:663
unsigned int getSize() const
Definition: vpImage.h:187
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:758
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:280
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:617
const Type * operator[](int i) const
Definition: vpImage.h:224
unsigned int getNumberOfPixel() const
Definition: vpImage.h:212
void resize(const unsigned int h, const unsigned int w)
set the size of the image
Definition: vpImage.h:532
void destroy()
destructor
Definition: vpImage.h:553
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:223
void set_j(const double jj)
Definition: vpImagePoint.h:169
void insert(const vpImage< Type > &src, const vpImagePoint topLeft)
Definition: vpImage.h:816
Type * operator[](const int i)
Definition: vpImage.h:220
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:799
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:248
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:738
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1344