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

Generated on Sat Nov 22 05:07:54 2008 for core/vil by  doxygen 1.5.1