diff options
Diffstat (limited to 'meowpp/gra/Camera.h')
-rw-r--r-- | meowpp/gra/Camera.h | 367 |
1 files changed, 42 insertions, 325 deletions
diff --git a/meowpp/gra/Camera.h b/meowpp/gra/Camera.h index 45321de..2b6347c 100644 --- a/meowpp/gra/Camera.h +++ b/meowpp/gra/Camera.h @@ -32,13 +32,10 @@ private: Myself() { fixed2D_.dimension(2); } - ~Myself() { + Myself(Myself const& v): + photo_(v.photo_), rot_(v.rot_), fixed2D_(v.fixed2D_) { } - Myself& copyFrom(Myself const& b) { - photo_ .copyFrom(b. photo_); - rot_ .copyFrom(b. rot_); - fixed2D_.copyFrom(b.fixed2D_); - return *this; + ~Myself() { } }; @@ -47,14 +44,13 @@ public: /*! * @brief constructor */ - Camera(): self(true) { + Camera(): self() { } /*! * @brief copy constructor */ - Camera(Camera const& b): self(false) { - copyFrom(b); + Camera(Camera const& b): self(b.self, Self<Myself>::COPY_FROM) { } /*! @@ -119,7 +115,7 @@ public: * @brief 設定rotation */ Rotation3D<double> const& rotation(Rotation3D<double> const& rot) { - self()->rot_ = rot; + self()->rot_.copyFrom(rot); return rotation(); } @@ -142,7 +138,7 @@ public: */ FixedPoints2D const& fixedPoints2D(FixedPoints2D const& fps2d) const { if (fps2d.dimension() == 2) { - self()->fixed2D_ = fps2d; + self()->fixed2D_.copyFrom(fps2d); } return fixedPoints2D(); } @@ -150,7 +146,7 @@ public: /*! * @brief 取得編號為i的fixed points 2d */ - Vector<double> fixedPoints2D(int i) { + Vector<double> fixedPoint2D(int i) { return self->fixed2D_.identityPoint(i); } @@ -159,7 +155,7 @@ public: */ bool inside(Vector3D<double> p) const { return self->photo_.inside( - Vector3D<double>(self->rot_.transformate(p.matrix()))); + Vector3D<double>(rotation().transformate(p.matrix()))); } /*! @@ -167,7 +163,7 @@ public: */ Pixel color(Vector3D<double> p) const { return self->photo_.color( - Vector3D<double>(self->rot_.transformate(p.matrix()))); + Vector3D<double>(rotation().transformate(p.matrix()))); } /*! @@ -182,7 +178,20 @@ public: * @note 未完成 */ bool write(FILE* f, bool bin, unsigned int fg) const { - return false; + if (bin) { + double tmp; + for (size_t i = 0; i < 3; ++i) { + if (fwrite(&(tmp = rotation().theta(i)), sizeof(tmp), 1, f) < 1) + return false; + } + } + else { + for (size_t i = 0; i < 3; ++i) { + if (fprintf(f, "%f ", rotation().theta(i)) < 1) return false; + } + fprintf(f, "\n"); + } + return (fixedPoints2D().write(f, bin, fg) && photo().write(f, bin, fg)); } /*! @brief 將資料讀入 @@ -190,7 +199,23 @@ public: * @note 未完成 */ bool read(FILE* f, bool bin, unsigned int fg) { - return false; + if (bin) { + double tmp; + for (size_t i = 0; i < 3; ++i) { + if (fread(&tmp, sizeof(tmp), 1, f) < 1) { + return false; + } + rotationGet().theta(i, tmp); + } + } + else { + double a; + for (size_t i = 0; i < 3; ++i) { + if (fscanf(f, "%lf", &a) < 1) return false; + rotationGet().theta(i, a); + } + } + return (fixedPoints2DGet().read(f, bin, fg) && photoGet().read(f, bin, fg)); } /*! @brief new一個自己 @@ -229,316 +254,8 @@ public: std::string type() const { return std::string(ctype()); } - - //////////////////////////////////////////////////////////////////// -private: - class BoundleAdjustment2D { - private: - class Parameters { - private: - std::vector<Camera>& cam_; - std::vector<Rotation3D<double> > rot_; - std::vector<PhotoProjection<double> > pho_; - struct Pair { - size_t i1_; - size_t i2_; - Vector<double> v1_; - Vector<double> v2_; - Pair(size_t a, size_t b, - Vector<double> const& v1, Vector<double> const& v2): - i1_(a), i2_(b), v1_(v1), v2_(v2) { - } - }; - std::vector<Pair> pairs_; - - void setParameters(Vector<double> const& v) { - size_t n = 0; - for (size_t i = 0, I = cam_.size(); i < I; ++i) { - pho_[i].focal(v(n++)); - for (size_t j = 0; j < 3; j++) { - rot_[i].theta(j, v(n++)); - } - } - for (size_t i = 0, I = pairs_.size(); i < I; ++i) { - pairs_[i].v1_.entry(2, pho_[pairs_[i].i1_].focal()); - pairs_[i].v2_.entry(2, pho_[pairs_[i].i2_].focal()); - } - } - Vector<double> getParameters() const { - Vector<double> ret(cam_.size() * 4, 0.0); - for (size_t i = 0, I = cam_.size(); i < I; ++i) { - ret.entry(i * 4, pho_[i].focal()); - for (size_t j = 0; j < 3; ++j) { - ret.entry(i * 4 + 1 + j, rot_[i].theta(j)); - } - } - return ret; - } - Vector<double> residureV() const { - Vector<double> ret(pairs_.size() * 3, 0.0); - for (size_t i = 0, I = pairs_.size(); i < I; ++i) { - size_t i_from = pairs_[i].i1_; - size_t i_to = pairs_[i].i2_; - Matrix<double> v_from(pairs_[i].v1_.matrix()); - Matrix<double> v_to (pairs_[i].v2_.matrix()); - Matrix<double> v_tr( - pho_[i_to].transformate( - rot_[i_to].transformate( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - ) - ); - Matrix<double> delta(v_to - v_tr); - for (size_t j = 0; j < 3; ++j) { - ret.entry(i * 3 + j, delta(j, 0)); - } - } - return ret; - } - public: - Parameters(std::vector<Camera>& cam): cam_(cam) { - rot_.resize(cam_.size()); - pho_.resize(cam_.size(), PhotoProjection<double>(3)); - for (size_t i = 0, I = cam_.size(); i < I; ++i) { - rot_[i].referenceFrom(cam_[i].rotation()); - pho_[i].focal(cam_[i].photo().focal()); - } - for (size_t i = 0, I = cam_.size(); i < I; ++i) { - std::map<int,Vector<double> >const& p1 = ( - cam_[i].fixedPoints2D().identityPoints()); - for (size_t j = 0; j < I; ++j) { - if (i == j) continue; - std::map<int,Vector<double> >const& p2 = ( - cam_[j].fixedPoints2D().identityPoints()); - for (std::map<int,Vector<double> >::const_iterator - it1 = p1.begin(); it1 != p1.end(); ++it1) { - for (std::map<int,Vector<double> >::const_iterator - it2 = p2.begin(); it2 != p2.end(); ++it2) { - if (it1->first != it2->first) continue; - Vector<double> v1(it1->second), v2(it2->second); - v1.dimension(3, 0.0); - v2.dimension(3, 0.0); - pairs_.push_back(Pair(i, j, v1, v2)); - } - } - } - } - } - Vector<double> init() const { - return getParameters(); - } - Vector<double> residure(Vector<double> const& v) const { - ((Parameters*)this)->setParameters(v); - return residureV(); - } - Matrix<double> jacobian(Vector<double> const& v) const { - //setParameters(v); - Matrix<double> ret(pairs_.size() * 3, v.dimension(), 0.0); - for (size_t i = 0, I = pairs_.size(); i < I; ++i) { - for (size_t j = 0, J = v.dimension(); j < J; ++j) { - size_t j0 = j / 4; - size_t dj = j % 4; - size_t i_from = pairs_[i].i1_; - size_t i_to = pairs_[i].i2_; - Matrix<double> v_from(pairs_[i].v1_.matrix()); - Matrix<double> v_to (pairs_[i].v2_.matrix()); - Matrix<double> v_tr (3, 1, 0.0); - if (j0 == i_from) { - if (dj == 0) { - v_tr = ( - pho_[i_to].jacobian( - rot_[i_to].transformate( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - ) - * - rot_[i_to].jacobian( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - * - rot_[i_from].jacobianInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - * - BallProjection<double>(3, 1.0).jacobian( - v_from - ).col(2) - ); - } - else { - v_tr = ( - pho_[i_to].jacobian( - rot_[i_to].transformate( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - ) - * - rot_[i_to].jacobian( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - * - rot_[i_from].jacobianInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ); - } - } - else if (j0 == i_to) { - if (dj == 0) { - v_tr = ( - pho_[i_to].jacobian( - rot_[i_to].transformate( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - ).col(2) - ); - } - else { - v_tr = ( - pho_[i_to].jacobian( - rot_[i_to].transformate( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ) - ) - ) - * - rot_[i_to].jacobian( - rot_[i_from].transformateInv( - BallProjection<double>(3, 1.0).transformate( - v_from - ) - ), - dj - 1 - ) - ); - } - } - for (size_t k = 0; k < 3; ++k) { - ret.entry(i * 3 + k, j, -v_tr(k, 0)); - } - } - } - return ret; - } - Matrix<double> identity(Vector<double> const& v) const { - //setParameters(v); - Matrix<double> ret(v.dimension(), v.dimension(), 0.0); - ret.identity(); - return ret; - } - double averageResidure() const { - Vector<double> res(residureV()); - double sum = 0; - for (size_t i = 0, I = res.dimension(); i < I; ++i) { - sum += res(i); - } - return sum / res.dimension(); - } - size_t dimensinonI() const { - return cam_.size() * 4; - } - size_t dimensionO() const { - return pairs_.size() * 3; - } - }; - class F { - private: - Parameters& p_; - public: - F(Parameters& p): p_(p) { - } - Vector<double> operator()(Vector<double> const& v) const { - return p_.residure(v); - } - }; - class J { - private: - Parameters& p_; - public: - J(Parameters& p): p_(p) { - } - Matrix<double> operator()(Vector<double> const& v) const { - return p_.jacobian(v); - } - }; - class I { - private: - Parameters& p_; - public: - I(Parameters& p): p_(p) { - } - Matrix<double> operator()(Vector<double> const& v) const { - return p_.identity(v); - } - }; - class Stop { - private: - Parameters& p_; - double t_; - public: - Stop(Parameters& p, double t): p_(p), t_(t) { - } - bool operator()(double r) const { - return (r < p_.dimensionO() * t_); - } - }; - public: - BoundleAdjustment2D() { - } - ~BoundleAdjustment2D() { - } - double operator()(std::vector<Camera>* cs, double threshold) const { - Parameters p(*cs); - Vector<double> v0(p.init()); - levenbergMarquardt(F(p), J(p), I(p), v0, Stop(p, threshold), 100000); - return p.averageResidure(); - } - }; -public: - /*! - * @brief 將數台camera用fixed points做boundle adjustment - * - * @param [in] cs 要調整的cameras - * @param [in] threshold 允許誤差值 - * @return 誤差值 - */ - static double boundleAdjustment2D(std::vector<Camera>* cs, double threshold) { - static BoundleAdjustment2D bdl; - return bdl(cs, threshold); - } }; -} +} // meow #endif // gra_Camera_H__ |