core/vil/vil_transform.h
Go to the documentation of this file.
00001 // This is core/vil/vil_transform.h
00002 #ifndef vil_transform_h_
00003 #define vil_transform_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief STL algorithm like methods.
00010 // \author Ian Scott.
00011 
00012 #include <vcl_cassert.h>
00013 #include <vil/vil_image_view.h>
00014 
00015 //: Apply a unary operation to each pixel in image.
00016 // \param functor should take a value of type T and return same type
00017 // \relatesalso vil_image_view
00018 template <class T, class F >
00019 inline void vil_transform(vil_image_view<T >& image, F functor)
00020 {
00021   const unsigned ni = image.ni(), nj= image.nj(), np = image.nplanes();
00022 
00023   vcl_ptrdiff_t istep=image.istep(),jstep=image.jstep(),pstep = image.planestep();
00024   T* plane = image.top_left_ptr();
00025 
00026   if (istep==1)
00027   {
00028     // Optimise special case
00029     for (unsigned p=0;p<np;++p,plane += pstep)
00030     {
00031       T* row = plane;
00032       for (unsigned j=0;j<nj;++j,row += jstep)
00033       {
00034         T *pixel = row, *end_row = row+ni;
00035         for (;pixel!=end_row;++pixel) *pixel = functor(*pixel);
00036       }
00037     }
00038   }
00039   else
00040   if (jstep==1)
00041   {
00042     // Optimise special case
00043     for (unsigned p=0;p<np;++p,plane += pstep)
00044     {
00045       T* col = plane;
00046       for (unsigned i=0;i<ni;++i,col += istep)
00047       {
00048         T *pixel = col, *end_col=col+nj;
00049         for (;pixel!=end_col;++pixel) *pixel = functor(*pixel);
00050       }
00051     }
00052   }
00053   else
00054   {
00055     // General case
00056     for (unsigned p=0;p<np;++p,plane += pstep)
00057     {
00058       T* row = plane;
00059       for (unsigned j=0;j<nj;++j,row += jstep)
00060       {
00061         T* pixel = row;
00062         for (unsigned i=0;i<ni;++i,pixel+=istep)
00063           *pixel = functor(*pixel);
00064       }
00065     }
00066   }
00067 }
00068 
00069 
00070 //: Apply a unary operation to each pixel in src to get dest.
00071 // \param functor should take a value of type inP, and return a value of type outP
00072 // \relatesalso vil_image_view
00073 template <class inP, class outP, class Op >
00074 inline void vil_transform(const vil_image_view<inP >&src, vil_image_view<outP >&dest, Op functor)
00075 {
00076   const unsigned ni = src.ni(), nj= src.nj(), np = src.nplanes();
00077 
00078   dest.set_size(ni, nj, np);
00079 
00080   // Optimise special case;
00081   if (dest.istep()==1 && src.istep()==1)
00082   {
00083     for (unsigned p = 0; p < np; ++p)
00084       for (unsigned j = 0; j < nj; ++j)
00085       {
00086         const inP* src_row = &src(0,j,p);
00087         outP* dest_row = &dest(0,j,p);
00088         for (unsigned i = 0; i < ni; ++i)
00089           dest_row[i] = functor(src_row[i]);
00090       }
00091     return;
00092   }
00093 
00094   for (unsigned p = 0; p < np; ++p)
00095     for (unsigned j = 0; j < nj; ++j)
00096       for (unsigned i = 0; i < ni; ++i)
00097         dest(i,j,p) = functor(src(i,j,p));
00098 }
00099 
00100 //: Apply a binary function to each pixel in src and dest that modifies dest.
00101 // \param functor should take two parameters (inP src, outP &dest);
00102 // \relatesalso vil_image_view
00103 template <class inP, class outP, class Op >
00104 inline void vil_transform2(const vil_image_view<inP >&src, vil_image_view<outP >&dest, Op functor)
00105 {
00106   const unsigned ni = src.ni(), nj= src.nj(), np = src.nplanes();
00107 
00108   dest.set_size(ni, nj, np);
00109 
00110   // Optimise special case;
00111   if (dest.istep()==1 && src.istep()==1)
00112   {
00113     for (unsigned p = 0; p < np; ++p)
00114       for (unsigned j = 0; j < nj; ++j)
00115       {
00116         const inP* src_row = &src(0,j,p);
00117         outP* dest_row = &dest(0,j,p);
00118         for (unsigned i = 0; i < ni; ++i)
00119           functor(src_row[i],dest_row[i]);
00120       }
00121     return;
00122   }
00123 
00124   for (unsigned p = 0; p < np; ++p)
00125     for (unsigned j = 0; j < nj; ++j)
00126       for (unsigned i = 0; i < ni; ++i)
00127          functor(src(i,j,p), dest(i,j,p));
00128 }
00129 
00130 
00131 //: Apply a binary operation to each pixel in srcA and srcB to get dest.
00132 // \relatesalso vil_image_view
00133 template <class inA, class inB, class outP, class BinOp >
00134 inline void vil_transform(const vil_image_view<inA >&srcA,
00135                           const vil_image_view<inB >&srcB,
00136                           vil_image_view<outP >&dest,
00137                           BinOp functor)
00138 {
00139   assert(srcB.ni() == srcA.ni() && srcA.nj() == srcB.nj() && srcA.nplanes() == srcB.nplanes());
00140   dest.set_size(srcA.ni(), srcA.nj(), srcA.nplanes());
00141   for (unsigned p = 0; p < srcA.nplanes(); ++p)
00142     for (unsigned j = 0; j < srcA.nj(); ++j)
00143       for (unsigned i = 0; i < srcA.ni(); ++i)
00144         dest(i,j,p) = functor(srcA(i,j,p),srcB(i,j,p));
00145 }
00146 
00147 //: Apply a binary operation to each pixel in srcA and srcB to get dest.
00148 // non-const dest version, assumes dest is already correct size.
00149 // \relatesalso vil_image_view
00150 template <class inA, class inB, class outP, class BinOp >
00151 inline void vil_transform(const vil_image_view<inA >&srcA,
00152                           const vil_image_view<inB >&srcB,
00153                           const vil_image_view<outP >&dest,
00154                           BinOp functor)
00155 {
00156   assert(dest.ni() == srcA.ni() && srcA.nj() == dest.nj() && srcA.nplanes() == dest.nplanes());
00157   assert(srcB.ni() == srcA.ni() && srcA.nj() == srcB.nj() && srcA.nplanes() == srcB.nplanes());
00158   vil_image_view<outP >& nc_dest = const_cast<vil_image_view<outP >&>(dest);
00159   for (unsigned p = 0; p < srcA.nplanes(); ++p)
00160     for (unsigned j = 0; j < srcA.nj(); ++j)
00161       for (unsigned i = 0; i < srcA.ni(); ++i)
00162         nc_dest(i,j,p) = functor(srcA(i,j,p),srcB(i,j,p));
00163 }
00164 
00165 
00166 #endif // vil_transform_h_