ViSP  2.10.0
vpImage.h
1 /****************************************************************************
2  *
3  * $Id: vpImage.h 5126 2015-01-05 22:07: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 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 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
316 
319  vp_deprecated void sub(vpImage<Type>* im2, vpImage<Type>* dst);
320  // Returns a new image that's half size of the current image
321  vp_deprecated void halfSizeImage(vpImage<Type>* res);
322  // Returns a new image that's a quarter size of the current image
323  vp_deprecated void quarterSizeImage(vpImage<Type>* res);
324  // Returns a new image that's double size of the current image
325  vp_deprecated void doubleSizeImage(vpImage<Type>* res);
326 #endif
327 private:
328  unsigned int npixels ; //<! number of pixel in the image
329  unsigned int width ; //<! number of columns
330  unsigned int height ; //<! number of rows
331  Type **row ;
332  } ;
333 
334 
348 template<class Type>
349 void
350 vpImage<Type>::init(unsigned int h, unsigned int w, Type value)
351 {
352  try
353  {
354  init(h,w) ;
355  }
356  catch(vpException me)
357  {
358  vpERROR_TRACE(" ") ;
359  throw ;
360  }
361 
362  for (unsigned int i=0 ; i < npixels ; i++)
363  bitmap[i] = value ;
364 }
365 
366 
384 template<class Type>
385 void
386 vpImage<Type>::init(unsigned int h, unsigned int w)
387 {
388 
389  if (h != this->height) {
390  if (row != NULL) {
391  vpDEBUG_TRACE(10,"Destruction row[]");
392  delete [] row;
393  row = NULL;
394  }
395  }
396 
397  if ((h != this->height) || (w != this->width))
398  {
399  if (bitmap != NULL) {
400  vpDEBUG_TRACE(10,"Destruction bitmap[]") ;
401  delete [] bitmap;
402  bitmap = NULL;
403  }
404  }
405 
406  this->width = w ;
407  this->height = h;
408 
409  npixels=width*height;
410 
411  if (bitmap == NULL) bitmap = new Type[npixels] ;
412 
413  // vpERROR_TRACE("Allocate bitmap %p",bitmap) ;
414  if (bitmap == NULL)
415  {
416  vpERROR_TRACE("cannot allocate bitmap ") ;
418  "cannot allocate bitmap ")) ;
419  }
420 
421  if (row == NULL) row = new Type*[height] ;
422 // vpERROR_TRACE("Allocate row %p",row) ;
423  if (row == NULL)
424  {
425  vpERROR_TRACE("cannot allocate row ") ;
427  "cannot allocate row ")) ;
428  }
429 
430  unsigned int i ;
431  for ( i =0 ; i < height ; i++)
432  row[i] = bitmap + i*width ;
433 }
434 
453 template<class Type>
454 vpImage<Type>::vpImage(unsigned int h, unsigned int w)
455  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
456 {
457  try
458  {
459  init(h,w,0) ;
460  }
461  catch(...)
462  {
463  throw ;
464  }
465 }
466 
484 template<class Type>
485 vpImage<Type>::vpImage (unsigned int h, unsigned int w, Type value)
486  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
487 {
488  try
489  {
490  init(h,w,value) ;
491  }
492  catch(vpException me)
493  {
494  vpERROR_TRACE(" ") ;
495  throw ;
496  }
497 }
498 
508 template<class Type>
510  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
511 {
512 }
513 
534 template<class Type>
535 void
536 vpImage<Type>::resize(unsigned int h, unsigned int w)
537 {
538  try
539  {
540  init(h, w) ;
541  }
542  catch(vpException me)
543  {
544  vpERROR_TRACE(" ") ;
545  throw ;
546  }
547 }
548 
568 template<class Type>
569 void
570 vpImage<Type>::resize(unsigned int h, unsigned int w, const Type val)
571 {
572  try
573  {
574  init(h, w, val) ;
575  }
576  catch(vpException me)
577  {
578  vpERROR_TRACE(" ") ;
579  throw ;
580  }
581 }
582 
583 
590 template<class Type>
591 void
593 {
594  // vpERROR_TRACE("Deallocate ") ;
595 
596 
597  if (bitmap!=NULL)
598  {
599  // vpERROR_TRACE("Deallocate bitmap memory %p",bitmap) ;
600 // vpDEBUG_TRACE(20,"Deallocate bitmap memory %p",bitmap) ;
601  delete [] bitmap ;
602  bitmap = NULL;
603  }
604 
605 
606  if (row!=NULL)
607  {
608  // vpERROR_TRACE("Deallocate row memory %p",row) ;
609 // vpDEBUG_TRACE(20,"Deallocate row memory %p",row) ;
610  delete [] row ;
611  row = NULL;
612  }
613 
614 }
615 
622 template<class Type>
624 {
625  destroy() ;
626 }
627 
628 
629 
633 template<class Type>
635  : bitmap(NULL), display(NULL), npixels(0), width(0), height(0), row(NULL)
636 {
637  try
638  {
639  resize(I.getHeight(),I.getWidth());
640  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
641  for (unsigned int i =0 ; i < this->height ; i++) row[i] = bitmap + i*this->width ;
642  }
643  catch(vpException me)
644  {
645  vpERROR_TRACE(" ") ;
646  throw ;
647  }
648 }
649 
655 template<class Type>
657 {
658  Type m = bitmap[0] ;
659  for (unsigned int i=0 ; i < npixels ; i++)
660  {
661  if (bitmap[i]>m) m = bitmap[i] ;
662  }
663  return m ;
664 }
665 
671 template<class Type>
673 {
674  Type m = bitmap[0];
675  for (unsigned int i=0 ; i < npixels ; i++)
676  if (bitmap[i]<m) m = bitmap[i] ;
677  return m ;
678 }
679 
680 
687 template<class Type>
688 void vpImage<Type>::getMinMaxValue(Type &min, Type &max) const
689 {
690  min = max = bitmap[0];
691  for (unsigned int i=0 ; i < npixels ; i++)
692  {
693  if (bitmap[i]<min) min = bitmap[i] ;
694  if (bitmap[i]>max) max = bitmap[i] ;
695  }
696 }
697 
701 template<class Type>
703 {
704  /* 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 */
705  if(bitmap != NULL){
706  delete[] bitmap;
707  bitmap = NULL ;
708  }
709 
710  if(row != NULL){
711  delete[] row;
712  row = NULL ;
713  }
714  this->width = I.width;
715  this->height = I.height;
716  this->npixels = I.npixels;
717  try
718  {
719  if(I.npixels != 0)
720  {
721  if (bitmap == NULL){
722  bitmap = new Type[npixels] ;
723  }
724 
725  if (bitmap == NULL){
726  vpERROR_TRACE("cannot allocate bitmap ") ;
728  "cannot allocate bitmap ")) ;
729  }
730 
731  if (row == NULL){
732  row = new Type*[height] ;
733  }
734  if (row == NULL){
735  vpERROR_TRACE("cannot allocate row ") ;
737  "cannot allocate row ")) ;
738  }
739 
740  memcpy(bitmap, I.bitmap, I.npixels*sizeof(Type)) ;
741 
742  for (unsigned int i=0; i<this->height; i++){
743  row[i] = bitmap + i*this->width;
744  }
745  }
746  }
747  catch(vpException me)
748  {
749  vpERROR_TRACE(" ") ;
750  throw ;
751  }
752  return (* this);
753 }
754 
755 
762 template<class Type>
764 {
765  for (unsigned int i=0 ; i < npixels ; i++)
766  bitmap[i] = v ;
767 
768  return *this;
769 }
770 
776 template<class Type>
778 {
779  if (this->width != I.getWidth())
780  return false;
781  if (this->height != I.getHeight())
782  return false;
783 
784  for (unsigned int i=0 ; i < npixels ; i++)
785  {
786  if (bitmap[i] != I.bitmap[i])
787  return false;
788  }
789  return true ;
790 }
796 template<class Type>
798 {
799  if (this->width != I.getWidth())
800  return true;
801  if (this->height != I.getHeight())
802  return true;
803 
804  for (unsigned int i=0 ; i < npixels ; i++)
805  {
806  if (bitmap[i] == I.bitmap[i])
807  return false;
808  }
809  return true ;
810 }
811 
837 template<class Type>
839 {
840  vpImage<Type> C;
841  sub(*this,B,C);
842  return C;
843 }
844 
854 template<class Type>
856  const vpImagePoint topLeft)
857 {
858  Type* srcBitmap;
859  Type* destBitmap;
860 
861  int itl = (int)topLeft.get_i();
862  int jtl = (int)topLeft.get_j();
863 
864  int dest_ibegin = 0;
865  int dest_jbegin = 0;
866  int src_ibegin = 0;
867  int src_jbegin = 0;
868  int dest_w = (int)this->getWidth();
869  int dest_h = (int)this->getHeight();
870  int src_w = (int)src.getWidth();
871  int src_h = (int)src.getHeight();
872  int wsize = (int)src.getWidth();
873  int hsize = (int)src.getHeight();
874 
875  if (itl >= dest_h || jtl >= dest_w)
876  return;
877 
878  if (itl < 0)
879  src_ibegin = -itl;
880  else
881  dest_ibegin = itl;
882 
883  if (jtl < 0)
884  src_jbegin = -jtl;
885  else
886  dest_jbegin = jtl;
887 
888  if (src_w - src_jbegin > dest_w - dest_jbegin)
889  wsize = dest_w - dest_jbegin;
890  else
891  wsize = src_w - src_jbegin;
892 
893  if (src_h - src_ibegin > dest_h - dest_ibegin)
894  hsize = dest_h - dest_ibegin;
895  else
896  hsize = src_h - src_ibegin;
897 
898  for (int i = 0; i < hsize; i++)
899  {
900  srcBitmap = src.bitmap + ((src_ibegin+i)*src_w+src_jbegin);
901  destBitmap = this->bitmap + ((dest_ibegin+i)*dest_w+dest_jbegin);
902 
903  memcpy(destBitmap,srcBitmap,wsize*sizeof(Type));
904  }
905 }
906 
936 template<class Type>
937 void
939 {
940  unsigned int h = height/2;
941  unsigned int w = width/2;
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<<1][j<<1];
946 }
947 
970 template<class Type>
971 void
973 {
974  unsigned int h = height/4;
975  unsigned int w = width/4;
976  res.resize(h, w);
977  for(unsigned int i = 0; i < h; i++)
978  for(unsigned int j = 0; j < w; j++)
979  res[i][j] = (*this)[i<<2][j<<2];
980 }
981 
1015 template<class Type>
1016 void
1018 {
1019  int h = height*2;
1020  int w = width*2;
1021 
1022  res.resize(h, w);
1023 
1024  for(int i = 0; i < h; i++)
1025  for(int j = 0; j < w; j++)
1026  res[i][j] = (*this)[i>>1][j>>1];
1027 
1028  /*
1029  A B C
1030  E F G
1031  H I J
1032  A C H J are pixels from original image
1033  B E G I are interpolated pixels
1034  */
1035 
1036  //interpolate pixels B and I
1037  for(int i = 0; i < h; i += 2)
1038  for(int j = 1; j < w - 1; j += 2)
1039  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1040  + (*this)[i>>1][(j>>1) + 1]));
1041 
1042  //interpolate pixels E and G
1043  for(int i = 1; i < h - 1; i += 2)
1044  for(int j = 0; j < w; j += 2)
1045  res[i][j] = (Type)(0.5 * ((*this)[i>>1][j>>1]
1046  + (*this)[(i>>1)+1][j>>1]));
1047 
1048  //interpolate pixel F
1049  for(int i = 1; i < h - 1; i += 2)
1050  for(int j = 1; j < w - 1; j += 2)
1051  res[i][j] = (Type)(0.25 * ((*this)[i>>1][j>>1]
1052  + (*this)[i>>1][(j>>1)+1]
1053  + (*this)[(i>>1)+1][j>>1]
1054  + (*this)[(i>>1)+1][(j>>1)+1]));
1055 }
1056 
1067 template<class Type>
1068 Type vpImage<Type>::getValue(double /* i */, double /* j */) const
1069 {
1070  vpTRACE("Not implemented");
1071 }
1072 
1090 template<>
1091 inline unsigned char vpImage<unsigned char>::getValue(double i, double j) const
1092 {
1093  unsigned int iround, jround;
1094  double rfrac, cfrac;
1095 
1096  iround = (unsigned int)floor(i);
1097  jround = (unsigned int)floor(j);
1098 
1099  if (iround >= height || jround >= width) {
1100  vpERROR_TRACE("Pixel outside the image") ;
1102  "Pixel outside the image"));
1103  }
1104 
1105  if (i > height - 1)
1106  i = (double)(height - 1);
1107 
1108  if (j > width - 1)
1109  j = (double)(width - 1);
1110 
1111  double rratio = i - (double) iround;
1112  if(rratio < 0)
1113  rratio=-rratio;
1114  double cratio = j - (double) jround;
1115  if(cratio < 0)
1116  cratio=-cratio;
1117 
1118  rfrac = 1.0f - rratio;
1119  cfrac = 1.0f - cratio;
1120 
1121 
1122  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1123  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1124  return (unsigned char)vpMath::round(value);
1125 }
1126 
1127 
1145 template<>
1146 inline double vpImage<double>::getValue(double i, double j) const
1147 {
1148  unsigned int iround, jround;
1149  double rfrac, cfrac;
1150 
1151  iround = (unsigned int)floor(i);
1152  jround = (unsigned int)floor(j);
1153 
1154  if (iround >= height || jround >= width) {
1155  vpERROR_TRACE("Pixel outside the image") ;
1157  "Pixel outside the image"));
1158  }
1159 
1160  if (i > height - 1)
1161  i = (double)(height - 1);
1162 
1163  if (j > width - 1)
1164  j = (double)(width - 1);
1165 
1166  double rratio = i - (double) iround;
1167  if(rratio < 0)
1168  rratio=-rratio;
1169  double cratio = j - (double) jround;
1170  if(cratio < 0)
1171  cratio=-cratio;
1172 
1173  rfrac = 1.0f - rratio;
1174  cfrac = 1.0f - cratio;
1175 
1176 
1177  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1178  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1179  return value;
1180 }
1181 
1182 template<>
1183 inline vpRGBa vpImage<vpRGBa>::getValue(double i, double j) const
1184 {
1185  unsigned int iround, jround;
1186  double rfrac, cfrac;
1187 
1188  iround = (unsigned int)floor(i);
1189  jround = (unsigned int)floor(j);
1190 
1191  if (iround >= height || jround >= width) {
1192  vpERROR_TRACE("Pixel outside the image") ;
1194  "Pixel outside the image"));
1195  }
1196 
1197  if (i > height - 1)
1198  i = (double)(height - 1);
1199 
1200  if (j > width - 1)
1201  j = (double)(width - 1);
1202 
1203  double rratio = i - (double) iround;
1204  if(rratio < 0)
1205  rratio=-rratio;
1206  double cratio = j - (double) jround;
1207  if(cratio < 0)
1208  cratio=-cratio;
1209 
1210  rfrac = 1.0f - rratio;
1211  cfrac = 1.0f - cratio;
1212 
1213  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1214  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1215  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1216  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1217  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1218  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1219  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1220 }
1221 
1232 template<class Type>
1234 {
1235  vpTRACE("Not implemented");
1236 }
1237 
1238 template<>
1239 inline unsigned char vpImage<unsigned char>::getValue(vpImagePoint &ip) const
1240 {
1241  unsigned int iround, jround;
1242  double rfrac, cfrac;
1243 
1244  iround = (unsigned int)floor(ip.get_i());
1245  jround = (unsigned int)floor(ip.get_j());
1246 
1247  if (iround >= height || jround >= width) {
1248  vpERROR_TRACE("Pixel outside the image") ;
1250  "Pixel outside the image"));
1251  }
1252 
1253  if (ip.get_i() > height - 1)
1254  ip.set_i((double)(height - 1));
1255 
1256  if (ip.get_j() > width - 1)
1257  ip.set_j((double)(width - 1));
1258 
1259  double rratio = ip.get_i() - (double) iround;
1260  if(rratio < 0)
1261  rratio=-rratio;
1262  double cratio = ip.get_j() - (double) jround;
1263  if(cratio < 0)
1264  cratio=-cratio;
1265 
1266  rfrac = 1.0f - rratio;
1267  cfrac = 1.0f - cratio;
1268 
1269 
1270  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1271  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1272  return (unsigned char)vpMath::round(value);
1273 }
1274 
1275 
1276 template<>
1277 inline double vpImage<double>::getValue(vpImagePoint &ip) const
1278 {
1279  unsigned int iround, jround;
1280  double rfrac, cfrac;
1281 
1282  iround = (unsigned int)floor(ip.get_i());
1283  jround = (unsigned int)floor(ip.get_j());
1284 
1285  if (iround >= height || jround >= width) {
1286  vpERROR_TRACE("Pixel outside the image") ;
1288  "Pixel outside the image"));
1289  }
1290 
1291  if (ip.get_i() > height - 1)
1292  ip.set_i((double)(height - 1));
1293 
1294  if (ip.get_j() > width - 1)
1295  ip.set_j((double)(width - 1));
1296 
1297  double rratio = ip.get_i() - (double) iround;
1298  if(rratio < 0)
1299  rratio=-rratio;
1300  double cratio = ip.get_j() - (double) jround;
1301  if(cratio < 0)
1302  cratio=-cratio;
1303 
1304  rfrac = 1.0f - rratio;
1305  cfrac = 1.0f - cratio;
1306 
1307 
1308  double value = ((double)row[iround][jround] * rfrac + (double)row[iround+1][jround] * rratio)*cfrac
1309  + ((double)row[iround][jround+1]*rfrac + (double)row[iround+1][jround+1] * rratio)*cratio;
1310  return value;
1311 }
1312 
1313 template<>
1315 {
1316  unsigned int iround, jround;
1317  double rfrac, cfrac;
1318 
1319  iround = (unsigned int)floor(ip.get_i());
1320  jround = (unsigned int)floor(ip.get_j());
1321 
1322  if (iround >= height || jround >= width) {
1323  vpERROR_TRACE("Pixel outside the image") ;
1325  "Pixel outside the image"));
1326  }
1327 
1328  if (ip.get_i() > height - 1)
1329  ip.set_i((double)(height - 1));
1330 
1331  if (ip.get_j() > width - 1)
1332  ip.set_j((double)(width - 1));
1333 
1334  double rratio = ip.get_i() - (double) iround;
1335  if(rratio < 0)
1336  rratio=-rratio;
1337  double cratio = ip.get_j() - (double) jround;
1338  if(cratio < 0)
1339  cratio=-cratio;
1340 
1341  rfrac = 1.0f - rratio;
1342  cfrac = 1.0f - cratio;
1343 
1344  double valueR = ((double)row[iround][jround].R * rfrac + (double)row[iround+1][jround].R * rratio)*cfrac
1345  + ((double)row[iround][jround+1].R * rfrac + (double)row[iround+1][jround+1].R * rratio)*cratio;
1346  double valueG = ((double)row[iround][jround].G * rfrac + (double)row[iround+1][jround].G * rratio)*cfrac
1347  + ((double)row[iround][jround+1].G* rfrac + (double)row[iround+1][jround+1].G * rratio)*cratio;
1348  double valueB = ((double)row[iround][jround].B * rfrac + (double)row[iround+1][jround].B * rratio)*cfrac
1349  + ((double)row[iround][jround+1].B*rfrac + (double)row[iround+1][jround+1].B * rratio)*cratio;
1350  return vpRGBa((unsigned char)vpMath::round(valueR),(unsigned char)vpMath::round(valueG),(unsigned char)vpMath::round(valueB));
1351 }
1352 
1382 template<class Type>
1384 {
1385 
1386  try
1387  {
1388  if ((this->getHeight() != C.getHeight())
1389  || (this->getWidth() != C.getWidth()))
1390  C.resize(this->getHeight(), this->getWidth());
1391  }
1392  catch(vpException me)
1393  {
1394  vpERROR_TRACE("Error caught") ;
1395  std::cout << me << std::endl ;
1396  throw ;
1397  }
1398 
1399  if ( (this->getWidth() != B.getWidth())||(this->getHeight() != B.getHeight()))
1400  {
1401  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1403  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1404  }
1405 
1406  for (unsigned int i=0;i<this->getWidth()*this->getHeight();i++)
1407  {
1408  *(C.bitmap + i) = *(bitmap + i) - *(B.bitmap + i) ;
1409  }
1410 }
1411 
1423 template<class Type>
1425  vpImage<Type> &C)
1426 {
1427 
1428  try
1429  {
1430  if ((A.getHeight() != C.getHeight())
1431  || (A.getWidth() != C.getWidth()))
1432  C.resize(A.getHeight(), A.getWidth());
1433  }
1434  catch(vpException me)
1435  {
1436  vpERROR_TRACE("Error caught") ;
1437  std::cout << me << std::endl ;
1438  throw ;
1439  }
1440 
1441  if ( (A.getWidth() != B.getWidth())||(A.getHeight() != B.getHeight()))
1442  {
1443  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1445  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1446  }
1447 
1448  for (unsigned int i=0;i<A.getWidth()*A.getHeight();i++)
1449  {
1450  *(C.bitmap + i) = *(A.bitmap + i) - *(B.bitmap + i) ;
1451  }
1452 }
1453 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1454 
1465 template<class Type>
1466 void
1468 {
1469  if (B == NULL || C == NULL) {
1471  "Images are not allocated in vpImage<>::sub()")) ;
1472  }
1473  if ( (this->getWidth() != B->getWidth())
1474  || (this->getHeight() != B->getHeight())
1475  || (this->getWidth() != C->getWidth())
1476  || (this->getHeight() != C->getHeight()))
1477  {
1478  vpERROR_TRACE("\n\t\t vpImage mismatch in vpImage/vpImage substraction") ;
1480  "vpImage mismatch in vpImage/vpImage substraction ")) ;
1481  }
1482 
1483  for(unsigned int i = 0; i < height * width; i++)
1484  C->bitmap[i] = this->bitmap[i] - B->bitmap[i];
1485 }
1486 
1500 template<class Type>
1501 void
1503 {
1504  unsigned int r = height/2;
1505  unsigned int c = width/2;
1506  if(res == NULL) {
1508  "Images are not allocated in vpImage<>::sub()")) ;
1509  }
1510  if((res->getWidth() != c) || (res->getHeight()!= r))
1511  res->resize(r,c);
1512  for(unsigned int y = 0; y < r; y++)
1513  for(unsigned int x = 0; x < c; x++)
1514  (*res)[y][x] = (*this)[y*2][x*2];
1515 }
1516 
1528 template<class Type>
1529 void
1531 {
1532  unsigned int r = height/4;
1533  unsigned int c = width/4;
1534  if(res == NULL) {
1536  "Images are not allocated in vpImage<>::sub()")) ;
1537  }
1538  if((res->getWidth() != c) || (res->getHeight()!= r))
1539  res->resize(r,c);
1540  for(unsigned int y = 0; y < r; y++)
1541  for(unsigned int x = 0; x < c; x++)
1542  (*res)[y][x] = (*this)[y*4][x*4];
1543 }
1544 
1556 template<class Type>
1557 void
1559 {
1560  int h = height*2;
1561  int w = width*2;
1562 
1563  if(res == NULL) {
1565  "Images are not allocated in vpImage<>::sub()")) ;
1566  }
1567  if((res->getWidth() != w) || (res->getHeight()!= h))
1568  res->resize(h, w);
1569 
1570  for(int j = 0; j < h; j++)
1571  for(int i = 0; i < w; i++)
1572  (*res)[j][i] = (*this)[j/2][i/2];
1573 
1574  /*
1575  A B C
1576  E F G
1577  H I J
1578  A C H J are pixels from original image
1579  B E G I are interpolated pixels
1580  */
1581 
1582  //interpolate pixels B and I
1583  for(int j = 0; j < h; j += 2)
1584  for(int i = 1; i < w - 1; i += 2)
1585  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2][i/2 + 1]));
1586 
1587  //interpolate pixels E and G
1588  for(int j = 1; j < h - 1; j += 2)
1589  for(int i = 0; i < w; i += 2)
1590  (*res)[j][i] = (Type)(0.5 * ((*this)[j/2][i/2] + (*this)[j/2+1][i/2]));
1591 
1592  //interpolate pixel F
1593  for(int j = 1; j < h - 1; j += 2)
1594  for(int i = 1; i < w - 1; i += 2)
1595  (*res)[j][i] = (Type)(0.25 * ((*this)[j/2][i/2] + (*this)[j/2][i/2+1] +
1596  (*this)[j/2+1][i/2] + (*this)[j/2+1][i/2+1]));
1597 }
1598 
1599 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1600 
1601 #endif
unsigned int getCols() const
Definition: vpImage.h:180
vpDisplay * display
Definition: vpImage.h:121
#define vpDEBUG_TRACE
Definition: vpDebug.h:482
void doubleSizeImage(vpImage< Type > &res)
Definition: vpImage.h:1017
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:174
double get_i() const
Definition: vpImagePoint.h:195
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:386
Type operator()(const unsigned int i, const unsigned int j) const
Definition: vpImage.h:237
#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:688
#define vpTRACE
Definition: vpDebug.h:418
void halfSizeImage(vpImage< Type > &res)
Definition: vpImage.h:938
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
Type operator()(const vpImagePoint &ip) const
Definition: vpImage.h:266
error that can be emited by ViSP classes.
Definition: vpException.h:76
Type getValue(double i, double j) const
Definition: vpImage.h:1068
Type getMinValue() const
Return the minimum value within the bitmap.
Definition: vpImage.h:672
Type * operator[](const unsigned int i)
operator[] allows operation like I[i] = x.
Definition: vpImage.h:221
virtual ~vpImage()
destructor
Definition: vpImage.h:623
static int round(const double x)
Definition: vpMath.h:228
double get_j() const
Definition: vpImagePoint.h:206
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:68
void quarterSizeImage(vpImage< Type > &res)
Definition: vpImage.h:972
unsigned int getRows() const
Definition: vpImage.h:171
void set_i(const double ii)
Definition: vpImagePoint.h:159
vpImage< Type > & operator=(const vpImage< Type > &I)
Copy operator.
Definition: vpImage.h:702
unsigned int getSize() const
Definition: vpImage.h:189
bool operator!=(const vpImage< Type > &I)
Definition: vpImage.h:797
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:656
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:536
void destroy()
destructor
Definition: vpImage.h:592
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:170
void insert(const vpImage< Type > &src, const vpImagePoint topLeft)
Definition: vpImage.h:855
Type * operator[](const int i)
Definition: vpImage.h:222
vpImage< Type > operator-(const vpImage< Type > &B)
Definition: vpImage.h:838
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:93
void operator()(const unsigned int i, const unsigned int j, const Type &v)
Definition: vpImage.h:250
vpImage()
constructor
Definition: vpImage.h:509
Definition of the vpImage class member functions.
Definition: vpImage.h:115
bool operator==(const vpImage< Type > &I)
Definition: vpImage.h:777
void sub(const vpImage< Type > &B, vpImage< Type > &C)
Definition: vpImage.h:1383