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