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