00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "HomgMetric.h"
00009
00010 #include <vcl_iostream.h>
00011 #include <vnl/vnl_math.h>
00012 #include <vnl/vnl_transpose.h>
00013 #include <vnl/vnl_identity_3x3.h>
00014 #include <vnl/vnl_double_2.h>
00015 #include <vgl/vgl_point_2d.h>
00016 #include <vgl/vgl_homg_point_2d.h>
00017 #include <vgl/vgl_homg_line_2d.h>
00018 #include <vgl/vgl_line_segment_2d.h>
00019 #include <vgl/algo/vgl_homg_operators_2d.h>
00020
00021 #include <mvl/HomgPoint2D.h>
00022 #include <mvl/HomgLine2D.h>
00023 #include <mvl/HomgLineSeg2D.h>
00024 #include <mvl/HomgOperator2D.h>
00025 #include <mvl/ImageMetric.h>
00026
00027 #include <mvl/PMatrix.h>
00028 #include <mvl/FMatrix.h>
00029 #include <mvl/HMatrix2D.h>
00030 #include <mvl/TriTensor.h>
00031
00032
00033
00034 HomgMetric::HomgMetric(const ImageMetric* metric)
00035 {
00036 metric_ = metric;
00037 }
00038
00039 HomgMetric::~HomgMetric()
00040 {
00041
00042 }
00043
00044
00045 vcl_ostream& HomgMetric::print(vcl_ostream & s) const
00046 {
00047 if (metric_)
00048 s << "[HomgMetric: " << *metric_ << ']';
00049 else
00050 s << "[HomgMetric: Null ImageMetric]";
00051
00052 return s;
00053 }
00054
00055
00056 vgl_point_2d<double> HomgMetric::homg_to_image(vgl_homg_point_2d<double> const& p) const
00057 {
00058 if (metric_) return metric_->homg_to_image(p);
00059 else return vgl_point_2d<double>(p.x()/p.w(), p.y()/p.w());
00060 }
00061
00062 vnl_double_2 HomgMetric::homg_to_image(const HomgPoint2D& p) const
00063 {
00064 if (metric_) return metric_->homg_to_image(p);
00065 else return vnl_double_2(p.x()/p.w(), p.y()/p.w());
00066 }
00067
00068 void HomgMetric::homg_to_image(const HomgPoint2D& homg, double* ix, double* iy) const
00069 {
00070 if (metric_) {
00071 vnl_double_2 p = metric_->homg_to_image(homg);
00072 *ix = p[0];
00073 *iy = p[1];
00074 } else {
00075 homg.get_nonhomogeneous(*ix, *iy);
00076 }
00077 }
00078
00079 void HomgMetric::homg_to_image(vgl_homg_point_2d<double> const& homg, double& ix, double& iy) const
00080 {
00081 if (metric_) {
00082 vgl_point_2d<double> p = metric_->homg_to_image(homg);
00083 ix = p.x(); iy = p.y();
00084 } else {
00085 ix = homg.x()/homg.w();
00086 iy = homg.y()/homg.w();
00087 }
00088 }
00089
00090 vgl_homg_point_2d<double> HomgMetric::homg_to_imagehomg(vgl_homg_point_2d<double> const& p) const
00091 {
00092 if (metric_) return metric_->homg_to_imagehomg(p);
00093 else return p;
00094 }
00095
00096 HomgPoint2D HomgMetric::homg_to_imagehomg(const HomgPoint2D& p) const
00097 {
00098 if (metric_) return metric_->homg_to_imagehomg(p);
00099 else return p;
00100 }
00101
00102
00103 vgl_homg_point_2d<double> HomgMetric::image_to_homg(vgl_point_2d<double> const& p) const
00104 {
00105 if (metric_) return metric_->image_to_homg(p);
00106 else return vgl_homg_point_2d<double>(p.x(), p.y(), 1.0);
00107 }
00108
00109 HomgPoint2D HomgMetric::image_to_homg(const vnl_double_2& p) const
00110 {
00111 if (metric_) return metric_->image_to_homg(p);
00112 else return HomgPoint2D(p[0], p[1], 1.0);
00113 }
00114
00115 HomgPoint2D HomgMetric::image_to_homg(double x, double y) const
00116 {
00117 if (metric_) return metric_->image_to_homg(x, y);
00118 else return HomgPoint2D(x, y, 1.0);
00119 }
00120
00121 vgl_homg_point_2d<double> HomgMetric::imagehomg_to_homg(vgl_homg_point_2d<double> const& p) const
00122 {
00123 if (metric_) return metric_->imagehomg_to_homg(p);
00124 else return p;
00125 }
00126
00127 HomgPoint2D HomgMetric::imagehomg_to_homg(const HomgPoint2D& p) const
00128 {
00129 if (metric_) return metric_->imagehomg_to_homg(p);
00130 else return p;
00131 }
00132
00133
00134 vgl_homg_line_2d<double> HomgMetric::homg_to_image_line(vgl_homg_line_2d<double> const& l) const
00135 {
00136 if (metric_) return metric_->homg_to_image_line(l);
00137 else return l;
00138 }
00139
00140 HomgLine2D HomgMetric::homg_to_image_line(const HomgLine2D& l) const
00141 {
00142 if (metric_) return metric_->homg_to_image_line(l);
00143 else return l;
00144 }
00145
00146 vgl_homg_line_2d<double> HomgMetric::image_to_homg_line(vgl_homg_line_2d<double> const& l) const
00147 {
00148 if (metric_) return metric_->image_to_homg_line(l);
00149 else return l;
00150 }
00151
00152 HomgLine2D HomgMetric::image_to_homg_line(const HomgLine2D& l) const
00153 {
00154 if (metric_) return metric_->image_to_homg_line(l);
00155 else return l;
00156 }
00157
00158 HomgLineSeg2D HomgMetric::image_to_homg_line(const HomgLineSeg2D& l) const
00159 {
00160 if (metric_) return metric_->image_to_homg_line(l);
00161 else return l;
00162 }
00163
00164 HomgLineSeg2D HomgMetric::homg_line_to_image(const HomgLineSeg2D& l) const
00165 {
00166 if (metric_) return metric_->homg_line_to_image(l);
00167 else return l;
00168 }
00169
00170
00171 double HomgMetric::perp_dist_squared(vgl_homg_point_2d<double> const& p,
00172 vgl_homg_line_2d<double> const& l) const
00173 {
00174 if (metric_) return metric_->perp_dist_squared(p, l);
00175 else return vgl_homg_operators_2d<double>::perp_dist_squared(p, l);
00176 }
00177
00178 double HomgMetric::perp_dist_squared(const HomgPoint2D& p, const HomgLine2D& l) const
00179 {
00180 if (metric_) return metric_->perp_dist_squared(p, l);
00181 else return HomgOperator2D::perp_dist_squared(p, l);
00182 }
00183
00184 vgl_homg_point_2d<double> HomgMetric::perp_projection(vgl_homg_line_2d<double> const& l,
00185 vgl_homg_point_2d<double> const& p) const
00186 {
00187 if (metric_) return metric_->perp_projection(l, p);
00188 else return vgl_homg_operators_2d<double>::perp_projection(l, p);
00189 }
00190
00191 HomgPoint2D HomgMetric::perp_projection(const HomgLine2D& l, const HomgPoint2D& p) const
00192 {
00193 if (metric_) return metric_->perp_projection(l, p);
00194 else return HomgOperator2D::perp_projection(l, p);
00195 }
00196
00197 double HomgMetric::distance_squared(vgl_homg_point_2d<double> const& p1,
00198 vgl_homg_point_2d<double> const& p2) const
00199 {
00200 if (metric_) return metric_->distance_squared(p1, p2);
00201 else return vgl_homg_operators_2d<double>::distance_squared(p1, p2);
00202 }
00203
00204 double HomgMetric::distance_squared(double x1, double y1, double x2, double y2) const
00205 {
00206 HomgPoint2D p1(x1,y1,1.0);
00207 HomgPoint2D p2(x2,y2,1.0);
00208 if (metric_) return metric_->distance_squared(p1, p2);
00209 else return HomgOperator2D::distance_squared(p1, p2);
00210 }
00211
00212 double HomgMetric::distance_squared(const HomgPoint2D& p1, const HomgPoint2D& p2) const
00213 {
00214 if (metric_) return metric_->distance_squared(p1, p2);
00215 else return HomgOperator2D::distance_squared(p1, p2);
00216 }
00217
00218 double HomgMetric::distance_squared(vgl_line_segment_2d<double> const& segment,
00219 vgl_homg_line_2d<double> const& line) const
00220 {
00221 if (metric_) return metric_->distance_squared(segment, line);
00222 else {
00223 double r1 = vgl_homg_operators_2d<double>::perp_dist_squared(vgl_homg_point_2d<double>(segment.point1()), line),
00224 r2 = vgl_homg_operators_2d<double>::perp_dist_squared(vgl_homg_point_2d<double>(segment.point2()), line);
00225 return r1 > r2 ? r1 : r2;
00226 }
00227 }
00228
00229 double HomgMetric::distance_squared(const HomgLineSeg2D& segment, const HomgLine2D& line) const
00230 {
00231 if (metric_) return metric_->distance_squared(segment, line);
00232 else return HomgOperator2D::distance_squared(segment, line);
00233 }
00234
00235 bool HomgMetric::is_within_distance(vgl_homg_point_2d<double> const& p1,
00236 vgl_homg_point_2d<double> const& p2,
00237 double distance) const
00238 {
00239 if (metric_) return metric_->is_within_distance(p1, p2, distance);
00240 else return vgl_homg_operators_2d<double>::is_within_distance(p1, p2, distance);
00241 }
00242
00243 bool HomgMetric::is_within_distance(const HomgPoint2D& p1, const HomgPoint2D& p2, double distance) const
00244 {
00245 if (metric_) return metric_->is_within_distance(p1, p2, distance);
00246 else return HomgOperator2D::is_within_distance(p1, p2, distance);
00247 }
00248
00249
00250
00251
00252 bool HomgMetric::is_linear() const
00253 {
00254 if (metric_) return metric_->is_linear();
00255 else return true;
00256 }
00257
00258
00259 vnl_double_3x3 HomgMetric::get_C() const
00260 {
00261 static vnl_identity_3x3 I;
00262 if (metric_) return metric_->get_C();
00263 else return I;
00264 }
00265
00266
00267 vnl_double_3x3 HomgMetric::get_C_inverse() const
00268 {
00269 static vnl_identity_3x3 I;
00270 if (metric_) return metric_->get_C_inverse();
00271 else return I;
00272 }
00273
00274
00275
00276
00277 bool HomgMetric::can_invert_distance() const
00278 {
00279 if (metric_) return metric_->can_invert_distance();
00280 else return true;
00281 }
00282
00283
00284 double HomgMetric::image_to_homg_distance(double image_distance) const
00285 {
00286 if (metric_) return metric_->image_to_homg_distance(image_distance);
00287 else return image_distance;
00288 }
00289
00290
00291 double HomgMetric::homg_to_image_distance(double image_distance) const
00292 {
00293 if (metric_) return metric_->homg_to_image_distance(image_distance);
00294 else return image_distance;
00295 }
00296
00297
00298 double HomgMetric::image_to_homg_distance_sqr(double image_distance_2) const
00299 {
00300 if (metric_)
00301 return vnl_math_sqr(metric_->image_to_homg_distance(vcl_sqrt(image_distance_2)));
00302 else
00303 return image_distance_2;
00304 }
00305
00306
00307 double HomgMetric::homg_to_image_distance_sqr(double image_distance) const
00308 {
00309 if (metric_)
00310 return vnl_math_sqr(metric_->homg_to_image_distance(vcl_sqrt(image_distance)));
00311 else
00312 return image_distance;
00313 }
00314
00315 static vcl_ostream& warning(char const * fn)
00316 {
00317 return vcl_cerr << "HomgMetric::" << fn << "() WARNING: ";
00318 }
00319
00320
00321
00322
00323 PMatrix HomgMetric::homg_to_image_P(const PMatrix& P, const HomgMetric& c)
00324 {
00325 if (!c.is_linear()) warning("homg_to_image_P") << "ImageMetric for image 1 is nonlinear\n";
00326 return PMatrix(c.get_C() * P.get_matrix());
00327 }
00328
00329 PMatrix HomgMetric::image_to_homg_P(const PMatrix& P, const HomgMetric& c)
00330 {
00331 if (!c.is_linear()) warning("homg_to_image_P") << "ImageMetric for image 1 is nonlinear\n";
00332 return PMatrix(c.get_C_inverse() * P.get_matrix());
00333 }
00334
00335
00336
00337 FMatrix HomgMetric::homg_to_image_F(const FMatrix& F, const HomgMetric& c1, const HomgMetric& c2)
00338 {
00339 if (!c1.is_linear()) warning("homg_to_image_F") << "ImageMetric for image 1 is nonlinear\n";
00340 if (!c2.is_linear()) warning("homg_to_image_F") << "ImageMetric for image 2 is nonlinear\n";
00341
00342 vnl_double_3x3 C1inv = c1.get_C_inverse();
00343 vnl_double_3x3 C2inv = c2.get_C_inverse();
00344 return FMatrix(vnl_transpose(C2inv) * F.get_matrix() * C1inv);
00345 }
00346
00347
00348 FMatrix HomgMetric::image_to_homg_F(const FMatrix& F, const HomgMetric& c1, const HomgMetric& c2)
00349 {
00350 if (!c1.is_linear()) warning("image_to_homg_F") << "ImageMetric for image 1 is nonlinear\n";
00351 if (!c2.is_linear()) warning("image_to_homg_F") << "ImageMetric for image 2 is nonlinear\n";
00352
00353 vnl_double_3x3 C1 = c1.get_C();
00354 vnl_double_3x3 C2 = c2.get_C();
00355 return FMatrix(vnl_transpose(C2) * F.get_matrix() * C1);
00356 }
00357
00358
00359 HMatrix2D HomgMetric::homg_to_image_H(const HMatrix2D& H, const HomgMetric& c1, const HomgMetric& c2)
00360 {
00361 if (!c1.is_linear()) warning("homg_to_image_H") << "ImageMetric for image 1 is nonlinear\n";
00362 if (!c2.is_linear()) warning("homg_to_image_H") << "ImageMetric for image 2 is nonlinear\n";
00363
00364 vnl_double_3x3 C1i = c1.get_C_inverse();
00365 vnl_double_3x3 C2 = c2.get_C();
00366 return HMatrix2D(C2 * H.get_matrix() * C1i);
00367 }
00368
00369
00370 HMatrix2D HomgMetric::image_to_homg_H(const HMatrix2D& H, const HomgMetric& c1, const HomgMetric& c2)
00371 {
00372 if (!c1.is_linear()) warning("image_to_homg_H") << "ImageMetric for image 1 is nonlinear\n";
00373 if (!c2.is_linear()) warning("image_to_homg_H") << "ImageMetric for image 2 is nonlinear\n";
00374
00375 vnl_double_3x3 C1 = c1.get_C();
00376 vnl_double_3x3 C2i = c2.get_C_inverse();
00377 return HMatrix2D(C2i * H.get_matrix() * C1);
00378 }
00379
00380
00381 TriTensor HomgMetric::homg_to_image_T(const TriTensor& T, const HomgMetric& c1, const HomgMetric& c2, const HomgMetric& c3)
00382 {
00383
00384 vnl_double_3x3 C1i = c1.get_C_inverse();
00385 vnl_double_3x3 C2 = c2.get_C();
00386 vnl_double_3x3 C3 = c3.get_C();
00387
00388 return T.decondition(C1i.transpose().as_ref(), C2.transpose().as_ref(), C3.transpose().as_ref());
00389 }
00390
00391
00392 TriTensor HomgMetric::image_to_homg_T(const TriTensor& T, const HomgMetric& c1, const HomgMetric& c2, const HomgMetric& c3)
00393 {
00394
00395 vnl_double_3x3 C1 = c1.get_C();
00396 vnl_double_3x3 C2i = c2.get_C_inverse();
00397 vnl_double_3x3 C3i = c3.get_C_inverse();
00398
00399 return T.decondition(C1.transpose().as_ref(), C2i.transpose().as_ref(), C3i.transpose().as_ref());
00400 }