contrib/mul/vimt3d/vimt3d_image_3d.cxx
Go to the documentation of this file.
00001 //:
00002 //  \file
00003 //  \brief A base class for arbitrary 3d images+transform
00004 //  \author Tim Cootes
00005 
00006 #include "vimt3d_image_3d.h"
00007 #include <vgl/vgl_point_3d.h>
00008 #include <vgl/vgl_vector_3d.h>
00009 
00010 //: Return vector indicating size of image in pixels
00011 //  3D image is v[0] x v[1] x v[2]
00012 vcl_vector<unsigned> vimt3d_image_3d::image_size() const
00013 {
00014   vcl_vector<unsigned> d(3);
00015   d[0]=image_base().ni();
00016   d[1]=image_base().nj();
00017   d[2]=image_base().nk();
00018   return d;
00019 }
00020 
00021 
00022 //: Return 3 element vector indicating the size of a pixel
00023 vcl_vector<double> vimt3d_image_3d::pixel_size() const
00024 {
00025   vcl_vector<double> d(3);
00026   vgl_vector_3d<double> v =world2im_.inverse().
00027     delta(vgl_point_3d<double>(0,0,0), vgl_vector_3d<double>(1.0,1.0,1.0));
00028 
00029   d[0] = v.x();
00030   d[1] = v.y();
00031   d[2] = v.z();
00032   return d;
00033 }
00034 
00035 
00036 //: Return vectors defining bounding box containing image in world co-ords
00037 void vimt3d_image_3d::world_bounds(vcl_vector<double>& b_lo,
00038                                    vcl_vector<double>& b_hi) const
00039 {
00040   b_lo.resize(3); b_hi.resize(3);
00041   vgl_point_3d<double> p = world2im_.inverse()(0,0,0);
00042   b_lo[0]=p.x(); b_hi[0]=p.x();
00043   b_lo[1]=p.y(); b_hi[1]=p.y();
00044   b_lo[2]=p.z(); b_hi[2]=p.z();
00045 
00046   // Compute each corner
00047   for (int i=0;i<2;++i)
00048     for (int j=0;j<2;++j)
00049       for (int k=0;k<2;++k)
00050       {
00051         p = world2im_.inverse()(i*(image_base().ni()-1),
00052                                 j*(image_base().nj()-1),
00053                                 k*(image_base().nk()-1));
00054         if (p.x()<b_lo[0]) b_lo[0]=p.x();
00055         else if (p.x()>b_hi[0]) b_hi[0]=p.x();
00056         if (p.y()<b_lo[1]) b_lo[1]=p.y();
00057         else if (p.y()>b_hi[1]) b_hi[1]=p.y();
00058         if (p.z()<b_lo[2]) b_lo[2]=p.z();
00059         else if (p.z()>b_hi[2]) b_hi[2]=p.z();
00060       }
00061 }
00062 
00063 //Related Functions
00064 //: Return bounding box containing image in world co-ords as a box
00065 vgl_box_3d<double> world_bounding_box(const vimt3d_image_3d& img)
00066 {
00067   vcl_vector<double> b_lo(3,0.0);
00068   vcl_vector<double> b_hi(3,0.0);
00069   img.world_bounds(b_lo,b_hi);
00070   //Use C-style vector interface for corner points, passing address of data as the C-style vector
00071   return vgl_box_3d<double>(&(b_lo[0]),&(b_hi[0]));
00072 }
00073 
00074 // Translate the image so that its centre is at the origin of the world coordinate system.
00075 void vimt3d_centre_image_at_origin(vimt3d_image_3d& image)
00076 {
00077   vgl_box_3d<double> bbox = world_bounding_box(image);
00078   vgl_point_3d<double> c = bbox.centroid();
00079   vimt3d_transform_3d& w2i = image.world2im();
00080   w2i.set_origin(w2i(c));
00081 }
00082 
00083 // Calculate the voxel dimensions from the image transform
00084 // NEEDS A TEST PROGRAM
00085 vgl_vector_3d<double> vimt3d_voxel_size_from_transform(const vimt3d_image_3d& image)
00086 {
00087   const vimt3d_transform_3d& i2w = image.world2im().inverse();
00088   vgl_point_3d<double> p(0,0,0);
00089   vgl_vector_3d<double> i(1,0,0);
00090   vgl_vector_3d<double> j(0,1,0);
00091   vgl_vector_3d<double> k(0,0,1);
00092   double dx = i2w.delta(p, i).length();
00093   double dy = i2w.delta(p, j).length();
00094   double dz = i2w.delta(p, k).length();
00095   return vgl_vector_3d<double>(dx, dy, dz);
00096 }