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