00001
00002 #ifndef vpgl_lens_warp_mapper_h_
00003 #define vpgl_lens_warp_mapper_h_
00004
00005
00006
00007
00008
00009
00010 #include <vpgl/vpgl_lens_distortion.h>
00011 #include <vil/vil_image_view.h>
00012 #include <vgl/vgl_point_2d.h>
00013 #include <vgl/vgl_vector_2d.h>
00014 #include <vgl/vgl_box_2d.h>
00015 #include <vgl/vgl_homg_point_2d.h>
00016 #include <vcl_cassert.h>
00017
00018
00019
00020
00021 template <class DataT, class BoxT>
00022 vgl_box_2d<BoxT>
00023 vpgl_lens_warp_bounds(const vpgl_lens_distortion<DataT>& lens,
00024 const vgl_box_2d<BoxT>& box,
00025 BoxT step_size = BoxT(1))
00026 {
00027 vgl_box_2d<BoxT> new_box;
00028 for (BoxT x=box.min_x(); x<=box.max_x(); x+=step_size){
00029 vgl_point_2d<DataT> p1(lens.distort(vgl_homg_point_2d<DataT>(x,box.min_y())));
00030 new_box.add(vgl_point_2d<BoxT>( BoxT(p1.x()), BoxT(p1.y()) ));
00031 vgl_point_2d<DataT> p2(lens.distort(vgl_homg_point_2d<DataT>(x,box.max_y())));
00032 new_box.add(vgl_point_2d<BoxT>( BoxT(p2.x()), BoxT(p2.y()) ));
00033 }
00034 for (BoxT y=box.min_y(); y<=box.max_y(); y+=step_size){
00035 vgl_point_2d<DataT> p1(lens.distort(vgl_homg_point_2d<DataT>(box.min_x(),y)));
00036 new_box.add(vgl_point_2d<BoxT>( BoxT(p1.x()), BoxT(p1.y()) ));
00037 vgl_point_2d<DataT> p2(lens.distort(vgl_homg_point_2d<DataT>(box.max_x(),y)));
00038 new_box.add(vgl_point_2d<BoxT>( BoxT(p2.x()), BoxT(p2.y()) ));;
00039 }
00040 return new_box;
00041 }
00042
00043
00044
00045
00046 template <class DataT, class BoxT>
00047 vgl_box_2d<BoxT>
00048 vpgl_lens_unwarp_bounds(const vpgl_lens_distortion<DataT>& lens,
00049 const vgl_box_2d<BoxT>& box,
00050 BoxT step_size = BoxT(1))
00051 {
00052 vgl_box_2d<BoxT> new_box;
00053 for (BoxT x=box.min_x(); x<=box.max_x(); x+=step_size){
00054 vgl_point_2d<DataT> p1(lens.undistort(vgl_homg_point_2d<DataT>(x,box.min_y())));
00055 new_box.add(vgl_point_2d<BoxT>( BoxT(p1.x()), BoxT(p1.y()) ));
00056 vgl_point_2d<DataT> p2(lens.undistort(vgl_homg_point_2d<DataT>(x,box.max_y())));
00057 new_box.add(vgl_point_2d<BoxT>( BoxT(p2.x()), BoxT(p2.y()) ));
00058 }
00059 for (BoxT y=box.min_y(); y<=box.max_y(); y+=step_size){
00060 vgl_point_2d<DataT> p1(lens.undistort(vgl_homg_point_2d<DataT>(box.min_x(),y)));
00061 new_box.add(vgl_point_2d<BoxT>( BoxT(p1.x()), BoxT(p1.y()) ));
00062 vgl_point_2d<DataT> p2(lens.undistort(vgl_homg_point_2d<DataT>(box.max_x(),y)));
00063 new_box.add(vgl_point_2d<BoxT>( BoxT(p2.x()), BoxT(p2.y()) ));;
00064 }
00065 return new_box;
00066 }
00067
00068
00069
00070
00071
00072
00073 template <class sType, class dType, class T, class InterpFunctor>
00074 vil_image_view<dType>
00075 vpgl_lens_warp_resize(const vil_image_view<sType>& in,
00076 dType ,
00077 vpgl_lens_distortion<T>& ld,
00078 InterpFunctor interp)
00079 {
00080 vgl_box_2d<int> bounds = vpgl_lens_warp_bounds(ld, vgl_box_2d<int>(0,in.ni(),0,in.nj()));
00081 vgl_vector_2d<T> offset(T(-bounds.min_x()), T(-bounds.min_y()));
00082 ld.set_translation( offset, true );
00083 vil_image_view<dType> out(bounds.width(), bounds.height(), in.nplanes());
00084 vpgl_lens_warp(in, out, ld, interp);
00085 return out;
00086 }
00087
00088
00089
00090
00091
00092 template <class sType, class dType, class T, class InterpFunctor>
00093 void vpgl_lens_warp(const vil_image_view<sType>& in,
00094 vil_image_view<dType>& out,
00095 const vpgl_lens_distortion<T>& ld,
00096 InterpFunctor interp)
00097 {
00098 unsigned const out_w = out.ni();
00099 unsigned const out_h = out.nj();
00100
00101 assert(out.nplanes() == in.nplanes());
00102
00103 vgl_homg_point_2d<T> init(T(0),T(0));
00104 for (unsigned oy = 0; oy < out_h; ++oy)
00105 {
00106 vgl_homg_point_2d<T> unwarp_pt = init;
00107 for (unsigned ox = 0; ox < out_w; ++ox)
00108 {
00109
00110 double ix, iy;
00111 unwarp_pt = ld.undistort(vgl_homg_point_2d<T>(ox,oy),&unwarp_pt);
00112 if (oy == 0) init = unwarp_pt;
00113 ix = unwarp_pt.x()/unwarp_pt.w();
00114 iy = unwarp_pt.y()/unwarp_pt.w();
00115 for (unsigned p = 0; p < out.nplanes(); ++p)
00116 {
00117 out(ox, oy, p) = dType(interp(in, ix, iy, p));
00118 }
00119 }
00120 }
00121 }
00122
00123
00124
00125
00126
00127
00128 template <class sType, class dType, class T, class InterpFunctor>
00129 vil_image_view<dType>
00130 vpgl_lens_unwarp_resize(const vil_image_view<sType>& in,
00131 dType ,
00132 vpgl_lens_distortion<T>& ld,
00133 InterpFunctor interp)
00134 {
00135 vgl_box_2d<int> bounds = vpgl_lens_unwarp_bounds(ld, vgl_box_2d<int>(0,in.ni(),0,in.nj()));
00136 vgl_vector_2d<T> offset(T(-bounds.min_x()), T(-bounds.min_y()));
00137 ld.set_translation( offset, false );
00138 vil_image_view<dType> out(bounds.width(), bounds.height(), in.nplanes());
00139 vpgl_lens_unwarp(in, out, ld, interp);
00140 return out;
00141 }
00142
00143
00144
00145 template <class sType, class dType, class T, class InterpFunctor>
00146 void vpgl_lens_unwarp(const vil_image_view<sType>& in,
00147 vil_image_view<dType>& out,
00148 const vpgl_lens_distortion<T>& ld,
00149 InterpFunctor interp)
00150 {
00151 unsigned const out_w = out.ni();
00152 unsigned const out_h = out.nj();
00153
00154 assert(out.nplanes() == in.nplanes());
00155
00156 for (unsigned oy = 0; oy < out_h; ++oy)
00157 {
00158 for (unsigned ox = 0; ox < out_w; ++ox)
00159 {
00160 vgl_point_2d<T> pt = ld.distort(vgl_homg_point_2d<T>(ox,oy));
00161 for (unsigned p = 0; p < out.nplanes(); ++p)
00162 {
00163 out(ox, oy, p) = dType(interp(in, pt.x(), pt.y(), p));
00164 }
00165 }
00166 }
00167 }
00168
00169 #endif // vpgl_lens_warp_mapper_h_