contrib/mul/vimt/vimt_crop.h
Go to the documentation of this file.
00001 // This is mul/vimt/vimt_crop.h
00002 #ifndef vimt_crop_h_
00003 #define vimt_crop_h_
00004 //:
00005 //  \file
00006 //  \brief Create windows into vimt_images.
00007 //  \author Tim Cootes, Ian Scott
00008 
00009 #include <vimt/vimt_image_2d_of.h>
00010 #include <vil/vil_crop.h>
00011 #include <vcl_cmath.h>
00012 #include <vcl_cassert.h>
00013 
00014 //: Create windowed view of given image
00015 //  The parameters should be in image co-ords.
00016 //  The world2im transform is set to match
00017 //  so this appears identical to im when addressed
00018 //  in world co-ords. O(1).
00019 template <class T>
00020 vimt_image_2d_of<T> vimt_crop(const vimt_image_2d_of<T>& im,
00021                               unsigned x0, unsigned nx,
00022                               unsigned y0, unsigned ny)
00023 {
00024   vimt_transform_2d trans;
00025   trans.set_translation(-double(x0),-double(y0));
00026   return vimt_image_2d_of<T>(vil_crop(im.image(),x0,nx,y0,ny),trans*im.world2im());
00027 }
00028 
00029 
00030 //: Create windowed view of given image by specifying a bounding box in world co-ords.
00031 //  The world2im transform is set so that this appears identical to im when addressed in world co-ords.
00032 //  \param im The input image.
00033 //  \param bbox Bounding box of desired crop region in world coords.
00034 //  \return A cropped view of the original image.
00035 //  \note The crop region may be expanded slightly as required to fit the voxel grid.
00036 //  \note If the crop region extends outside the image, it is truncated to fit the image.
00037 template <class T>
00038 vimt_image_2d_of<T> vimt_crop(const vimt_image_2d_of<T>& im,
00039                               const vgl_box_2d<double>& bbox)
00040 {
00041   // Compute the bounding box in image coords.
00042   vgl_point_2d<double> pi = im.world2im()(bbox.min_point());
00043   vgl_point_2d<double> qi = im.world2im()(bbox.max_point());
00044   vgl_box_2d<double> bbox_img;
00045   bbox_img.add(pi);
00046   bbox_img.add(qi);
00047 
00048   // Get the lower and upper corner points, rounding down and up respectively.
00049   pi = bbox_img.min_point();
00050   qi = bbox_img.max_point();
00051   pi.set(vcl_floor(pi.x()), vcl_floor(pi.y()));
00052   qi.set(vcl_ceil(qi.x()),  vcl_ceil(qi.y()));
00053 
00054   // Restrict to image bounds - perhaps we could use vgl_box intersection instead?
00055   unsigned ni = im.image().ni();
00056   unsigned nj = im.image().nj();
00057   unsigned pix = pi.x()<0 ? 0 : static_cast<unsigned>(pi.x());
00058   unsigned piy = pi.y()<0 ? 0 : static_cast<unsigned>(pi.y());
00059   unsigned qix = qi.x()+1>ni ? ni-1 : static_cast<unsigned>(qi.x());
00060   unsigned qiy = qi.y()+1>nj ? nj-1 : static_cast<unsigned>(qi.y());
00061 
00062   // Crop image
00063   assert (qix>=pix && qiy>=piy);
00064   unsigned nx = qix - pix + 1;
00065   unsigned ny = qiy - piy + 1;
00066   return vimt_crop(im, pix, nx, piy, ny);
00067 }
00068 
00069 
00070 #endif // vimt_crop_h_