CutPaste.C

Go to the documentation of this file.
00001 /*!@file Image/CutPaste.C Cut+paste operations from/to Image subregions */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters@klab.caltech.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/CutPaste.C $
00035 // $Id: CutPaste.C 14535 2011-02-18 22:40:51Z siagian $
00036 //
00037 
00038 #include "Image/CutPaste.H"
00039 
00040 #include "Image/Image.H"
00041 #include "Image/Pixels.H"
00042 #include "Util/Assert.H"
00043 #include "Util/safecopy.H"
00044 #include "rutz/trace.h"
00045 #include "Image/vec2.h"
00046 
00047 #include <algorithm>
00048 
00049 // ######################################################################
00050 template <class T>
00051 Image<T> concatX(const Image<T>& left, const Image<T>& right)
00052 {
00053 GVX_TRACE(__PRETTY_FUNCTION__);
00054 
00055   if (!left.initialized()) return right;
00056   else if (!right.initialized()) return left;
00057 
00058   ASSERT(left.getHeight() == right.getHeight());
00059   const int h = left.getHeight();
00060   const int wl = left.getWidth();
00061   const int wr = right.getWidth();
00062   Image<T> result(wl + wr, left.getHeight(), NO_INIT);
00063   typename Image<T>::const_iterator lptr = left.begin();
00064   typename Image<T>::const_iterator rptr = right.begin();
00065   typename Image<T>::iterator dptr = result.beginw();
00066   for (int j = 0; j < h; ++j)
00067     {
00068       for (int i1 = 0; i1 < wl; i1 ++) *dptr++ = *lptr++;
00069       for (int i2 = 0; i2 < wr; i2 ++) *dptr++ = *rptr++;
00070     }
00071 
00072   return result;
00073 }
00074 
00075 // ######################################################################
00076 template <class T>
00077 Image<T> concatY(const Image<T>& top, const Image<T>& bottom)
00078 {
00079 GVX_TRACE(__PRETTY_FUNCTION__);
00080 
00081   if (!top.initialized()) return bottom;
00082   else if (!bottom.initialized()) return top;
00083 
00084   ASSERT(top.getWidth() == bottom.getWidth());
00085   const int w = top.getWidth();
00086   const int ht = top.getHeight();
00087   const int hb = bottom.getHeight();
00088   Image<T> result(w, ht + hb, NO_INIT);
00089   typename Image<T>::const_iterator tptr = top.begin();
00090   typename Image<T>::const_iterator bptr = bottom.begin();
00091   typename Image<T>::iterator dptr = result.beginw();
00092   for (int i = 0; i < ht * w; ++i) *dptr++ = *tptr++;
00093   for (int i2 = 0; i2 < hb * w; i2 ++) *dptr++ = *bptr++;
00094   return result;
00095 }
00096 
00097 // ######################################################################
00098 template <class T>
00099 Image<T> concatLooseY(const Image<T>& topImg,
00100                       const Image<T>& bottomImg,
00101                       const T& bgColor)
00102 {
00103 GVX_TRACE(__PRETTY_FUNCTION__);
00104 
00105   const int dsth = topImg.getHeight() + bottomImg.getHeight();
00106   const int dstw = std::max(topImg.getWidth(), bottomImg.getWidth());
00107 
00108   const int topw = topImg.getWidth();
00109   const int toph = topImg.getHeight();
00110   const int botw = bottomImg.getWidth();
00111   const int both = bottomImg.getHeight();
00112 
00113   Image<T> result = Image<T>(dstw, dsth, NO_INIT);
00114 
00115   result.clear(bgColor);
00116 
00117   T* const dptr = result.getArrayPtr();
00118   const T* const topptr = topImg.getArrayPtr();
00119   const T* const botptr = bottomImg.getArrayPtr();
00120 
00121   for (int j=0; j < toph; ++j)
00122     for (int i=0; i < topw; ++i)
00123       dptr[i + j * dstw] = topptr[i + j * topw];
00124 
00125   for (int j=0; j < both; ++j)
00126     for (int i=0; i < botw; ++i)
00127       dptr[i + (j+toph) * dstw] = botptr[i + j * botw];
00128 
00129   return result;
00130 }
00131 
00132 // ######################################################################
00133 template <class T>
00134 Image<T> concatLooseX(const Image<T>& leftImg,
00135                       const Image<T>& rightImg,
00136                       const T& bgColor)
00137 {
00138 GVX_TRACE(__PRETTY_FUNCTION__);
00139 
00140   const int dstw = leftImg.getWidth() + rightImg.getWidth();
00141   const int dsth = std::max(leftImg.getHeight(), rightImg.getHeight());
00142 
00143   const int lw = leftImg.getWidth();
00144   const int lh = leftImg.getHeight();
00145   const int rw = rightImg.getWidth();
00146   const int rh = rightImg.getHeight();
00147 
00148   Image<T> result = Image<T>(dstw, dsth, NO_INIT);
00149 
00150   result.clear(bgColor);
00151 
00152   T* const dptr = result.getArrayPtr();
00153   const T* const lptr = leftImg.getArrayPtr();
00154   const T* const rptr = rightImg.getArrayPtr();
00155 
00156   for (int j=0; j < lh; ++j)
00157     for (int i=0; i < lw; ++i)
00158       dptr[i + j * dstw] = lptr[i + j * lw];
00159 
00160   for (int j=0; j < rh; ++j)
00161     for (int i=0; i < rw; ++i)
00162       dptr[(i + lw) + j * dstw] = rptr[i + j * rw];
00163 
00164   return result;
00165 }
00166 
00167 // ######################################################################
00168 template <class T>
00169 Image<T> crop(const Image<T>& src, const Point2D<int>& pt, const Dims& dims,
00170               const bool zerofill)
00171 {
00172 GVX_TRACE(__PRETTY_FUNCTION__);
00173 
00174   if (pt == Point2D<int>(0,0) && dims == src.getDims())
00175     return src;
00176 
00177   Image<T> result(dims, NO_INIT);
00178 
00179   typename Image<T>::iterator dptr = result.beginw();
00180 
00181   if (!zerofill)
00182     {
00183       ASSERT(src.coordsOk(pt));
00184       ASSERT(src.coordsOk(pt.i + dims.w() - 1, pt.j + dims.h() - 1));
00185 
00186       typename Image<T>::const_iterator sptr =
00187         src.begin()
00188         + pt.j * src.getWidth()   // Skip downward over starting rows
00189         + pt.i;                   // Skip rightward over starting columns
00190 
00191       const int src_catchup = src.getWidth() - result.getWidth();
00192 
00193       for (int y = 0; y < dims.h(); ++y)
00194         {
00195           for (int x = 0; x < dims.w(); ++x)
00196             {
00197               *dptr++ = *sptr++;
00198             }
00199           sptr += src_catchup;
00200         }
00201     }
00202   else
00203     {
00204       const T zero = T();
00205 
00206       const int ymax = pt.j + dims.h();
00207       const int xmax = pt.i + dims.w();
00208 
00209       for (int y = pt.j; y < ymax; ++y)
00210         for (int x = pt.i; x < xmax; ++x)
00211           {
00212             if (src.coordsOk(x, y)) *dptr = src.getVal(x, y);
00213             else                    *dptr = zero;
00214             ++dptr;
00215           }
00216     }
00217 
00218   return result;
00219 }
00220 
00221 // ######################################################################
00222 template <class T>
00223 Image<T> crop(const Image<T>& src, const Rectangle& rect, const bool zerofill)
00224 {
00225   return crop(src,
00226               Point2D<int>(rect.left(), rect.top()),
00227               Dims(rect.width(), rect.height()),
00228               zerofill);
00229 }
00230 
00231 // ######################################################################
00232 template <class T>
00233 Image<T> shift(const Image<T>& srcImg, const int dx, const int dy)
00234 {
00235 GVX_TRACE(__PRETTY_FUNCTION__);
00236 
00237   // make sure the source image is valid
00238   ASSERT(srcImg.initialized());
00239 
00240   // create and clear the return image
00241   Dims dim(srcImg.getDims());
00242   Image<T> retImg(srcImg.getDims(), ZEROS);
00243 
00244   // create the source and destination iterators
00245   typename Image<T>::const_iterator srcBegPtr = srcImg.begin();
00246   typename Image<T>::const_iterator srcEndPtr = srcImg.end();
00247   typename Image<T>::iterator retBegPtr = retImg.beginw();
00248   typename Image<T>::iterator retEndPtr = retImg.endw();
00249 
00250   // adjust the pointers according to the direction of image shift
00251   int shiftAmt = dy * dim.w() + dx;
00252   if(shiftAmt < 0)
00253     srcBegPtr -= shiftAmt;
00254   else
00255     retBegPtr += shiftAmt;
00256 
00257   // determine width of the actual data to be transferred
00258   //  int newW = dim.w() - abs(dx);
00259   //  int quad = dx*dy;
00260 
00261   // transfer from source to destination image
00262   //  for(int i=0; (srcBegPtr != srcEndPtr) && (retBegPtr != retEndPtr);
00263   //      ++i, ++srcBegPtr, ++retBegPtr) {
00264     //    if(((quad < 0) && (i%dim.w() < abs(dx))) ||
00265     //       ((quad > 0) && (i%dim.w() >= newW)))
00266     //      *retBegPtr = T(0);
00267     //    else
00268   //      *retBegPtr = *srcEndPtr;
00269   //  } // for block
00270 
00271   // transfer from source to destination image
00272   while((srcBegPtr != srcEndPtr) && (retBegPtr != retEndPtr))
00273     *retBegPtr++ = *srcBegPtr++;
00274 
00275   return retImg;
00276 }
00277 
00278 // ######################################################################
00279 template <class T>
00280 Image<T> shiftImage(const Image<T>& srcImg, const float dx, const float dy)
00281 {
00282 GVX_TRACE(__PRETTY_FUNCTION__);
00283 
00284   // make sure the source image is valid
00285   ASSERT(srcImg.initialized());
00286 
00287   // create and clear the return image
00288   Dims dim(srcImg.getDims());
00289   int w = dim.w(), h = dim.h();
00290   Image<T> retImg(dim, ZEROS);
00291 
00292   // prepare a couple of variable for the x direction
00293   int xt = (int)floor(dx);
00294   float xfrac = dx - xt;
00295   int startx = std::max(0,xt);
00296   int endx = std::min(0,xt) + w;
00297   if (fabs(xfrac) < 1.0e-10) xfrac = 0.0;
00298   else endx--;
00299 
00300   // prepare a couple of variable for the y direction
00301   int yt = (int)floor(dy);
00302   float yfrac = dy - yt;
00303   int starty = std::max(0,yt);
00304   int endy = std::min(0,yt) + h;
00305   if (fabs(yfrac) < 1.0e-10) yfrac = 0.0;
00306   else endy--;
00307 
00308   // dispatch to faster shiftClean() if displacements are roughly integer:
00309   if (fabs(xfrac) < 1.0e-10 && fabs(yfrac) < 1.0e-10)
00310     return shiftClean(srcImg, xt, yt);
00311 
00312   if (xfrac > 0.0)
00313   {
00314     xfrac = 1.0 - xfrac;
00315     xt++;
00316   }
00317 
00318   if (yfrac > 0.0)
00319   {
00320     yfrac = 1.0 - yfrac;
00321     yt++;
00322   }
00323 
00324   // prepare the coefficients
00325   float tl = (1.0 - xfrac) * (1.0 - yfrac);
00326   float tr = xfrac * (1.0 - yfrac);
00327   float bl = (1.0 - xfrac) * yfrac;
00328   float br = xfrac * yfrac;
00329 
00330   // prepare the pointers
00331   typename Image<T>::const_iterator src, src2 = srcImg.begin();
00332   typename Image<T>::iterator ret, ret2 = retImg.beginw();
00333   if (xt > 0) ret2 += xt;
00334   if (xt < 0) src2 -= xt;
00335   if (yt > 0) ret2 += yt * w;
00336   if (yt < 0) src2 -= yt * w;
00337 
00338   // now loop over the images
00339   for (int y = starty; y < endy; ++y)
00340     {
00341       src = src2; ret = ret2;
00342       for (int x = startx; x < endx; ++x)
00343         {
00344           (*ret) = (T)((*src) * tl);
00345           if (tr > 0.0) (*ret) += (T)((*(src + 1)) * tr);
00346           if (bl > 0.0) (*ret) += (T)((*(src + w)) * bl);
00347           if (br > 0.0) (*ret) += (T)((*(src + w + 1)) * br);
00348           ++src; ++ret;
00349         }
00350       src2 += w; ret2 += w;
00351     }
00352   return retImg;
00353 }
00354 
00355 // ######################################################################
00356 template <class T>
00357 Image<T> shiftClean(const Image<T>& srcImg, const int dx, const int dy,
00358                     const T bgval)
00359 {
00360 GVX_TRACE(__PRETTY_FUNCTION__);
00361 
00362   // make sure the source image is valid
00363   ASSERT(srcImg.initialized());
00364 
00365   // create and clear the return image
00366   int w = srcImg.getWidth(), h = srcImg.getHeight();
00367   Image<T> retImg(w, h, NO_INIT); retImg.clear(bgval);
00368 
00369   // create the source and destination iterators
00370   typename Image<T>::const_iterator src = srcImg.begin();
00371   typename Image<T>::iterator dst = retImg.beginw();
00372 
00373   // find range of pixels to copy:
00374   int startx = std::max(0, -dx), endx = std::min(w - 1, w - 1 - dx);
00375   if (startx >= w || endx < 0) return retImg; // empty result
00376   int starty = std::max(0, -dy), endy = std::min(h - 1, h - 1 - dy);
00377   if (starty >= h || endy < 0) return retImg; // empty result
00378 
00379   int dstx = std::max(0, std::min(w - 1, dx));
00380   int dsty = std::max(0, std::min(h - 1, dy));
00381 
00382   src += startx + starty * w;
00383   dst += dstx + dsty * w;
00384 
00385   int skip = w - endx + startx - 1;
00386 
00387   // do the copy:
00388   for (int j = starty; j <= endy; j ++)
00389     {
00390       for (int i = startx; i <= endx; i ++) *dst++ = *src++;
00391 
00392       // ready for next row of pixels:
00393       src += skip; dst += skip;
00394     }
00395 
00396   return retImg;
00397 }
00398 
00399 // ######################################################################
00400 template <class T>
00401 void inplacePaste(Image<T>& dst,
00402                   const Image<T>& img, const Point2D<int>& pos)
00403 {
00404 GVX_TRACE(__PRETTY_FUNCTION__);
00405 
00406   int w = dst.getWidth(), h = dst.getHeight();
00407   int iw = img.getWidth(), ih=img.getHeight();
00408 
00409   ASSERT(pos.i + iw <= w && pos.j + ih <= h);
00410 
00411   typename Image<T>::const_iterator sptr = img.begin();
00412   typename Image<T>::iterator dptr = dst.beginw() + pos.i + pos.j * w;
00413   for (int j = 0; j < ih; j ++)
00414     {
00415       safecopy(dptr, sptr, iw);
00416       dptr += w;
00417       sptr += iw;
00418     }
00419 }
00420 
00421 // ######################################################################
00422 template <class T>
00423 void inplaceClearRegion(Image<T>& dst,
00424                         const Rectangle& region1, const T& val)
00425 {
00426 GVX_TRACE(__PRETTY_FUNCTION__);
00427 
00428   const Rectangle region = region1.getOverlap(dst.getBounds());
00429 
00430   if (!region.isValid() || !dst.initialized())
00431     return;
00432 
00433   const int w = dst.getWidth();
00434   const int iw = region.width(), ih = region.height();
00435 
00436   ASSERT(dst.rectangleOk(region));
00437 
00438   typename Image<T>::iterator dptr = dst.beginw() + region.left() + region.top() * w;
00439   for (int j = 0; j < ih; ++j)
00440     {
00441       for (int i = 0; i < iw; ++i)
00442         dptr[i] = val;
00443       dptr += w;
00444     }
00445 }
00446 
00447 // ######################################################################
00448 template <class T>
00449 void inplaceEmbed(Image<T>& dst,
00450                   const Image<T>& img, const Rectangle& r,
00451                   const T background, const bool keep_aspect)
00452 {
00453 GVX_TRACE(__PRETTY_FUNCTION__);
00454 
00455   ASSERT(dst.initialized() && img.initialized());
00456   ASSERT(dst.rectangleOk(r));
00457   int ww = r.width(), hh = r.height();
00458   int iw = img.getWidth(), ih = img.getHeight();
00459   int myw = dst.getWidth();
00460   float sw = float(iw) / float(ww), sh = float(ih) / float(hh);
00461 
00462   // take larger of scale factors if keep aspect ratio:
00463   if (keep_aspect)
00464     {
00465       if (sw > sh) sh = sw;
00466       if (sh > sw) sw = sh;
00467     }
00468 
00469   // determine bounds of actual embedded image, within rectangle:
00470   const int imin = (ww - int(float(iw) / sw)) / 2;
00471   const int imax = ww - imin;
00472   const int jmin = (hh - int(float(ih) / sh)) / 2;
00473   const int jmax = hh - jmin;
00474 
00475   typename Image<T>::iterator aptr = dst.beginw();
00476   typename Image<T>::const_iterator sptr = img.begin();
00477   aptr += r.top() * myw + r.left();
00478 
00479   // top empty lines:
00480   for (int j = 0; j < jmin; j ++)
00481     {
00482       for (int i = 0; i < ww; i ++) *aptr++ = background;
00483       aptr += myw - ww;
00484     }
00485 
00486   // bulk of embedded image:
00487   for (int j = jmin; j < jmax; j ++)
00488     {
00489       for (int i = 0; i < imin; i ++) *aptr++ = background;
00490 
00491       const float y = std::max(0.0F, float(j - jmin) * sh);
00492       const int y0 = int(y);
00493       const float fy = y - float(y0);
00494       const int y1 = std::min(y0 + 1, ih - 1);
00495       const int wy0 = iw * y0, wy1 = iw * y1;
00496 
00497       for (int i = imin; i < imax; i ++)
00498         {
00499           const float x = std::max(0.0F, float(i - imin) * sw);
00500           const int x0 = int(x);
00501           const float fx = x - float(x0);
00502           const int x1 = std::min(x0 + 1, iw - 1);
00503 
00504           typename promote_trait<T, float>::TP
00505             d00( sptr[x0 + wy0] ), d10( sptr[x1 + wy0] ),
00506             d01( sptr[x0 + wy1] ), d11( sptr[x1 + wy1] ),
00507             dx0( d00 + (d10 - d00) * fx ),
00508             dx1( d01 + (d11 - d01) * fx );
00509 
00510           *aptr++ = T( dx0 + (dx1 - dx0) * fy );  // no need to clamp
00511         }
00512       for (int i = imax; i < ww; i ++) *aptr++ = background;
00513       aptr += myw - ww;
00514     }
00515 
00516   // bottom empty lines:
00517   for (int j = jmax; j < hh; j ++)
00518     {
00519       for (int i = 0; i < ww; i ++) *aptr++ = background;
00520       aptr += myw - ww;
00521     }
00522 }
00523 
00524 // ######################################################################
00525 // NOTE: can only have one mask in the image
00526 template <class T>
00527 Rectangle findBoundingRect(const Image<T>& src,
00528                            const T threshold)
00529 {
00530 GVX_TRACE(__PRETTY_FUNCTION__);
00531 
00532   ASSERT(src.initialized());
00533 
00534   int x1 = -1;  int y1 = -1; int x2 = -1; int y2 = -1;
00535   int w = src.getWidth(); int h = src.getHeight();
00536 
00537   // find x offset
00538   for(int i = 0; i < src.getWidth(); i++)
00539     for (int j = 0; j < src.getHeight(); j++)
00540       if (src.getVal(i,j) >= threshold){ x1 = i; i = w; break; }
00541   LDEBUG("x1 = %d", x1);
00542 
00543   // find y
00544   for(int j = 0; j < src.getHeight(); j++)
00545     for (int i = 0; i < src.getWidth(); i++)
00546       if (src.getVal(i,j) >= threshold) { y1 = j; j = h; break; }
00547   LDEBUG("y1 = %d", y1);
00548 
00549   // find width
00550   for(int i = src.getWidth()-1; i >= 0; i--)
00551     for (int j = 0; j < src.getHeight(); j++)
00552       if (src.getVal(i,j) >= threshold) { x2 = i; i =-1; break; }
00553   LDEBUG("x2 = %d", x2);
00554 
00555   // find height
00556   for(int j = src.getHeight()-1; j >= 0; j--)
00557     for (int i = 0; i < src.getWidth(); i++)
00558       if (src.getVal(i,j) >= threshold) { y2 = j; j =-1; break; }
00559   LDEBUG("y2 = %d", y2);
00560 
00561   return Rectangle::tlbrI(y1,x1,y2,x2);
00562 }
00563 
00564 // ######################################################################
00565 Rectangle findBoundingRect(const std::vector<Point2D<int> >& poly, const Dims imgDims)
00566 {
00567   GVX_TRACE(__PRETTY_FUNCTION__);
00568 
00569   Point2D<int> upperLeft = poly[0];
00570   Point2D<int> bottomRight = poly[0];
00571 
00572   for(uint i=0; i<poly.size(); i++)
00573   {
00574     if (poly[i].i < upperLeft.i)
00575       upperLeft.i = poly[i].i;
00576 
00577     if (poly[i].j < upperLeft.j)
00578       upperLeft.j = poly[i].j;
00579 
00580     if (poly[i].i > bottomRight.i)
00581       bottomRight.i = poly[i].i;
00582 
00583     if (poly[i].j > bottomRight.j)
00584       bottomRight.j = poly[i].j;
00585   }
00586   Dims size(bottomRight.i-upperLeft.i,
00587       bottomRight.j - upperLeft.j);
00588 
00589   int width = bottomRight.i-upperLeft.i;
00590   int height = bottomRight.j - upperLeft.j;
00591 
00592   if (imgDims.w() > 0 && imgDims.h() > 0)
00593   {
00594     //Fix any bounding problems
00595     if (upperLeft.i < 0) upperLeft.i = 0;
00596     if (upperLeft.j < 0) upperLeft.j = 0;
00597     if (upperLeft.i + width  > imgDims.w())
00598       width = imgDims.w() - upperLeft.i;
00599     if (upperLeft.j + height  > imgDims.h())
00600       height = imgDims.h() - upperLeft.j;
00601   }
00602 
00603   return Rectangle(upperLeft, Dims(width, height));
00604 }
00605 
00606 
00607 // Include the explicit instantiations (color instantiations are now
00608 // requested by using "T_or_RGB" for the template formal parameter name in
00609 // the declarations in the .H file).
00610 #include "inst/Image/CutPaste.I"
00611 
00612 template Image<double>
00613 crop(const Image<double>&, const Point2D<int>&, const Dims&, bool);
00614 
00615 template Image<PixRGB<unsigned short> >
00616 crop(Image<PixRGB<unsigned short> > const&, Point2D<int> const&, Dims const&, bool);
00617 
00618 template Image<unsigned short>
00619 concatX(Image<unsigned short> const&, Image<unsigned short> const&);
00620 
00621 template void
00622 inplacePaste(Image<double>&, const Image<double>&, const Point2D<int>&);
00623 
00624 template Image<int>
00625 shiftClean(const Image<int>& srcImg, const int dx, const int dy,
00626            const int bgval);
00627 
00628 template Image<geom::vec2f>
00629 shiftClean(const Image<geom::vec2f>& srcImg, const int dx, const int dy,
00630            const geom::vec2f bgval);
00631 
00632 template void
00633 inplacePaste(Image<geom::vec2f>&, const Image<geom::vec2f>&, const Point2D<int>&);
00634 
00635 template void inplaceEmbed(Image<uint16>&, const Image<uint16>&, const Rectangle&,
00636                            const uint16 background, const bool);
00637 
00638 template Image<uint16> crop(const Image<uint16>&, const Rectangle&, const bool);
00639 template Image<double> crop(const Image<double>&, const Rectangle&, const bool);
00640 
00641 // ######################################################################
00642 /* So things look consistent in everyone's emacs... */
00643 /* Local Variables: */
00644 /* indent-tabs-mode: nil */
00645 /* End: */
Generated on Sun May 8 08:05:06 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3