ViSP  2.6.2
vpImage.h
1 /****************************************************************************
2  *
3  * $Id: vpImage.h 3689 2012-04-26 06:34:16Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 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 
109 template<class Type>
110 class vpImage
111 {
112  friend class vpImageConvert;
113 
114 public:
115  Type *bitmap ;
117 
119  vpImage() ;
121  vpImage(const vpImage<Type>&);
123  vpImage(unsigned int height, unsigned int width) ;
125  vpImage(unsigned int height, unsigned int width, Type value) ;
127  virtual ~vpImage() ;
129  void init(unsigned int height, unsigned int width) ;
131  void init(unsigned int height, unsigned int width, Type value) ;
133  void resize(const unsigned int height, const unsigned int width) ;
135  void destroy() ;
136 
145  inline unsigned int getHeight() const { return height; }
154  inline unsigned int getWidth() const { return width; }
155 
164  inline unsigned int getRows() const { return height ; }
165 
173  inline unsigned int getCols() const { return width ; }
174 
182  inline unsigned int getSize() const { return width*height ; }
183 
184 
185  // Return the maximum value within the bitmap
186  Type getMaxValue() const ;
187  // Return the minumum value within the bitmap
188  Type getMinValue() const ;
189  //Look for the minumum and the maximum value within the bitmap
190  void getMinMaxValue(Type &min, Type &max) const;
191 
192  // Gets the value of a pixel at a location with bilinear interpolation.
193  Type getValue(double i, double j) const;
194  // Gets the value of a pixel at a location with bilinear interpolation.
195  Type getValue(vpImagePoint &ip) const;
196 
207  inline unsigned int getNumberOfPixel() const{ return npixels; }
208 
209  //------------------------------------------------------------------
210  // Acces to the image
211 
212 
214  inline Type *operator[]( const unsigned int i) { return row[i];}
215 
217  inline const Type *operator[](unsigned int i) const { return row[i];}
218 
228  inline Type operator()(const unsigned int i, const unsigned int j) const
229  {
230  return bitmap[i*width+j] ;
231  }
241  inline void operator()(const unsigned int i, const unsigned int j,
242  const Type &v)
243  {
244  bitmap[i*width+j] = v ;
245  }
257  inline Type operator()(const vpImagePoint &ip) const
258  {
259  unsigned int i = (unsigned int) ip.get_i();
260  unsigned int j = (unsigned int) ip.get_j();
261 
262  return bitmap[i*width+j] ;
263  }
273  inline void operator()(const vpImagePoint &ip,
274  const Type &v)
275  {
276  unsigned int i = (unsigned int) ip.get_i();
277  unsigned int j = (unsigned int) ip.get_j();
278 
279  bitmap[i*width+j] = v ;
280  }
281 
283 
285  void operator=(const vpImage<Type> &I) ;
286 
287  void operator=(const Type &v);
288  bool operator==(const vpImage<Type> &I);
289  bool operator!=(const vpImage<Type> &I);
290 
291  void insert(const vpImage<Type> &src, const vpImagePoint topLeft);
292 
293 
294  // Returns a new image that's half size of the current image
295  void halfSizeImage(vpImage<Type> &res);
296 
297  // Returns a new image that's a quarter size of the current image
298  void quarterSizeImage(vpImage<Type> &res);
299 
300  // Returns a new image that's double size of the current image
301  void doubleSizeImage(vpImage<Type> &res);
302 
303  void sub(const vpImage<Type> &B, vpImage<Type> &C);
304  void sub(const vpImage<Type> &A, const vpImage<Type> &B, vpImage<Type> &C);
305 
306 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
307 
310  vp_deprecated void sub(vpImage<Type>* im2, vpImage<Type>* dst);
311  // Returns a new image that's half size of the current image
312  vp_deprecated void halfSizeImage(vpImage<Type>* res);
313  // Returns a new image that's a quarter size of the current image
314  vp_deprecated void quarterSizeImage(vpImage<Type>* res);
315  // Returns a new image that's double size of the current image
316  vp_deprecated void doubleSizeImage(vpImage<Type>* res);
317 #endif
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 
337 template<class Type>
338 void
339 vpImage<Type>::init(unsigned int height, unsigned int width, Type value)
340 {
341  try
342  {
343  init(height,width) ;
344  }
345  catch(vpException me)
346  {
347  vpERROR_TRACE(" ") ;
348  throw ;
349  }
350 
351  for (unsigned int i=0 ; i < npixels ; i++)
352  bitmap[i] = value ;
353 }
354 
355 
370 template<class Type>
371 void
372 vpImage<Type>::init(unsigned int height, unsigned int width)
373 {
374 
375  if (height != this->height) {
376  if (row != NULL) {
377  vpDEBUG_TRACE(10,"Destruction row[]");
378  delete [] row;
379  row = NULL;
380  }
381  }
382 
383  if ((height != this->height) || (width != this->width))
384  {
385  if (bitmap != NULL) {
386  vpDEBUG_TRACE(10,"Destruction bitmap[]") ;
387  delete [] bitmap;
388  bitmap = NULL;
389  }
390  }
391 
392 
393 
394  this->width = width ;
395  this->height = height ;
396 
397  npixels=width*height;
398 
399 
400  if (bitmap == NULL) bitmap = new Type[npixels] ;
401 
402  // vpERROR_TRACE("Allocate bitmap %p",bitmap) ;
403  if (bitmap == NULL)
404  {
405  vpERROR_TRACE("cannot allocate bitmap ") ;
407  "cannot allocate bitmap ")) ;
408  }
409 
410  if (row == NULL) row = new Type*[height] ;
411 // vpERROR_TRACE("Allocate row %p",row) ;
412  if (row == NULL)
413  {
414  vpERROR_TRACE("cannot allocate row ") ;
416  "cannot allocate row ")) ;
417  }
418 
419  unsigned int i ;
420  for ( i =0 ; i < height ; i++)
421  row[i] = bitmap + i*width ;
422 }
423 
439 template<class Type>
440 vpImage<Type>::vpImage(unsigned int height, unsigned int width)
441 {
442  bitmap = NULL ;
443  row = NULL ;
444 
445  display = NULL ;
446  this->height = this->width = 0 ;
447  try
448  {
449  init(height,width,0) ;
450  }
451  catch(vpException me)
452  {
453  vpERROR_TRACE(" ") ;
454  throw ;
455  }
456 }
457 
473 template<class Type>
474 vpImage<Type>::vpImage (unsigned int height, unsigned int width, Type value)
475 {
476  bitmap = NULL ;
477  row = NULL ;
478 
479  display = NULL ;
480  this->height = this->width = 0 ;
481  try
482  {
483  init(height,width,value) ;
484  }
485  catch(vpException me)
486  {
487  vpERROR_TRACE(" ") ;
488  throw ;
489  }
490 }
491 
501 template<class Type>
503 {
504  bitmap = NULL ;
505  row = NULL ;
506 
507  display = NULL ;
508 
509  this->height = this->width = 0 ;
510  this->npixels = 0;
511 }
512 
528 template<class Type>
529 void
530 vpImage<Type>::resize(unsigned int height, unsigned int width)
531 {
532  try
533  {
534  init(height, width) ;
535  }
536  catch(vpException me)
537  {
538  vpERROR_TRACE(" ") ;
539  throw ;
540  }
541 }
542 
549 template<class Type>
550 void
552 {
553  // vpERROR_TRACE("Deallocate ") ;
554 
555 
556  if (bitmap!=NULL)
557  {
558  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap) ;
559 // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap) ;
560  delete [] bitmap ;
561  bitmap = NULL;
562  }
563 
564 
565  if (row!=NULL)
566  {
567  // vpERROR_TRACE("Deallocate row memory %p",row) ;
568 // vpDEBUG_TRACE(20,"Deallocate row memory %p",row) ;
569  delete [] row ;
570  row = NULL;
571  }
572 
573 }
574 
581 template<class Type>
583 {
584  destroy() ;
585 }
586 
587 
588 
592 template<class Type>
594 {
595  bitmap = NULL ;
596  row = NULL ;
597  /* 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 */
598  this->width = 0;
599  this->height = 0;
600  this->npixels = 0;
601  try
602  {
603  //if (I.bitmap!=NULL)
604 // if(I.getHeight() != 0 || I.getWidth() != 0)
605  {
606  resize(I.getHeight(),I.getWidth());
607  unsigned int i;
608  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
609  for (i =0 ; i < this->height ; i++) row[i] = bitmap + i*this->width ;
610  }
611  }
612  catch(vpException me)
613  {
614  vpERROR_TRACE(" ") ;
615  throw ;
616  }
617 }
618 
624 template<class Type>
626 {
627  Type m = bitmap[0] ;
628  for (unsigned int i=0 ; i < npixels ; i++)
629  {
630  if (bitmap[i]>m) m = bitmap[i] ;
631  }
632  return m ;
633 }
634 
640 template<class Type>
642 {
643  Type m = bitmap[0];
644  for (unsigned int i=0 ; i < npixels ; i++)
645  if (bitmap[i]<m) m = bitmap[i] ;
646  return m ;
647 }
648 
649 
656 template<class Type>
657 void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
658 {
659  min = max = bitmap[0];
660  for (unsigned int i=0 ; i < npixels ; i++)
661  {
662  if (bitmap[i]<min) min = bitmap[i] ;
663  if (bitmap[i]>max) max = bitmap[i] ;
664  }
665 }
666 
670 template<class Type>
672 {
673  /* 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 */
674  if(bitmap != NULL){
675  delete[] bitmap;
676  bitmap = NULL ;
677  }
678 
679  if(row != NULL){
680  delete[] row;
681  row = NULL ;
682  }
683  this->width = I.width;
684  this->height = I.height;
685  this->npixels = I.npixels;
686  try
687  {
688  if(I.npixels != 0)
689  {
690  if (bitmap == NULL){
691  bitmap = new Type[npixels] ;
692  }
693 
694  if (bitmap == NULL){
695  vpERROR_TRACE("cannot allocate bitmap ") ;
697  "cannot allocate bitmap ")) ;
698  }
699 
700  if (row == NULL){
701  row = new Type*[height] ;
702  }
703  if (row == NULL){
704  vpERROR_TRACE("cannot allocate row ") ;
706  "cannot allocate row ")) ;
707  }
708 
709  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
710 
711  for (unsigned int i=0; i<this->height; i++){
712  row[i] = bitmap + i*this->width;
713  }
714  }
715  }
716  catch(vpException me)
717  {
718  vpERROR_TRACE(" ") ;
719  throw ;
720  }
721 }
722 
723 
730 template<class Type>
731 void vpImage<Type>::operator=(const Type &v)
732 {
733  for (unsigned int i=0 ; i < npixels ; i++)
734  bitmap[i] = v ;
735 }
736 
742 template<class Type>
744 {
745  if (this->width != I.getWidth())
746  return false;
747  if (this->height != I.getHeight())
748  return false;
749 
750  for (unsigned int i=0 ; i < npixels ; i++)
751  {
752  if (bitmap[i] != I.bitmap[i])
753  return false;
754  }
755  return true ;
756 }
762 template<class Type>
764 {
765  if (this->width != I.getWidth())
766  return true;
767  if (this->height != I.getHeight())
768  return true;
769 
770  for (unsigned int i=0 ; i < npixels ; i++)
771  {
772  if (bitmap[i] == I.bitmap[i])
773  return false;
774  }
775  return true ;
776 }
777 
803 template<class Type>
805 {
806  vpImage<Type> C;
807  sub(*this,B,C);
808  return C;
809 }
810 
820 template<class Type>
822  const vpImagePoint topLeft)
823 {
824  Type* srcBitmap;
825  Type* destBitmap;
826 
827  int itl = (int)topLeft.get_i();
828  int jtl = (int)topLeft.get_j();
829 
830  int dest_ibegin = 0;
831  int dest_jbegin = 0;
832  int src_ibegin = 0;
833  int src_jbegin = 0;
834  int dest_w = this->getWidth();
835  int dest_h = this->getHeight();
836  int src_w = src.getWidth();
837  int src_h = src.getHeight();
838  int wsize = src.getWidth();
839  int hsize = src.getHeight();
840 
841  if (itl >= dest_h || jtl >= dest_w)
842  return;
843 
844  if (itl < 0)
845  src_ibegin = -itl;
846  else
847  dest_ibegin = itl;
848 
849  if (jtl < 0)
850  src_jbegin = -jtl;
851  else
852  dest_jbegin = jtl;
853 
854  if (src_w - src_jbegin > dest_w - dest_jbegin)
855  wsize = dest_w - dest_jbegin;
856  else
857  wsize = src_w - src_jbegin;
858 
859  if (src_h - src_ibegin > dest_h - dest_ibegin)
860  hsize = dest_h - dest_ibegin;
861  else
862  hsize = src_h - src_ibegin;
863 
864  for (int i = 0; i < hsize; i++)
865  {
866  srcBitmap = src.bitmap + ((src_ibegin+i)*src_w+src_jbegin);
867  destBitmap = this->bitmap + ((dest_ibegin+i)*dest_w+dest_jbegin);
868 
869  memcpy(destBitmap,srcBitmap,wsize*sizeof(Type));
870  }
871 }
872 
902 template<class Type>
903 void
905 {
906  unsigned int h = height/2;
907  unsigned int w = width/2;
908  res.resize(h, w);
909  for(unsigned int i = 0; i < h; i++)
910  for(unsigned int j = 0; j < w; j++)
911  res[i][j] = (*this)[i<<1][j<<1];
912 }
913 
936 template<class Type>
937 void
939 {
940  unsigned int h = height/4;
941  unsigned int w = width/4;
942  res.resize(h, w);
943  for(unsigned int i = 0; i < h; i++)
944  for(unsigned int j = 0; j < w; j++)
945  res[i][j] = (*this)[i<<2][j<<2];
946 }
947 
981 template<class Type>
982 void
984 {
985  int h = height*2;
986  int w = width*2;
987 
988  res.resize(h, w);
989 
990  for(int i = 0; i < h; i++)
991  for(int j = 0; j < w; j++)
992  res[i][j] = (*this)[i>>1][j>>1];
993 
994  /*
995  A B C
996  E F G
997  H I J
998  A C H J are pixels from original image
999  B E G I are interpolated pixels
1000  */
1001 
1002  //interpolate pixels B and I
1003  for(int i = 0; i < h; i += 2)
1004  for(int j = 1; j < w - 1; j += 2)
1005  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1006  + (*this)[i>>1][(j>>1) + 1]));
1007 
1008  //interpolate pixels E and G
1009  for(int i = 1; i < h - 1; i += 2)
1010  for(int j = 0; j < w; j += 2)
1011  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1012  + (*this)[(i>>1)+1][j>>1]));
1013 
1014  //interpolate pixel F
1015  for(int i = 1; i < h - 1; i += 2)
1016  for(int j = 1; j < w - 1; j += 2)
1017  res[i][j] = (Type)(0.25 * ((*this)[i>>1][j>>1]
1018  + (*this)[i>>1][(j>>1)+1]
1019  + (*this)[(i>>1)+1][j>>1]
1020  + (*this)[(i>>1)+1][(j>>1)+1]));
1021 }
1022 
1033 template<class Type>
1034 Type vpImage<Type>::getValue(double /* i */, double /* j */) const
1035 {
1036  vpTRACE("Not implemented");
1037 }
1038 
1056 template<>
1057 inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const
1058 {
1059  unsigned int iround, jround;
1060  double rfrac, cfrac;
1061 
1062  iround = (unsigned int)floor(i);
1063  jround = (unsigned int)floor(j);
1064 
1065  if (iround >= height || jround >= width) {
1066  vpERROR_TRACE("Pixel outside the image") ;
1068  "Pixel outside the image"));
1069  }
1070 
1071  if (i > height - 1)
1072  i = (double)(height - 1);
1073 
1074  if (j > width - 1)
1075  j = (double)(width - 1);
1076 
1077  double rratio = i - (double) iround;
1078  if(rratio < 0)
1079  rratio=-rratio;
1080  double cratio = j - (double) jround;
1081  if(cratio < 0)
1082  cratio=-cratio;
1083 
1084  rfrac = 1.0f - rratio;
1085  cfrac = 1.0f - cratio;
1086 
1087 
1088  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1089  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1090  return (unsigned char)vpMath::round(value);
1091 }
1092 
1093 
1111 template<>
1112 inline double vpImage<double>::getValue(double i, double j) const
1113 {
1114  unsigned int iround, jround;
1115  double rfrac, cfrac;
1116 
1117  iround = (unsigned int)floor(i);
1118  jround = (unsigned int)floor(j);
1119 
1120  if (iround >= height || jround >= width) {
1121  vpERROR_TRACE("Pixel outside the image") ;
1123  "Pixel outside the image"));
1124  }
1125 
1126  if (i > height - 1)
1127  i = (double)(height - 1);
1128 
1129  if (j > width - 1)
1130  j = (double)(width - 1);
1131 
1132  double rratio = i - (double) iround;
1133  if(rratio < 0)
1134  rratio=-rratio;
1135  double cratio = j - (double) jround;
1136  if(cratio < 0)
1137  cratio=-cratio;
1138 
1139  rfrac = 1.0f - rratio;
1140  cfrac = 1.0f - cratio;
1141 
1142 
1143  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1144  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1145  return value;
1146 }
1147 
1148 template<>
1149 inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1150 {
1151  unsigned int iround, jround;
1152  double rfrac, cfrac;
1153 
1154  iround = (unsigned int)floor(i);
1155  jround = (unsigned int)floor(j);
1156 
1157  if (iround >= height || jround >= width) {
1158  vpERROR_TRACE("Pixel outside the image") ;
1160  "Pixel outside the image"));
1161  }
1162 
1163  if (i > height - 1)
1164  i = (double)(height - 1);
1165 
1166  if (j > width - 1)
1167  j = (double)(width - 1);
1168 
1169  double rratio = i - (double) iround;
1170  if(rratio < 0)
1171  rratio=-rratio;
1172  double cratio = j - (double) jround;
1173  if(cratio < 0)
1174  cratio=-cratio;
1175 
1176  rfrac = 1.0f - rratio;
1177  cfrac = 1.0f - cratio;
1178 
1179  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1180  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1181  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1182  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1183  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1184  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1185  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1186 }
1187 
1198 template<class Type>
1200 {
1201  vpTRACE("Not implemented");
1202 }
1203 
1204 template<>
1205 inline unsigned char vpImage<unsigned char>::getValue(vpImagePoint &ip) const
1206 {
1207  unsigned int iround, jround;
1208  double rfrac, cfrac;
1209 
1210  iround = (unsigned int)floor(ip.get_i());
1211  jround = (unsigned int)floor(ip.get_j());
1212 
1213  if (iround >= height || jround >= width) {
1214  vpERROR_TRACE("Pixel outside the image") ;
1216  "Pixel outside the image"));
1217  }
1218 
1219  if (ip.get_i() > height - 1)
1220  ip.set_i((double)(height - 1));
1221 
1222  if (ip.get_j() > width - 1)
1223  ip.set_j((double)(width - 1));
1224 
1225  double rratio = ip.get_i() - (double) iround;
1226  if(rratio < 0)
1227  rratio=-rratio;
1228  double cratio = ip.get_j() - (double) jround;
1229  if(cratio < 0)
1230  cratio=-cratio;
1231 
1232  rfrac = 1.0f - rratio;
1233  cfrac = 1.0f - cratio;
1234 
1235 
1236  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1237  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1238  return (unsigned char)vpMath::round(value);
1239 }
1240 
1241 
1242 template<>
1243 inline double vpImage<double>::getValue(vpImagePoint &ip) const
1244 {
1245  unsigned int iround, jround;
1246  double rfrac, cfrac;
1247 
1248  iround = (unsigned int)floor(ip.get_i());
1249  jround = (unsigned int)floor(ip.get_j());
1250 
1251  if (iround >= height || jround >= width) {
1252  vpERROR_TRACE("Pixel outside the image") ;
1254  "Pixel outside the image"));
1255  }
1256 
1257  if (ip.get_i() > height - 1)
1258  ip.set_i((double)(height - 1));
1259 
1260  if (ip.get_j() > width - 1)
1261  ip.set_j((double)(width - 1));
1262 
1263  double rratio = ip.get_i() - (double) iround;
1264  if(rratio < 0)
1265  rratio=-rratio;
1266  double cratio = ip.get_j() - (double) jround;
1267  if(cratio < 0)
1268  cratio=-cratio;
1269 
1270  rfrac = 1.0f - rratio;
1271  cfrac = 1.0f - cratio;
1272 
1273 
1274  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1275  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1276  return value;
1277 }
1278 
1279 template<>
1281 {
1282  unsigned int iround, jround;
1283  double rfrac, cfrac;
1284 
1285  iround = (unsigned int)floor(ip.get_i());
1286  jround = (unsigned int)floor(ip.get_j());
1287 
1288  if (iround >= height || jround >= width) {
1289  vpERROR_TRACE("Pixel outside the image") ;
1291  "Pixel outside the image"));
1292  }
1293 
1294  if (ip.get_i() > height - 1)
1295  ip.set_i((double)(height - 1));
1296 
1297  if (ip.get_j() > width - 1)
1298  ip.set_j((double)(width - 1));
1299 
1300  double rratio = ip.get_i() - (double) iround;
1301  if(rratio < 0)
1302  rratio=-rratio;
1303  double cratio = ip.get_j() - (double) jround;
1304  if(cratio < 0)
1305  cratio=-cratio;
1306 
1307  rfrac = 1.0f - rratio;
1308  cfrac = 1.0f - cratio;
1309 
1310  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1311  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1312  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1313  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1314  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1315  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1316  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1317 }
1318 
1348 template<class Type>
1350 {
1351 
1352  try
1353  {
1354  if ((this->getHeight() != C.getHeight())
1355  || (this->getWidth() != C.getWidth()))
1356  C.resize(this->getHeight(), this->getWidth());
1357  }
1358  catch(vpException me)
1359  {
1360  vpERROR_TRACE("Error caught") ;
1361  std::cout << me << std::endl ;
1362  throw ;
1363  }
1364 
1365  if ( (this->getWidth() != B.getWidth())||(this->getHeight() != B.getHeight()))
1366  {
1367  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1369  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1370  }
1371 
1372  for (unsigned int i=0;i<this->getWidth()*this->getHeight();i++)
1373  {
1374  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i) ;
1375  }
1376 }
1377 
1389 template<class Type>
1391  vpImage<Type> &C)
1392 {
1393 
1394  try
1395  {
1396  if ((A.getHeight() != C.getHeight())
1397  || (A.getWidth() != C.getWidth()))
1398  C.resize(A.getHeight(), A.getWidth());
1399  }
1400  catch(vpException me)
1401  {
1402  vpERROR_TRACE("Error caught") ;
1403  std::cout << me << std::endl ;
1404  throw ;
1405  }
1406 
1407  if ( (A.getWidth() != B.getWidth())||(A.getHeight() != B.getHeight()))
1408  {
1409  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1411  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1412  }
1413 
1414  for (unsigned int i=0;i<A.getWidth()*A.getHeight();i++)
1415  {
1416  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i) ;
1417  }
1418 }
1419 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1420 
1431 template<class Type>
1432 void
1434 {
1435  if (B == NULL || C == NULL) {
1437  "Images are not allocated in vpImage<>::sub()")) ;
1438  }
1439  if ( (this->getWidth() != B->getWidth())
1440  || (this->getHeight() != B->getHeight())
1441  || (this->getWidth() != C->getWidth())
1442  || (this->getHeight() != C->getHeight()))
1443  {
1444  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1446  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1447  }
1448 
1449  for(unsigned int i = 0; i < height * width; i++)
1450  C->bitmap[i] = this->bitmap[i] - B->bitmap[i];
1451 }
1452 
1466 template<class Type>
1467 void
1469 {
1470  unsigned int r = height/2;
1471  unsigned int c = width/2;
1472  if(res == NULL) {
1474  "Images are not allocated in vpImage<>::sub()")) ;
1475  }
1476  if((res->getWidth() != c) || (res->getHeight()!= r))
1477  res->resize(r,c);
1478  for(unsigned int y = 0; y < r; y++)
1479  for(unsigned int x = 0; x < c; x++)
1480  (*res)[y][x] = (*this)[y*2][x*2];
1481 }
1482 
1494 template<class Type>
1495 void
1497 {
1498  unsigned int r = height/4;
1499  unsigned int c = width/4;
1500  if(res == NULL) {
1502  "Images are not allocated in vpImage<>::sub()")) ;
1503  }
1504  if((res->getWidth() != c) || (res->getHeight()!= r))
1505  res->resize(r,c);
1506  for(unsigned int y = 0; y < r; y++)
1507  for(unsigned int x = 0; x < c; x++)
1508  (*res)[y][x] = (*this)[y*4][x*4];
1509 }
1510 
1522 template<class Type>
1523 void
1525 {
1526  int h = height*2;
1527  int w = width*2;
1528 
1529  if(res == NULL) {
1531  "Images are not allocated in vpImage<>::sub()")) ;
1532  }
1533  if((res->getWidth() != w) || (res->getHeight()!= h))
1534  res->resize(h, w);
1535 
1536  for(int j = 0; j < h; j++)
1537  for(int i = 0; i < w; i++)
1538  (*res)[j][i] = (*this)[j/2][i/2];
1539 
1540  /*
1541  A B C
1542  E F G
1543  H I J
1544  A C H J are pixels from original image
1545  B E G I are interpolated pixels
1546  */
1547 
1548  //interpolate pixels B and I
1549  for(int j = 0; j < h; j += 2)
1550  for(int i = 1; i < w - 1; i += 2)
1551  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2][i/2 + 1]));
1552 
1553  //interpolate pixels E and G
1554  for(int j = 1; j < h - 1; j += 2)
1555  for(int i = 0; i < w; i += 2)
1556  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2+1][i/2]));
1557 
1558  //interpolate pixel F
1559  for(int j = 1; j < h - 1; j += 2)
1560  for(int i = 1; i < w - 1; i += 2)
1561  (*res)[j][i] = (Type)(0.25 * ((*this)[j/2][i/2] + (*this)[j/2][i/2+1] +
1562  (*this)[j/2+1][i/2] + (*this)[j/2+1][i/2+1]));
1563 }
1564 
1565 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1566 
1567 #endif
1568 
1569 
1570 /*
1571  * Local variables:
1572  * c-basic-offset: 2
1573  * End:
1574  */
unsigned int getCols() const
Definition: vpImage.h:173
void set_j(const double j)
Definition: vpImagePoint.h:156
vpDisplay * display
Definition: vpImage.h:116
#define vpDEBUG_TRACE
Definition: vpDebug.h:454
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:983
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:167
double get_i() const
Definition: vpImagePoint.h:181
unsigned int getWidth() const
Definition: vpImage.h:154
void init(unsigned int height, unsigned int width)
set the size of the image
Definition: vpImage.h:372
Type operator()(const unsigned int i, const unsigned int j) const
Definition: vpImage.h:228
#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:657
#define vpTRACE
Definition: vpDebug.h:401
void halfSizeImage(vpImage< Type > &res)
Definition: vpImage.h:904
Type * bitmap
points toward the bitmap
Definition: vpImage.h:115
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:257
void resize(const unsigned int height, const unsigned int width)
set the size of the image
Definition: vpImage.h:530
void set_i(const double i)
Definition: vpImagePoint.h:145
Type getValue(double i, double j) const
Definition: vpImage.h:1034
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:641
Convert image types.
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:214
virtual ~vpImage()
destructor
Definition: vpImage.h:582
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:938
unsigned int getRows() const
Definition: vpImage.h:164
unsigned int getSize() const
Definition: vpImage.h:182
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:763
void operator()(const vpImagePoint &ip, const Type &v)
Definition: vpImage.h:273
Type getMaxValue() const
Return the maximum value within the bitmap.
Definition: vpImage.h:625
unsigned int getNumberOfPixel() const
Definition: vpImage.h:207
void operator=(const vpImage< Type > &I)
Copy operator.
Definition: vpImage.h:671
void destroy()
destructor
Definition: vpImage.h:551
const Type * operator[](unsigned int i) const
operator[] allows operation like x = I[i]
Definition: vpImage.h:217
void insert(const vpImage< Type > &src, const vpImagePoint topLeft)
Definition: vpImage.h:821
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:804
unsigned int getHeight() const
Definition: vpImage.h:145
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:241
vpImage()
constructor
Definition: vpImage.h:502
Definition of the vpImage class member functions.
Definition: vpImage.h:110
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:743
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1349