00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "projective_cam.h"
00024
00025 #include <geometry/hom_point.h>
00026 #include <geometry/vector.h>
00027 #include <core/exceptions/software.h>
00028
00029 #include <cmath>
00030 #include <iostream>
00031
00032 using namespace fawkes;
00033 using std::cout;
00034 using std::endl;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 AboveHorizonException::AboveHorizonException(const char *msg, const center_in_roi_t img_pt) throw()
00047 : fawkes::Exception("AboveHorizonException: %s (%0.1f, %0.1f)", msg, img_pt.x, img_pt.y)
00048 {
00049 __img_pt = img_pt;
00050 }
00051
00052
00053
00054
00055 const center_in_roi_t &
00056 AboveHorizonException::get_img_pt() const
00057 {
00058 return __img_pt;
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 ProjectiveCam::ProjectiveCam(const Calibration &cal, const HomTransform *loc) :
00075 __cal(cal)
00076 {
00077 __p = NULL;
00078 __gpa_inv = NULL;
00079 __gpa_inv_data = new float[9];
00080
00081 if (loc) set_location(*loc);
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 ProjectiveCam::ProjectiveCam(const Calibration &cal,
00094 float roll, float pitch, float yaw,
00095 float height, float x, float y):
00096 __cal(cal)
00097 {
00098 __p = NULL;
00099 __gpa_inv = NULL;
00100 __gpa_inv_data = new float[9];
00101
00102 set_location(roll, pitch, yaw, height, x, y);
00103 }
00104
00105
00106
00107
00108 ProjectiveCam::ProjectiveCam(const ProjectiveCam &pc):
00109 __cal(pc.__cal)
00110 {
00111 __p = (pc.__p != NULL ? new Matrix(*pc.__p) : NULL);
00112 __gpa_inv_data = new float[9];
00113
00114 if (pc.__gpa_inv) {
00115 for (unsigned int i = 0; i < 9; ++i) {
00116 __gpa_inv_data[i] = pc.__gpa_inv_data[i];
00117 }
00118
00119 __gpa_inv = new Matrix(3, 3, __gpa_inv_data, false);
00120 }
00121 else __gpa_inv = NULL;
00122 }
00123
00124
00125
00126 ProjectiveCam::~ProjectiveCam()
00127 {
00128 delete __p;
00129 delete __gpa_inv;
00130 delete[] __gpa_inv_data;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 ProjectiveCam&
00144 ProjectiveCam::set_location(float roll, float pitch, float yaw, float height, float x, float y)
00145 {
00146 HomTransform t;
00147
00148
00149
00150
00151 t.rotate_x(-M_PI_2);
00152 t.rotate_z(-M_PI_2);
00153
00154 t.rotate_y(pitch);
00155 t.rotate_x(-roll);
00156
00157 t.trans(-x, y, height);
00158 t.rotate_z(yaw);
00159
00160 return set_location(t);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 ProjectiveCam&
00170 ProjectiveCam::set_location(const HomTransform& loc)
00171 {
00172 if (__p) {
00173 delete __gpa_inv;
00174 delete __p;
00175 __p = NULL;
00176 }
00177
00178 __p = new Matrix (__cal * loc.get_matrix().get_submatrix(0, 0, 3, 4));
00179
00180 __gpa_inv = new Matrix(3, 3, __gpa_inv_data, false);
00181 __gpa_inv->overlay(0, 0, __p->get_submatrix(0, 0, 3, 2));
00182 __gpa_inv->overlay(0, 2, __p->get_submatrix(0, 3, 3, 1));
00183 __gpa_inv->invert();
00184
00185 return *this;
00186 }
00187
00188
00189
00190
00191
00192 fawkes::cart_coord_2d_t
00193 ProjectiveCam::get_GPA_world_coord(const center_in_roi_t &img_p) const
00194 {
00195 Vector img_v(3);
00196 img_v.x(img_p.x);
00197 img_v.y(img_p.y);
00198 img_v.z(1);
00199
00200 Vector wld_v = *__gpa_inv * img_v;
00201
00202 wld_v /= wld_v.z();
00203
00204 if (wld_v.x() < 0) {
00205 throw AboveHorizonException("The given point is above the horizon!\n", img_p);
00206 }
00207
00208 return (fawkes::cart_coord_2d_t){ wld_v.x(), -wld_v.y() };
00209 }
00210
00211
00212
00213
00214
00215 center_in_roi_t
00216 ProjectiveCam::get_GPA_image_coord(const fawkes::cart_coord_2d_t &wld_p) const
00217 {
00218 Vector wld_v(4);
00219 wld_v.x(wld_p.x);
00220 wld_v.y(wld_p.y);
00221 wld_v.z(0);
00222 wld_v.set(3, 1);
00223
00224 Vector img_v = *__p * wld_v;
00225 img_v /= img_v.z();
00226
00227 center_in_roi_t res;
00228 res.x = img_v.x();
00229 res.y = img_v.y();
00230
00231 return res;
00232 }
00233
00234
00235
00236
00237
00238 Calibration
00239 ProjectiveCam::get_cal() const
00240 {
00241 return Calibration(__cal);
00242 }
00243
00244
00245
00246
00247
00248 Matrix
00249 ProjectiveCam::get_p() const
00250 {
00251 return Matrix(*__p);
00252 }
00253
00254
00255
00256
00257 Matrix
00258 ProjectiveCam::get_GPA_p() const
00259 {
00260 Matrix res(3, 3);
00261 res.overlay(0, 0, __p->get_submatrix(0, 0, 3, 2));
00262 res.overlay(0, 2, __p->get_submatrix(0, 3, 3, 1));
00263
00264 return res;
00265 }
00266
00267
00268
00269
00270
00271
00272 void
00273 ProjectiveCam::print_info (const char *name, const char *col_sep, const char *row_sep) const
00274 {
00275 __p->print_info(name ? name : "Projective Camera", col_sep, row_sep);
00276 __cal.print_info("Calibration Matrix", col_sep, row_sep);
00277 }
00278