00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "ImageMetric.h"
00009
00010 #include <vcl_iostream.h>
00011 #include <vcl_cassert.h>
00012 #include <vnl/vnl_double_2.h>
00013 #include <vnl/vnl_double_3x3.h>
00014 #include <vnl/vnl_math.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/algo/vgl_homg_operators_2d.h>
00019 #include <vgl/vgl_line_segment_2d.h>
00020
00021 #include <mvl/HomgPoint2D.h>
00022 #include <mvl/HomgLineSeg2D.h>
00023 #include <mvl/HomgOperator2D.h>
00024
00025 static vcl_ostream& warning(char const * fn)
00026 {
00027 return vcl_cerr << fn << " WARNING: ";
00028 }
00029
00030
00031
00032
00033
00034 vgl_homg_point_2d<double> ImageMetric::image_to_homg(vgl_point_2d<double> const& p) const
00035 {
00036 assert(!"ImageMetric::image_to_homg should be implemented for efficiency");
00037 return vgl_homg_point_2d<double>(p.x(), p.y(), 1.0);
00038 }
00039
00040
00041
00042 HomgPoint2D ImageMetric::image_to_homg(const vnl_double_2& p) const
00043 {
00044 assert(!"ImageMetric::image_to_homg should be implemented for efficiency");
00045 return HomgPoint2D(p[0], p[1], 1.0);
00046 }
00047
00048
00049 HomgPoint2D ImageMetric::image_to_homg(double x, double y) const
00050 {
00051 assert(!"ImageMetric::image_to_homg should be implemented for efficiency");
00052 return HomgPoint2D(x, y, 1.0);
00053 }
00054
00055
00056 vgl_point_2d<double> ImageMetric::homg_to_image(vgl_homg_point_2d<double> const& p) const
00057 {
00058 assert(!"ImageMetric::homg_to_image should be implemented for efficiency");
00059 return p;
00060 }
00061
00062 vnl_double_2 ImageMetric::homg_to_image(const HomgPoint2D& p) const
00063 {
00064 assert(!"ImageMetric::homg_to_image should be implemented for efficiency");
00065 double x,y;
00066 p.get_nonhomogeneous(x, y);
00067 return vnl_double_2(x, y);
00068 }
00069
00070
00071 vgl_homg_point_2d<double> ImageMetric::imagehomg_to_homg(vgl_homg_point_2d<double> const& x) const
00072 {
00073 return x;
00074 }
00075
00076 HomgPoint2D ImageMetric::imagehomg_to_homg(const HomgPoint2D& x) const
00077 {
00078 return x;
00079 }
00080
00081
00082 vgl_homg_point_2d<double> ImageMetric::homg_to_imagehomg(vgl_homg_point_2d<double> const& x) const
00083 {
00084 return x;
00085 }
00086
00087 HomgPoint2D ImageMetric::homg_to_imagehomg(const HomgPoint2D& x) const
00088 {
00089 return x;
00090 }
00091
00092
00093 vgl_homg_line_2d<double> ImageMetric::homg_to_image_line(vgl_homg_line_2d<double> const& l) const
00094 {
00095 if (is_linear())
00096 return get_C_inverse().transpose() * l;
00097
00098
00099 vgl_homg_point_2d<double> p1, p2;
00100 l.get_two_points(p1,p2);
00101 vgl_homg_point_2d<double> i1 = homg_to_imagehomg(p1);
00102 vgl_homg_point_2d<double> i2 = homg_to_imagehomg(p2);
00103 return vgl_homg_line_2d<double>(i1,i2);
00104 }
00105
00106 HomgLine2D ImageMetric::homg_to_image_line(const HomgLine2D& l) const
00107 {
00108 if (is_linear())
00109 return HomgLine2D(get_C_inverse().transpose() * l.get_vector().as_ref());
00110
00111
00112 HomgPoint2D p1, p2;
00113 l.get_2_points_on_line(&p1, &p2);
00114 HomgPoint2D i1 = homg_to_imagehomg(p1);
00115 HomgPoint2D i2 = homg_to_imagehomg(p2);
00116 return HomgOperator2D::join(i1, i2);
00117 }
00118
00119 vgl_homg_line_2d<double> ImageMetric::image_to_homg_line(const vgl_homg_line_2d<double>& l) const
00120 {
00121 if (is_linear())
00122 return get_C().transpose() * l;
00123
00124
00125 vgl_homg_point_2d<double> p1, p2;
00126 l.get_two_points(p1,p2);
00127 vgl_homg_point_2d<double> i1 = imagehomg_to_homg(p1);
00128 vgl_homg_point_2d<double> i2 = imagehomg_to_homg(p2);
00129 return vgl_homg_line_2d<double>(i1,i2);
00130 }
00131
00132 HomgLine2D ImageMetric::image_to_homg_line(const HomgLine2D& l) const
00133 {
00134 if (is_linear())
00135 return HomgLine2D(get_C().transpose() * l.get_vector().as_ref());
00136
00137
00138 HomgPoint2D p1, p2;
00139 l.get_2_points_on_line(&p1, &p2);
00140 HomgPoint2D i1 = imagehomg_to_homg(p1);
00141 HomgPoint2D i2 = imagehomg_to_homg(p2);
00142 return HomgOperator2D::join(i1, i2);
00143 }
00144
00145
00146
00147 vgl_line_segment_2d<double> ImageMetric::homg_line_to_image(vgl_line_segment_2d<double> const& l) const
00148 {
00149
00150 vgl_homg_point_2d<double> i1 = homg_to_imagehomg(vgl_homg_point_2d<double>(l.point1()));
00151 vgl_homg_point_2d<double> i2 = homg_to_imagehomg(vgl_homg_point_2d<double>(l.point2()));
00152 return vgl_line_segment_2d<double>(i1,i2);
00153 }
00154
00155 HomgLineSeg2D ImageMetric::homg_line_to_image(const HomgLineSeg2D& l) const
00156 {
00157
00158 HomgPoint2D i1 = homg_to_imagehomg(l.get_point1());
00159 HomgPoint2D i2 = homg_to_imagehomg(l.get_point2());
00160 return HomgLineSeg2D(i1, i2);
00161 }
00162
00163 vgl_line_segment_2d<double> ImageMetric::image_to_homg_line(vgl_line_segment_2d<double> const& l) const
00164 {
00165 vgl_homg_point_2d<double> i1 = imagehomg_to_homg(vgl_homg_point_2d<double>(l.point1()));
00166 vgl_homg_point_2d<double> i2 = imagehomg_to_homg(vgl_homg_point_2d<double>(l.point2()));
00167 return vgl_line_segment_2d<double>(i1,i2);
00168 }
00169
00170 HomgLineSeg2D ImageMetric::image_to_homg_line(const HomgLineSeg2D& l) const
00171 {
00172 HomgPoint2D i1 = imagehomg_to_homg(l.get_point1());
00173 HomgPoint2D i2 = imagehomg_to_homg(l.get_point2());
00174 return HomgLineSeg2D(i1, i2);
00175 }
00176
00177
00178
00179
00180 double ImageMetric::perp_dist_squared(vgl_homg_point_2d<double> const& p,
00181 vgl_homg_line_2d<double> const& l) const
00182 {
00183 return vgl_homg_operators_2d<double>::perp_dist_squared(homg_to_imagehomg(p), homg_to_image_line(l));
00184 }
00185
00186 double ImageMetric::perp_dist_squared(const HomgPoint2D& p, const HomgLine2D& l) const
00187 {
00188 return HomgOperator2D::perp_dist_squared(homg_to_imagehomg(p), homg_to_image_line(l));
00189 }
00190
00191
00192 vgl_homg_point_2d<double> ImageMetric::perp_projection(vgl_homg_line_2d<double> const& l,
00193 vgl_homg_point_2d<double> const& p) const
00194 {
00195 if (l.ideal())
00196 vcl_cerr << "ImageMetric::perp_projection -- line at infinity\n";
00197
00198 return vgl_homg_operators_2d<double>::perp_projection(homg_to_image_line(l), homg_to_imagehomg(p));
00199 }
00200
00201 HomgPoint2D ImageMetric::perp_projection(const HomgLine2D & l, const HomgPoint2D & p) const
00202 {
00203 if (p.ideal()) {
00204 vcl_cerr << "ImageMetric::perp_projection -- point at infinity\n";
00205 }
00206
00207 if (l.ideal()) {
00208 vcl_cerr << "ImageMetric::perp_projection -- line at infinity\n";
00209 }
00210
00211 return HomgOperator2D::perp_projection(homg_to_image_line(l), homg_to_imagehomg(p));
00212 }
00213
00214
00215 double ImageMetric::distance_squared(vgl_homg_point_2d<double> const& p1,
00216 vgl_homg_point_2d<double> const& p2) const
00217 {
00218 return vgl_homg_operators_2d<double>::distance_squared(homg_to_imagehomg(p1), homg_to_imagehomg(p2));
00219 }
00220
00221 double ImageMetric::distance_squared(const HomgPoint2D & p1, const HomgPoint2D & p2) const
00222 {
00223 return HomgOperator2D::distance_squared(homg_to_imagehomg(p1), homg_to_imagehomg(p2));
00224 }
00225
00226
00227
00228 double ImageMetric::distance_squared(vgl_line_segment_2d<double> const& segment,
00229 vgl_homg_line_2d<double> const& line) const
00230 {
00231
00232 return vnl_math_max(this->perp_dist_squared(vgl_homg_point_2d<double>(segment.point1()), line),
00233 this->perp_dist_squared(vgl_homg_point_2d<double>(segment.point2()), line));
00234 }
00235
00236 double ImageMetric::distance_squared(const HomgLineSeg2D& segment, const HomgLine2D& line) const
00237 {
00238
00239 return vnl_math_max(this->perp_dist_squared(segment.get_point1(), line),
00240 this->perp_dist_squared(segment.get_point2(), line));
00241 }
00242
00243 bool ImageMetric::is_within_distance(vgl_homg_point_2d<double> const& p1,
00244 vgl_homg_point_2d<double> const& p2,
00245 double distance) const
00246 {
00247 return distance_squared(p1, p2) < distance*distance;
00248 }
00249
00250 bool ImageMetric::is_within_distance(const HomgPoint2D& p1, const HomgPoint2D& p2, double distance) const
00251 {
00252 return distance_squared(p1, p2) < distance*distance;
00253 }
00254
00255
00256
00257
00258 double ImageMetric::homg_to_image_distance(double image_distance) const
00259 {
00260 warning("ImageMetric::invert_distance()") << "returning 0\n";
00261 return image_distance;
00262 }
00263
00264
00265
00266
00267 double ImageMetric::image_to_homg_distance(double image_distance) const
00268 {
00269 warning("ImageMetric::invert_distance()") << "returning 0\n";
00270 return image_distance;
00271 }
00272
00273
00274 bool ImageMetric::can_invert_distance() const
00275 {
00276 return false;
00277 }
00278
00279
00280
00281
00282 bool ImageMetric::is_linear() const
00283 {
00284 return false;
00285 }
00286
00287 #include <vnl/vnl_identity_3x3.h>
00288
00289
00290
00291 vnl_double_3x3 ImageMetric::get_C() const
00292 {
00293 static vnl_identity_3x3 I;
00294 warning("ImageMetric::get_C()") << "returning identity\n";
00295 return I;
00296 }
00297
00298
00299 vnl_double_3x3 ImageMetric::get_C_inverse() const
00300 {
00301 static vnl_identity_3x3 I;
00302 warning("ImageMetric::get_C_inverse()") << "returning identity\n";
00303 return I;
00304 }
00305
00306 #include <mvl/FMatrix.h>
00307
00308 FMatrix ImageMetric::decondition(const FMatrix& F, const ImageMetric* c1, const ImageMetric* c2)
00309 {
00310 if (!c1->is_linear())
00311 warning("ImageMetric::decondition(FMatrix...)") << "ImageMetric for image 1 is nonlinear\n";
00312
00313 if (!c2->is_linear())
00314 warning("ImageMetric::decondition(FMatrix...)") << "ImageMetric for image 2 is nonlinear\n";
00315
00316 vnl_double_3x3 C1inv = c1->get_C_inverse();
00317 vnl_double_3x3 C2inv = c2->get_C_inverse();
00318 return FMatrix( C1inv.transpose() * F.get_matrix() * C2inv );
00319 }
00320
00321 vcl_ostream & ImageMetric::print(vcl_ostream& s) const
00322 {
00323 return s << "Empty ImageMetric";
00324 }