core/vil/vil_fill.h
Go to the documentation of this file.
00001 // This is core/vil/vil_fill.h
00002 #ifndef vil_fill_h_
00003 #define vil_fill_h_
00004 //:
00005 // \file
00006 // \brief Various functions for manipulating image views
00007 // \author Tim Cootes - Manchester
00008 
00009 #include <vcl_cassert.h>
00010 #include <vil/vil_image_view.h>
00011 #include <vcl_algorithm.h>
00012 
00013 //: Fill view with given value
00014 //  O(size).
00015 // \relatesalso vil_image_view
00016 template<class T>
00017 void vil_fill(vil_image_view<T>& view, T value)
00018 {
00019   if (view.is_contiguous())
00020     vcl_fill(view.begin(), view.end(), value);
00021 
00022   unsigned ni = view.ni();
00023   vcl_ptrdiff_t istep=view.istep();
00024   unsigned nj = view.nj();
00025   vcl_ptrdiff_t jstep=view.jstep();
00026   unsigned np = view.nplanes();
00027   vcl_ptrdiff_t pstep = view.planestep();
00028 
00029   T* plane = view.top_left_ptr();
00030   for (unsigned p=0;p<np;++p,plane += pstep)
00031   {
00032     T* row = plane;
00033     for (unsigned j=0;j<nj;++j,row += jstep)
00034     {
00035       T* pixel = row;
00036       for (unsigned i=0;i<ni;++i,pixel+=istep) *pixel=value;
00037     }
00038   }
00039 }
00040 
00041 //: Fill data[i*step] (i=0..n-1) with given value
00042 // \sa vil_fill_line(vil_image_view<T>)
00043 template<class T>
00044 void vil_fill_line(T* data, unsigned n, vcl_ptrdiff_t step, T value)
00045 {
00046   T* end_data = data + n*step;
00047   while (data!=end_data) { *data=value; data+=step; }
00048 }
00049 
00050 
00051 //: Fill line from (ai,aj) to (bi,bj) using Bresenham's algorithm.
00052 // Only modifies first plane.
00053 // \relatesalso vil_image_view
00054 template<class T>
00055 void vil_fill_line(vil_image_view<T> &im,
00056                    int ai, int aj, int bi, int bj,
00057                    T value)
00058 {
00059   if (ai == bi && aj==bj)
00060   {
00061     if (im.in_range(ai, aj)) im(ai,aj) = value;
00062     return;
00063   }
00064 
00065   int d, x, y, xinc, yinc, incr1, incr2;
00066 
00067   int dx = bi-ai;
00068   int dy = bj-aj;
00069   if (dy<0)
00070   {
00071     dy=-dy;
00072     yinc=-1;
00073   }
00074   else
00075     yinc=1;
00076 
00077   if (dx<0)
00078   {
00079     dx=-dx;
00080     xinc=-1;
00081   }
00082   else
00083     xinc=1;
00084 
00085   if (im.in_range(ai, aj)) im(ai, aj)=value;
00086   x=ai;
00087   y=aj;
00088   if (dy<=dx)
00089   {
00090     d=(dy<<1)-dx;
00091     incr1=dy<<1;
00092     incr2=-((dx-dy)<<1);
00093     while (x!=bi)
00094     {
00095       x+=xinc;
00096       if (d<0)
00097         d+=incr1;
00098       else
00099       {
00100         y+=yinc;
00101         d+=incr2;
00102       }
00103       if (im.in_range(x, y)) im(x, y)=value;
00104     }
00105   }
00106   else
00107   {
00108     d=(dx<<1)-dy;
00109     incr1=dx<<1;
00110     incr2=-((dy-dx)<<1);
00111     while (y!=bj)
00112     {
00113       y+=yinc;
00114       if (d<0)
00115         d+=incr1;
00116       else
00117       {
00118         x+=xinc;
00119         d+=incr2;
00120       }
00121       if (im.in_range(x, y)) im(x, y)=value;
00122     }
00123   }
00124 }
00125 
00126 //: Fill row j in view with given value
00127 //  O(ni).
00128 // \relatesalso vil_image_view
00129 template<class T>
00130 void vil_fill_row(vil_image_view<T>& view, unsigned j, T value)
00131 {
00132   unsigned ni = view.ni();      vcl_ptrdiff_t istep=view.istep();
00133   assert(j<view.nj());          vcl_ptrdiff_t jstep=view.jstep();
00134   unsigned np = view.nplanes(); vcl_ptrdiff_t pstep=view.planestep();
00135 
00136   T* row = view.top_left_ptr() + j*jstep;
00137   for (unsigned p=0;p<np;++p,row += pstep)
00138     vil_fill_line(row,ni,istep,value);
00139 }
00140 
00141 //: Fill column i in view with given value
00142 //  O(nj).
00143 // \relatesalso vil_image_view
00144 template<class T>
00145 void vil_fill_col(vil_image_view<T>& view, unsigned i, T value)
00146 {
00147   assert(i<view.ni());          vcl_ptrdiff_t istep=view.istep();
00148   unsigned nj = view.nj();      vcl_ptrdiff_t jstep=view.jstep();
00149   unsigned np = view.nplanes(); vcl_ptrdiff_t pstep=view.planestep();
00150 
00151   T* col_top = view.top_left_ptr() + i*istep;
00152   for (unsigned p=0;p<np;++p,col_top += pstep)
00153     vil_fill_line(col_top,nj,jstep,value);
00154 }
00155 
00156 //: Writes given value into each pixel of image under the elements of the mask set to b
00157 //  If mask.nplanes()==1 then the same mask is applied to every image plane, otherwise
00158 //  there must be the same number of mask planes as image planes.
00159 //  \relatesalso vil_image_view
00160 template<class srcT>
00161 inline
00162 void vil_fill_mask(vil_image_view<srcT>& image,
00163                    const vil_image_view<bool>& mask,
00164                    srcT value, bool b=true)
00165 {
00166   unsigned ni = image.ni(), nj = image.nj(), np = image.nplanes();
00167   assert(ni==mask.ni() && nj==mask.nj());
00168   assert(mask.nplanes()==1 ||  mask.nplanes() ==np);
00169 
00170   vcl_ptrdiff_t istepA=image.istep(),jstepA=image.jstep(),pstepA = image.planestep();
00171   vcl_ptrdiff_t istepB=mask.istep(),jstepB=mask.jstep(),pstepB = mask.planestep();
00172 
00173   // If only one mask plane, apply to all image planes
00174   // Setting pstepB to 0 ensures that the same mask is used for each pass
00175   if (mask.nplanes()==1) pstepB=0;
00176 
00177   srcT* planeA = image.top_left_ptr();
00178   const bool* planeB = mask.top_left_ptr();
00179   for (unsigned p=0;p<np;++p,planeA += pstepA,planeB += pstepB)
00180   {
00181     srcT* rowA   = planeA;
00182     const bool* rowB   = planeB;
00183     for (unsigned j=0;j<nj;++j,rowA += jstepA,rowB += jstepB)
00184     {
00185       srcT* pixelA = rowA;
00186       const bool* pixelB = rowB;
00187       for (unsigned i=0;i<ni;++i,pixelA+=istepA,pixelB+=istepB)
00188         if (*pixelB==b) *pixelA=value;
00189     }
00190   }
00191 }
00192 
00193 //: Fills pixels in disk with centre (ci,cj), radius r, with given value
00194 //  Fills all planes of image with the value.
00195 //  \relatesalso vil_image_view
00196 template<class T>
00197 inline
00198 void vil_fill_disk(vil_image_view<T>& image, double ci, double cj, double r, T value)
00199 {
00200   unsigned ilo = vcl_max(0,int(ci-r));
00201   unsigned ihi = vcl_max(0,vcl_min(int(image.ni()-1),int(ci+r+1.0)));
00202   unsigned jlo = vcl_max(0,int(cj-r));
00203   unsigned jhi = vcl_max(0,vcl_min(int(image.nj()-1),int(cj+r+1.0)));
00204 
00205   double r2 = r*r;
00206   for (unsigned j=jlo;j<=jhi;++j)
00207   {
00208     double t2 = r2 - (j-cj)*(j-cj);
00209     for (unsigned i=ilo;i<=ihi;++i)
00210     {
00211       if ((i-ci)*(i-ci)<t2)
00212       {
00213         for (unsigned k=0;k<image.nplanes();++k) image(i,j,k)=value;
00214       }
00215     }
00216   }
00217 }
00218 
00219 #endif // vil_fill_h_