00001
00002 #include "vpgl_vsol_lens_warp.h"
00003
00004
00005
00006 #include <vgl/vgl_point_2d.h>
00007 #include <vgl/vgl_homg_point_2d.h>
00008 #include <vgl/vgl_distance.h>
00009 #include <vsol/vsol_point_2d.h>
00010 #include <vsol/vsol_line_2d.h>
00011 #include <vsol/vsol_polyline_2d.h>
00012 #include <vsol/vsol_digital_curve_2d.h>
00013 #include <vsol/vsol_polygon_2d.h>
00014 #include <vcl_list.h>
00015 #include <vcl_iostream.h>
00016
00017
00018
00019 vsol_spatial_object_2d_sptr
00020 vpgl_vsol_lens_warp(const vsol_spatial_object_2d_sptr& obj,
00021 const vpgl_lens_distortion<double>& lens,
00022 bool invert,
00023 double midpt_thresh)
00024 {
00025 if (vsol_point_2d_sptr pt = obj->cast_to_point())
00026 {
00027 return vpgl_vsol_lens_warp(pt, lens, invert, midpt_thresh).ptr();
00028 }
00029 else if (vsol_curve_2d* curve = obj->cast_to_curve())
00030 {
00031 if (vsol_line_2d_sptr line = curve->cast_to_line())
00032 {
00033 return vpgl_vsol_lens_warp(line, lens, invert, midpt_thresh).ptr();
00034 }
00035 else if (vsol_polyline_2d_sptr pline = curve->cast_to_polyline())
00036 {
00037 return vpgl_vsol_lens_warp(pline, lens, invert, midpt_thresh).ptr();
00038 }
00039 else if (vsol_digital_curve_2d_sptr dc = curve->cast_to_digital_curve())
00040 {
00041 return vpgl_vsol_lens_warp(dc, lens, invert, midpt_thresh).ptr();
00042 }
00043 }
00044 else if (vsol_region_2d* region = obj->cast_to_region())
00045 {
00046 if (vsol_polygon_2d_sptr pg = region->cast_to_polygon())
00047 {
00048 return vpgl_vsol_lens_warp(pg, lens, invert, midpt_thresh).ptr();
00049 }
00050 }
00051 return NULL;
00052 }
00053
00054
00055 vsol_point_2d_sptr
00056 vpgl_vsol_lens_warp(const vsol_point_2d_sptr& pt,
00057 const vpgl_lens_distortion<double>& lens,
00058 bool invert,
00059 double midpt_thresh)
00060 {
00061 if ( midpt_thresh <= 0 )
00062 return 0;
00063 if (invert)
00064 return new vsol_point_2d( lens.undistort( vgl_homg_point_2d<double>(pt->get_p()) ) );
00065 else
00066 return new vsol_point_2d( lens.distort( vgl_homg_point_2d<double>(pt->get_p()) ) );
00067 }
00068
00069
00070
00071 static bool
00072 vpgl_vsol_warp_divide(const vsol_line_2d_sptr& ln,
00073 const vsol_line_2d_sptr& wln,
00074 const vpgl_lens_distortion<double>& lens,
00075 bool invert,
00076 double midpt_thresh,
00077 vcl_list<vsol_point_2d_sptr>& pts)
00078 {
00079 if ( midpt_thresh <= 0 )
00080 return false;
00081 vsol_point_2d_sptr mp = ln->middle();
00082 vsol_point_2d_sptr dmp = vpgl_vsol_lens_warp(mp,lens,invert,midpt_thresh);
00083 vsol_point_2d_sptr wmp = wln->middle();
00084 if (vgl_distance(wmp->get_p(), dmp->get_p()) < midpt_thresh)
00085 return false;
00086
00087 vcl_list<vsol_point_2d_sptr> pts1, pts2;
00088 vpgl_vsol_warp_divide(new vsol_line_2d(ln->p0(),mp),
00089 new vsol_line_2d(wln->p0(),dmp),
00090 lens, invert, midpt_thresh, pts1);
00091 vpgl_vsol_warp_divide(new vsol_line_2d(mp,ln->p1()),
00092 new vsol_line_2d(dmp,wln->p1()),
00093 lens, invert, midpt_thresh, pts2);
00094
00095 pts.splice(pts.end(),pts1);
00096 pts.push_back(dmp);
00097 pts.splice(pts.end(),pts2);
00098 return true;
00099 }
00100
00101
00102
00103 vsol_curve_2d_sptr
00104 vpgl_vsol_lens_warp(const vsol_line_2d_sptr& ln,
00105 const vpgl_lens_distortion<double>& lens,
00106 bool invert,
00107 double midpt_thresh)
00108 {
00109 vsol_point_2d_sptr p0 = vpgl_vsol_lens_warp(ln->p0(), lens, invert, midpt_thresh);
00110 vsol_point_2d_sptr p1 = vpgl_vsol_lens_warp(ln->p1(), lens, invert, midpt_thresh);
00111 if (!p0 || !p1)
00112 return NULL;
00113 vsol_line_2d_sptr line = new vsol_line_2d(p0,p1);
00114 vcl_list<vsol_point_2d_sptr> pts;
00115 vpgl_vsol_warp_divide(ln,line,lens,invert,midpt_thresh,pts);
00116 if (pts.empty())
00117 return line.ptr();
00118 pts.push_front(p0);
00119 pts.push_back(p1);
00120 vcl_vector<vsol_point_2d_sptr> v_pts;
00121 for (vcl_list<vsol_point_2d_sptr>::iterator i = pts.begin();
00122 i != pts.end(); ++i )
00123 v_pts.push_back(*i);
00124 return new vsol_polyline_2d(v_pts);
00125 }
00126
00127
00128
00129 vsol_polyline_2d_sptr
00130 vpgl_vsol_lens_warp(const vsol_polyline_2d_sptr& pln,
00131 const vpgl_lens_distortion<double>& lens,
00132 bool invert,
00133 double midpt_thresh)
00134 {
00135 vcl_list<vsol_point_2d_sptr> pts;
00136 vsol_point_2d_sptr last_p = pln->p0();
00137 vsol_point_2d_sptr last_dp = vpgl_vsol_lens_warp(last_p, lens, invert, midpt_thresh);
00138 pts.push_back(last_dp);
00139 for (unsigned int i=1; i<pln->size(); ++i)
00140 {
00141 vsol_point_2d_sptr p = pln->vertex(i);
00142 vsol_point_2d_sptr dp = vpgl_vsol_lens_warp(p, lens, invert, midpt_thresh);
00143 if (!dp)
00144 return 0;
00145 vsol_line_2d_sptr ln = new vsol_line_2d(last_p,p);
00146 vsol_line_2d_sptr wln = new vsol_line_2d(last_dp,dp);
00147 vcl_list<vsol_point_2d_sptr> new_pts;
00148 vpgl_vsol_warp_divide(ln,wln,lens,invert,midpt_thresh,new_pts);
00149 pts.splice(pts.end(),new_pts);
00150 pts.push_back(dp);
00151 last_p = p;
00152 last_dp = dp;
00153 }
00154 vcl_vector<vsol_point_2d_sptr> v_pts;
00155 for (vcl_list<vsol_point_2d_sptr>::iterator i = pts.begin();
00156 i != pts.end(); ++i )
00157 v_pts.push_back(*i);
00158 return new vsol_polyline_2d(v_pts);
00159 }
00160
00161
00162
00163 vsol_digital_curve_2d_sptr
00164 vpgl_vsol_lens_warp(const vsol_digital_curve_2d_sptr& dc,
00165 const vpgl_lens_distortion<double>& lens,
00166 bool invert,
00167 double midpt_thresh)
00168 {
00169 vcl_list<vsol_point_2d_sptr> pts;
00170 vsol_point_2d_sptr last_p = dc->p0();
00171 vsol_point_2d_sptr last_dp = vpgl_vsol_lens_warp(last_p, lens, invert, midpt_thresh);
00172 pts.push_back(last_dp);
00173 for (unsigned int i=1; i<dc->size(); ++i){
00174 vsol_point_2d_sptr p = dc->point(i);
00175 vsol_point_2d_sptr dp = vpgl_vsol_lens_warp(p, lens, invert, midpt_thresh);
00176 if (!dp)
00177 return 0;
00178 vsol_line_2d_sptr ln = new vsol_line_2d(last_p,p);
00179 vsol_line_2d_sptr wln = new vsol_line_2d(last_dp,dp);
00180 vcl_list<vsol_point_2d_sptr> new_pts;
00181 vpgl_vsol_warp_divide(ln,wln,lens,invert,midpt_thresh,new_pts);
00182 pts.splice(pts.end(),new_pts);
00183 pts.push_back(dp);
00184 last_p = p;
00185 last_dp = dp;
00186 }
00187 vcl_vector<vsol_point_2d_sptr> v_pts;
00188 for (vcl_list<vsol_point_2d_sptr>::iterator i = pts.begin();
00189 i != pts.end(); ++i )
00190 v_pts.push_back(*i);
00191 return new vsol_digital_curve_2d(v_pts);
00192 }
00193
00194
00195
00196 vsol_polygon_2d_sptr
00197 vpgl_vsol_lens_warp(const vsol_polygon_2d_sptr& pg,
00198 const vpgl_lens_distortion<double>& lens,
00199 bool invert,
00200 double midpt_thresh)
00201 {
00202 vcl_list<vsol_point_2d_sptr> pts;
00203 vsol_point_2d_sptr last_p = pg->vertex(pg->size()-1);
00204 vsol_point_2d_sptr last_dp = vpgl_vsol_lens_warp(last_p, lens, invert, midpt_thresh);
00205 for (unsigned int i=0; i<pg->size(); ++i){
00206 vsol_point_2d_sptr p = pg->vertex(i);
00207 vsol_point_2d_sptr dp = vpgl_vsol_lens_warp(p, lens, invert, midpt_thresh);
00208 if (!dp)
00209 return 0;
00210 vsol_line_2d_sptr ln = new vsol_line_2d(last_p,p);
00211 vsol_line_2d_sptr wln = new vsol_line_2d(last_dp,dp);
00212 vcl_list<vsol_point_2d_sptr> new_pts;
00213 vpgl_vsol_warp_divide(ln,wln,lens,invert,midpt_thresh,new_pts);
00214 pts.splice(pts.end(),new_pts);
00215 pts.push_back(dp);
00216 last_p = p;
00217 last_dp = dp;
00218 }
00219 vcl_vector<vsol_point_2d_sptr> v_pts;
00220 for (vcl_list<vsol_point_2d_sptr>::iterator i = pts.begin();
00221 i != pts.end(); ++i )
00222 v_pts.push_back(*i);
00223 return new vsol_polygon_2d(v_pts);
00224 }
00225
00226
00227
00228
00229
00230 bool
00231 vpgl_vsol_lens_warp(vsol_spatial_object_2d_sptr& obj,
00232 const vpgl_lens_distortion<double>& lens,
00233 bool invert)
00234 {
00235 if (invert)
00236 vcl_cerr << "Warning: invert not yet implemented in vpgl_vsol_lens_warp\n";
00237
00238 if (vsol_point_2d_sptr pt = obj->cast_to_point())
00239 {
00240 return vpgl_vsol_lens_warp(pt, lens);
00241 }
00242 else if (vsol_curve_2d* curve = obj->cast_to_curve())
00243 {
00244 if (vsol_line_2d_sptr line = curve->cast_to_line())
00245 {
00246 return vpgl_vsol_lens_warp(line, lens);
00247 }
00248 else if (vsol_polyline_2d_sptr pline = curve->cast_to_polyline())
00249 {
00250 return vpgl_vsol_lens_warp(pline, lens);
00251 }
00252 else if (vsol_digital_curve_2d_sptr dc = curve->cast_to_digital_curve())
00253 {
00254 return vpgl_vsol_lens_warp(dc, lens);
00255 }
00256 }
00257 else if (vsol_region_2d* region = obj->cast_to_region())
00258 {
00259 if (vsol_polygon_2d_sptr pg = region->cast_to_polygon())
00260 {
00261 return vpgl_vsol_lens_warp(pg, lens);
00262 }
00263 }
00264 return false;
00265 }
00266
00267
00268
00269
00270 bool
00271 vpgl_vsol_lens_warp(vsol_point_2d_sptr& pt,
00272 const vpgl_lens_distortion<double>& lens,
00273 bool invert)
00274 {
00275 vgl_point_2d<double> new_pt;
00276 if (invert)
00277 new_pt = lens.undistort( vgl_homg_point_2d<double>(pt->get_p()) );
00278 else
00279 new_pt = lens.distort( vgl_homg_point_2d<double>(pt->get_p()) );
00280 pt->set_x(new_pt.x());
00281 pt->set_y(new_pt.y());
00282 return true;
00283 }
00284
00285
00286
00287
00288
00289 bool
00290 vpgl_vsol_lens_warp(vsol_line_2d_sptr& ln,
00291 const vpgl_lens_distortion<double>& lens,
00292 bool invert)
00293 {
00294 if (invert)
00295 vcl_cerr << "Warning: line invert not yet implemented in vpgl_vsol_lens_warp\n";
00296
00297 vsol_point_2d_sptr p0=ln->p0(), p1=ln->p1();
00298 return vpgl_vsol_lens_warp(p0, lens) &&
00299 vpgl_vsol_lens_warp(p1, lens);
00300 }
00301
00302
00303
00304
00305 bool
00306 vpgl_vsol_lens_warp(vsol_polyline_2d_sptr& pln,
00307 const vpgl_lens_distortion<double>& lens,
00308 bool invert)
00309 {
00310 if (invert)
00311 vcl_cerr << "Warning: polyline invert not yet implemented in vpgl_vsol_lens_warp\n";
00312
00313 for (unsigned int i=0; i<pln->size(); ++i){
00314 vsol_point_2d_sptr p=pln->vertex(i);
00315 if (!vpgl_vsol_lens_warp(p, lens))
00316 return false;
00317 }
00318 return true;
00319 }
00320
00321
00322
00323
00324
00325 bool
00326 vpgl_vsol_lens_warp(vsol_digital_curve_2d_sptr& dc,
00327 const vpgl_lens_distortion<double>& lens,
00328 bool invert)
00329 {
00330 if (invert)
00331 vcl_cerr << "Warning: curve invert not yet implemented in vpgl_vsol_lens_warp\n";
00332
00333 for (unsigned int i=0; i<dc->size(); ++i) {
00334 vsol_point_2d_sptr p=dc->point(i);
00335 if (!vpgl_vsol_lens_warp(p, lens))
00336 return false;
00337 }
00338 return true;
00339 }
00340
00341
00342
00343
00344
00345 bool
00346 vpgl_vsol_lens_warp(vsol_polygon_2d_sptr& pg,
00347 const vpgl_lens_distortion<double>& lens,
00348 bool invert)
00349 {
00350 if (invert)
00351 vcl_cerr << "Warning: polygon invert not yet implemented in vpgl_vsol_lens_warp\n";
00352
00353 for (unsigned int i=0; i<pg->size(); ++i){
00354 vsol_point_2d_sptr p=pg->vertex(i);
00355 if (!vpgl_vsol_lens_warp(p, lens))
00356 return false;
00357 }
00358 return true;
00359 }