aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/gra
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/gra')
-rw-r--r--meowpp/gra/Bitmap.h87
-rw-r--r--meowpp/gra/BundleAdjustment.h54
-rw-r--r--meowpp/gra/BundleAdjustment_LM.h375
-rw-r--r--meowpp/gra/Camera.h367
-rw-r--r--meowpp/gra/Eye.h174
-rw-r--r--meowpp/gra/FeaturePoint.h79
-rw-r--r--meowpp/gra/FeaturePointsDetector.h4
-rw-r--r--meowpp/gra/FeaturePointsDetector_Harris.h59
-rw-r--r--meowpp/gra/FeaturePointsMatch.h25
-rw-r--r--meowpp/gra/FeaturePointsMatch_K_Match.h38
-rw-r--r--meowpp/gra/IdentityPoints.h140
-rw-r--r--meowpp/gra/Photo.h78
-rw-r--r--meowpp/gra/WatchBall.h11
13 files changed, 966 insertions, 525 deletions
diff --git a/meowpp/gra/Bitmap.h b/meowpp/gra/Bitmap.h
index c4ed4e0..59136c2 100644
--- a/meowpp/gra/Bitmap.h
+++ b/meowpp/gra/Bitmap.h
@@ -1,9 +1,6 @@
#ifndef gra_Bitmap_H__
#define gra_Bitmap_H__
-
-#include "../Self.h"
-
#include "../math/utility.h"
#include "../math/Matrix.h"
@@ -15,7 +12,7 @@
#include <typeinfo>
#include <cstdlib>
-namespace meow{
+namespace meow {
/*!
* @brief 二維點陣資料
@@ -26,7 +23,8 @@ template<class Pixel>
class Bitmap: public ObjBase {
private:
Matrix<Pixel> matrix_;
- //
+
+ //! 回傳高斯模糊的權重
static std::vector<double> gaussianFactor1(double sigma) {
double sigma2 = squ(sigma);
size_t width = std::max(ceil((double)(sigma * 2)), 0.0);
@@ -38,6 +36,8 @@ private:
factor[width] = 1.0;
return factor;
}
+
+ //! 回傳gradiance的權重
static std::vector<double> gradianceFactor1(double sigma) {
double sigma2 = squ(sigma), ss = sigma * 2;
size_t width = std::max(ceil(ss), 1.0);
@@ -49,6 +49,8 @@ private:
factor[width] = 0.0;
return factor;
}
+
+ //! 針對某一方向用某種權重模糊
Bitmap xyBlur(std::vector<double> const& factor,
ssize_t dx, ssize_t dy) const {
Bitmap ret(*this);
@@ -128,7 +130,7 @@ public:
void reset(size_t h, size_t w, Pixel const& p) {
matrix_.reset(h, w, p);
}
-
+
/*!
* @brief 清除資料, 寬高階規零
*/
@@ -233,6 +235,28 @@ public:
}
/*!
+ * @brief 回傳矩陣形式
+ */
+ Matrix<Pixel> const& matrix() const {
+ return matrix_;
+ }
+
+ /*!
+ * @brief 回傳矩陣形式 (non-constant form)
+ */
+ Matrix<Pixel>& matrixGet() {
+ return matrix_;
+ }
+
+ /*!
+ * @brief 直接設定
+ */
+ Matrix<Pixel> const& matrix(Matrix<Pixel> const& p) {
+ matrix_.copyFrom(p);
+ return matrix();
+ }
+
+ /*!
* @brief 回傳高斯模糊
*
* @param [in] radiusY 高斯模糊的Y軸方向的sigma
@@ -278,7 +302,7 @@ public:
Bitmap<Pixel>& gradiancedX(double radiusY, double radiusX) {
return copyFrom(gradianceX(radiusY, radiusX));
}
-
+
/*!
* @brief 回傳對y偏微分
*
@@ -322,48 +346,42 @@ public:
Pixel const& operator()(size_t y, size_t x, Pixel const& p) const {
return pixel(y, x, p);
}
-
+
/*! @brief 將資料寫入檔案
*
* @note 未完成, 輸入參數 fg 無用
*/
bool write(FILE* f, bool bin, unsigned int fg) const {
- size_t w = width(), h = height();
+ if (fg & 1)
+ return false;
if (bin) {
- if (fwrite(&h, sizeof(size_t), 1, f) < 1) return false;
- if (fwrite(&w, sizeof(size_t), 1, f) < 1) return false;
+ long tmp;
+ if (fwrite(&(tmp = matrix_.cols()), sizeof(tmp), 1, f) < 1) return false;
+ if (fwrite(&(tmp = matrix_.rows()), sizeof(tmp), 1, f) < 1) return false;
}
else {
- if (fprintf(f, "%lu %lu\n", h, w) < 2) return false;
- }
- if (fg) {
- // TODO
- return false;
+ if (fprintf(f, "%ld %ld\n", (long)matrix_.cols(), (long)matrix_.rows())
+ < 2) return false;
}
return true;
- //return propertyWrite(__f, __bin, __fg);
}
-
+
/*! @brief 將資料讀入
*
* @note 未完成, 輸入參數 fg 無用
*/
bool read(FILE* f, bool bin, unsigned int fg) {
- size_t w, h;
- if (bin) {
- if (fread(&h, sizeof(size_t), 1, f) < 1) return false;
- if (fread(&w, sizeof(size_t), 1, f) < 1) return false;
- }
- else {
- if (fscanf(f, "%lu %lu\n", &h, &w) < 2) return false;
- }
- if (fg) {
- // TODO
+ if (fg & 1)
return false;
+ long tmp1, tmp2;
+ if (bin) {
+ if (fread(&tmp1, sizeof(tmp1), 1, f) < 1) return false;
+ if (fread(&tmp2, sizeof(tmp2), 1, f) < 1) return false;
}
else {
- reset(h, w, Pixel(0));
+ if (fscanf(f, "%ld %ld", &tmp1, &tmp2) < 2) return false;
}
+ matrix_.size(tmp1, tmp2, Pixel(0));
return true;
}
@@ -374,7 +392,7 @@ public:
ObjBase* create() const {
return new Bitmap();
}
-
+
/*! @brief 複製資料
*
* 輸入型別是 \c ObjBase \c const*
@@ -387,16 +405,15 @@ public:
ObjBase* copyFrom(ObjBase const* b) {
return &(copyFrom(*(Bitmap*)b));
}
-
+
/*! @brief 回傳class的type
*
* @return \c char \c const\c * 形式的typename
*/
char const* ctype() const{
- static char const* ptr = typeid(*this).name();
- return ptr;
+ return typeid(*this).name();
}
-
+
/*! @brief 回傳class的type
*
* @return \c std::string 形式的typename
@@ -406,6 +423,6 @@ public:
}
};
-}
+} // meow
#endif // gra_Bitmap_H__
diff --git a/meowpp/gra/BundleAdjustment.h b/meowpp/gra/BundleAdjustment.h
new file mode 100644
index 0000000..9dd01b7
--- /dev/null
+++ b/meowpp/gra/BundleAdjustment.h
@@ -0,0 +1,54 @@
+#ifndef BundleAdjustment_H__
+#define BundleAdjustment_H__
+
+#include "Eye.h"
+
+#include "../oo/ObjBase.h"
+
+namespace meow {
+
+enum SceneInfoFlags {
+ CAN_OFFSET = 0x01,
+ CAN_ROTATE = 0x02,
+ CAN_ZOOM = 0x04
+};
+
+template<class Pixel>
+struct SceneInfo {
+ Eye<Pixel>* eye;
+ unsigned long flag;
+
+ SceneInfo(): eye(NULL), flag(0) {
+ }
+
+ SceneInfo(Eye<Pixel>* e, unsigned long f): eye(e), flag(f) {
+ }
+
+ SceneInfo(SceneInfo const& si): eye(si.eye), flag(si.flag) {
+ }
+
+ ~SceneInfo() {
+ }
+};
+
+template<class Pixel>
+class BundleAdjustment: public ObjBase {
+protected:
+ BundleAdjustment() {
+ }
+public:
+ virtual ~BundleAdjustment() {
+ }
+
+ virtual bool adjustEye(std::vector<SceneInfo<Pixel> >* seq) const {
+ return false;
+ }
+
+ virtual bool adjustFixedPoint(std::vector<SceneInfo<Pixel> >* seq) const {
+ return false;
+ }
+};
+
+} // meow
+
+#endif // BundleAdjustment_H__
diff --git a/meowpp/gra/BundleAdjustment_LM.h b/meowpp/gra/BundleAdjustment_LM.h
new file mode 100644
index 0000000..7a86666
--- /dev/null
+++ b/meowpp/gra/BundleAdjustment_LM.h
@@ -0,0 +1,375 @@
+#ifndef BundleAdjustment_LM_H__
+#define BundleAdjustment_LM_H__
+
+#include "Eye.h"
+
+#include "BundleAdjustment.h"
+
+#include "../math/methods.h"
+#include "../math/Vector.h"
+#include "../math/Matrix.h"
+#include "../math/utility.h"
+
+#include "../oo/ObjBase.h"
+
+#include <algorithm>
+
+namespace meow {
+
+template<class Pixel>
+class BundleAdjustment_LM: public BundleAdjustment<Pixel> {
+private:
+ struct MatchPair {
+ size_t from_i;
+ Matrix<double> from_m;
+ size_t to_i;
+ Matrix<double> to_m;
+ };
+
+ class NoOffsetController {
+ private:
+ std::vector<MatchPair >* pairs_;
+ std::vector<Rotation3D <double> >* rot_;
+ std::vector<PhotoProjection<double> >* pho_;
+ BallProjection<double> bll_;
+ bool flag;
+ public:
+ NoOffsetController(std::vector<MatchPair >* pairs,
+ std::vector<Rotation3D<double> >* rot,
+ std::vector<PhotoProjection<double> >* pho,
+ bool fg):
+ pairs_(pairs), rot_(rot), pho_(pho), bll_(3.0, 1.0), flag(fg) {
+ }
+ Vector<double> init() {
+ if (flag == false) {
+ Vector<double> v(4, 0.0);
+ int i = (*pho_).size() - 1, n = 0;
+ v.entry(n++, (*pho_)[i].focal());
+ v.entry(n++, (*rot_)[i].theta(0));
+ v.entry(n++, (*rot_)[i].theta(1));
+ v.entry(n++, (*rot_)[i].theta(2));
+ return v;
+ }
+ Vector<double> v((*rot_).size() * 4, 0.0);
+ for (size_t n = 0, i = 0, I = (*rot_).size(); i < I; ++i) {
+ v.entry(n++, (*pho_)[i].focal());
+ v.entry(n++, (*rot_)[i].theta(0));
+ v.entry(n++, (*rot_)[i].theta(1));
+ v.entry(n++, (*rot_)[i].theta(2));
+ }
+ return v;
+ }
+ Vector<double> residure(Vector<double> const& v) {
+ for (size_t n = 0, i = 0, I = (*rot_).size(); i < I; ++i) {
+ if (flag == false && i != I - 1) continue;
+ (*pho_)[i].focal(v(n++));
+ (*rot_)[i].theta(0, v(n++));
+ (*rot_)[i].theta(1, v(n++));
+ (*rot_)[i].theta(2, v(n++));
+ }
+ for (typename std::vector<MatchPair>::iterator
+ it = (*pairs_).begin(), ed = (*pairs_).end(); it != ed; ++it) {
+ (*it).from_m.entry(2, 0, -(*pho_)[(*it).from_i].focal());
+ (*it). to_m.entry(2, 0, -(*pho_)[(*it). to_i].focal());
+ }
+ //
+ Vector<double> ret((*pairs_).size() * 2, 0.0);
+ size_t n = 0;
+ for (typename std::vector<MatchPair>::iterator
+ it = (*pairs_).begin(), ed = (*pairs_).end(); it != ed; ++it, ++n) {
+ Matrix<double> tr(
+ (*it).to_m
+ -
+ (*pho_)[(*it).to_i].transformate(
+ (*rot_)[(*it).to_i].transformate(
+ (*rot_)[(*it).from_i].transformateInv(
+ bll_.transformate(
+ (*it).from_m
+ )
+ )
+ )
+ )
+ );
+ ret.entry(n * 2 , tr(0, 0));
+ ret.entry(n * 2 + 1, tr(1, 0));
+ }
+ //*
+ //for (size_t i = 0; i < ret.dimension(); i++) {
+ // printf("(%-9.1f ", ret(i));
+ // if (i % 8 == 7) printf("\n");
+ //}
+ //printf("\n");
+ printf("re = %20.5f ?? %f\n", ret.length2(), 25.0 * (*pairs_).size());
+ // */
+ return ret;
+ }
+ Matrix<double> jacobian() const {
+ Matrix<double> ret;
+ if (flag == false) {
+ ret.reset((*pairs_).size() * 2, 4, 0.0);
+ }
+ else {
+ ret.reset((*pairs_).size() * 2, (*rot_).size() * 4, 0.0);
+ }
+ size_t n = 0;
+ for (typename std::vector<MatchPair>::iterator
+ it = (*pairs_).begin(), ed = (*pairs_).end(); it != ed; ++it, ++n) {
+ Matrix<double> tr_A( bll_ .transformate((*it).from_m));
+ Matrix<double> tr_B((*rot_)[(*it).from_i].transformateInv(tr_A));
+ Matrix<double> tr_C((*rot_)[(*it). to_i].transformate (tr_B));
+ Matrix<double> ja_A((*pho_)[(*it). to_i].jacobian (tr_C));
+ Matrix<double> ja_B((*rot_)[(*it). to_i].jacobian (tr_B));
+ Matrix<double> ja_C((*rot_)[(*it).from_i].jacobianInv(tr_A));
+ Matrix<double> m;
+ int fr = (flag == false ? 0 : (*it).from_i);
+ int to = (flag == false ? 0 : (*it). to_i);
+ if (flag != false || (*it).from_i == (*rot_).size() - 1) {
+ m = ja_A * ja_B * ja_C * bll_.jacobian((*it).from_m).col(2);
+ ret.entry(n * 2 , fr * 4, m(0, 0));
+ ret.entry(n * 2 + 1, fr * 4, m(1, 0));
+ for (size_t k = 0; k < 3; ++k) {
+ m = ja_A * ja_B * (*rot_)[(*it).from_i].jacobianInv(tr_A, k);
+ ret.entry(n * 2 , fr * 4 + 1 + k, m(0, 0));
+ ret.entry(n * 2 + 1, fr * 4 + 1 + k, m(1, 0));
+ }
+ }
+ if (flag != false || (*it).to_i == (*rot_).size() - 1) {
+ m = (*pho_)[(*it).to_i].jacobian(tr_C, 0);
+ ret.entry(n * 2 , to * 4, m(0, 0));
+ ret.entry(n * 2 + 1, to * 4, m(1, 0));
+ for (size_t k = 0; k < 3; ++k) {
+ m = ja_A * (*rot_)[(*it).to_i].jacobian(tr_B, k);
+ ret.entry(n * 2 , to * 4 + 1 + k, m(0, 0));
+ ret.entry(n * 2 + 1, to * 4 + 1 + k, m(1, 0));
+ }
+ }
+ }
+ return ret;
+ }
+ Matrix<double> identity() const {
+ if (flag == false) {
+ Matrix<double> ret(4, 4, 0.0);
+ ret.identitied();
+ return ret;
+ }
+ Matrix<double> ret((*rot_).size() * 4, (*rot_).size() * 4, 0.0);
+ ret.identitied();
+ return ret;
+ }
+ };
+
+ struct Myself {
+ double t_;
+
+ Myself(): t_(5.0) {
+ }
+
+ Myself(Myself const& m): t_(m.t_) {
+ }
+
+ ~Myself() {
+ }
+ };
+
+ Self<Myself> const self;
+
+public:
+ BundleAdjustment_LM(): self() {
+ }
+
+ BundleAdjustment_LM(BundleAdjustment_LM const& b):
+ self(b.self, Self<Myself>::COPY_FROM) {
+ }
+
+ ~BundleAdjustment_LM() {
+ }
+
+ BundleAdjustment_LM& copyFrom(BundleAdjustment_LM const& b) {
+ self().copyFrom(b.self);
+ return *this;
+ }
+
+ BundleAdjustment_LM& referenceFrom(BundleAdjustment_LM const& b) {
+ self().referenceFrom(b.self);
+ return *this;
+ }
+
+ double threshold() const {
+ return self->t_;
+ }
+
+ double threshold(double t) {
+ self()->t_ = t;
+ return threshold();
+ }
+
+ bool adjustEye(std::vector<SceneInfo<Pixel> >* seq) const {
+ // check
+ size_t N = (*seq).size();
+ for (size_t i = 0; i < N; ++i) {
+ if ( (*seq)[i].flag & CAN_OFFSET ) return false;
+ if (!((*seq)[i].flag & CAN_ROTATE)) return false;
+ if (!((*seq)[i].flag & CAN_ZOOM )) return false;
+ }
+ // get all pairs
+ typedef typename Camera<Pixel>::FixedPoints2D::IdentityPointsMapIterK FPS_K;
+ std::vector<FPS_K> beg(N), end(N);
+ FPS_K it1, it2;
+ for (size_t i = 0; i < N; ++i) {
+ beg[i] = (*seq)[i].eye->camera().fixedPoints2D().identityPoints().begin();
+ end[i] = (*seq)[i].eye->camera().fixedPoints2D().identityPoints().end ();
+ }
+ std::vector<std::vector<std::vector<MatchPair> > > all_pairs(N);
+ for (size_t i = 0; i < N; ++i) {
+ all_pairs[i].resize(N);
+ for (size_t j = 0; j < N; ++j) {
+ if (i == j) continue;
+ for (it1 = beg[i], it2 = beg[j]; it1 != end[i] && it2 != end[j]; ) {
+ if (it1->first < it2->first) ++it1;
+ else if(it1->first > it2->first) ++it2;
+ else {
+ MatchPair tmp;
+ tmp.from_i = i;
+ tmp.from_m = it1->second.matrix();
+ tmp.from_m.rows(3, -(*seq)[i].eye->camera().photo().focal());
+ tmp. to_i = j;
+ tmp. to_m = it2->second.matrix();
+ tmp. to_m.rows(3, -(*seq)[j].eye->camera().photo().focal());
+ all_pairs[i][j].push_back(tmp);
+ ++it1;
+ ++it2;
+ }
+ }
+ }
+ }
+ //
+ std::vector<MatchPair > pairs;
+ std::vector<Rotation3D <double> > rot;
+ std::vector<PhotoProjection<double> > pho;
+ std::vector<int > sum (N, 0);
+ std::vector<int > big (N, 0);
+ std::vector<int > real(N);
+ std::vector<int > rev (N);
+ // first!!
+ int best = -1, best_ct = -1;
+ for (size_t i = 0; i < N; ++i) {
+ int d = 0;
+ for (size_t j = 0; j < N; ++j) {
+ d += all_pairs[i][j].size();
+ }
+ if (best_ct < d) {
+ best_ct = d;
+ best = i;
+ }
+ real[i] = i;
+ big [i] = i;
+ }
+ for (size_t i = 0; i < N; ++i) {
+ // update else
+ real[i] = best;
+ rev[best] = i;
+ for (size_t j = 0; j < N; ++j) {
+ if ((int)j == best) {
+ sum[j] = -1;
+ continue;
+ }
+ if (sum[j] < 0) continue;
+ sum[j] += all_pairs[best][j].size();
+ if (all_pairs[j][big[j]].size() < all_pairs[j][best].size())
+ big[j] = best;
+ }
+ // add me
+ printf("%d same as %d\n", best, big[best]);
+ if (big[best] == best) {
+ rot.push_back((*seq)[big[best]].eye->camera() .rotation());
+ pho.push_back((*seq)[big[best]].eye->camera().photo().projection());
+ }
+ else {
+ rot.push_back(rot[rev[big[best]]]);
+ pho.push_back(pho[rev[big[best]]]);
+ }
+ for (size_t j = 0; j < N; ++j) {
+ if (sum[j] >= 0) continue;
+ for (size_t k = 0, K = all_pairs[best][j].size(); k < K; ++k) {
+ all_pairs[best][j][k].from_i = rev[all_pairs[best][j][k].from_i];
+ all_pairs[best][j][k]. to_i = rev[all_pairs[best][j][k]. to_i];
+ pairs.push_back(all_pairs[best][j][k]);
+ }
+ for (size_t k = 0, K = all_pairs[j][best].size(); k < K; ++k) {
+ all_pairs[j][best][k].from_i = rev[all_pairs[j][best][k].from_i];
+ all_pairs[j][best][k]. to_i = rev[all_pairs[j][best][k]. to_i];
+ pairs.push_back(all_pairs[j][best][k]);
+ }
+ }
+ for (size_t j = 0; j < N; ++j) { printf("%4d ", sum[j]); } printf("\n");
+ for (size_t j = 0; j < N; ++j) { printf("%4d ", big[j]); } printf("\n");
+ for (size_t j = 0; j < N; ++j) { printf("%4d ", real[j]); } printf("\n");
+ printf("\n");
+ // bundle adjustment
+ if (i > 0) {
+ NoOffsetController ct1(&pairs, &rot, &pho, false);
+ ct1.residure(levenbergMarquardtTraining(ct1, ct1.init(),
+ 7.3, 1.0,
+ squ(threshold()) * pairs.size(),
+ 7, 1000));
+ /*
+ NoOffsetController ct2(&pairs, &rot, &pho, true);
+ ct2.residure(levenbergMarquardtTraining(ct2, ct2.init(),
+ 0.1 * pairs.size(), 1.0,
+ squ(threshold()) * pairs.size(),
+ 7, 1000));
+ // */
+ }
+ // find next
+ best_ct = 0;
+ for (size_t j = 0; j < N; ++j) {
+ if (best_ct < sum[j]) {
+ best = j;
+ best_ct = sum[j];
+ }
+ }
+ getchar();
+ //if (i == N - 2) break;
+ }
+ // feedback
+ for (size_t i = 0; i < N; ++i) {
+ int id = real[i];
+ (*seq)[id].eye->cameraGet() .rotation (rot[i]);
+ (*seq)[id].eye->cameraGet().photoGet().projection(pho[i]);
+ //if (i == N - 2) break;
+ }
+ return true;
+ }
+
+ bool adjustFixedPoint(std::vector<SceneInfo<Pixel> >* seq) const {
+ return false;
+ }
+
+ bool write(FILE* f, bool bin, unsigned int fg) const {
+ return false;
+ }
+
+ bool read(FILE* f, bool bin, unsigned int fg) const {
+ return false;
+ }
+
+ ObjBase* create() const {
+ return new BundleAdjustment_LM;
+ }
+
+ ObjBase* copyFrom(ObjBase const* o) {
+ return &(copyFrom(*(BundleAdjustment_LM const*)o));
+ }
+
+ char const* ctype() const {
+ return typeid(*this).name();
+ }
+
+ std::string type() const {
+ return std::string(ctype());
+ }
+};
+
+} // meow
+
+#endif // BundleAdjustment_LM_H__
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__
diff --git a/meowpp/gra/Eye.h b/meowpp/gra/Eye.h
new file mode 100644
index 0000000..2621a16
--- /dev/null
+++ b/meowpp/gra/Eye.h
@@ -0,0 +1,174 @@
+#ifndef Eye_H__
+#define Eye_H__
+
+#include "Camera.h"
+
+#include "../Self.h"
+#include "../oo/ObjBase.h"
+
+namespace meow {
+
+/*!
+ * @brief 一個 \c Camera 加上一個offset transformation
+ *
+ * @author cat_leopard
+ */
+template<class Pixel>
+class Eye: public ObjBase {
+private:
+ struct Myself {
+ Camera<Pixel> cam_;
+ Vector3D<double> ofs_;
+
+ Myself(): cam_(), ofs_(0.0, 0.0, 0.0) {
+ }
+
+ Myself(Camera<Pixel> const& c, Vector3D<double> const& o): cam_(c), ofs_(o){
+ }
+
+ Myself(Myself const& b): cam_(b.cam_), ofs_(b.ofs_) {
+ }
+
+ ~Myself() {
+ }
+ };
+
+ Self<Myself> const self;
+public:
+ Eye(): self() {
+ }
+
+ Eye(Eye const& b): self(b.self(), Self<Myself>::COPY_FROM) {
+ }
+
+ Eye(Camera<Pixel> const& c, Vector3D<double> const& o): self(Myself(c, o)) {
+ }
+
+ ~Eye() {
+ }
+
+ Eye& copyFrom(Eye const& e) {
+ self().copyFrom(e.self);
+ return *this;
+ }
+
+ Eye& referenceFrom(Eye const& e) {
+ self().referenceFrom(e.self);
+ return *this;
+ }
+
+ Camera<Pixel> const& camera() const {
+ return self->cam_;
+ }
+
+ Camera<Pixel>& cameraGet() {
+ return self()->cam_;
+ }
+
+ Camera<Pixel> const& camera(Camera<Pixel> const& c) {
+ self()->cam_.copyFrom(c);
+ return camera();
+ }
+
+ Vector3D<double> const& offset() const {
+ return self->ofs_;
+ }
+
+ Vector3D<double>& offsetGet() {
+ return self()->ofs_;
+ }
+
+ Vector3D<double> const& offset(Vector3D<double> const& ofs) {
+ self()->ofs_ = ofs;
+ return offset();
+ }
+
+ bool inside(Vector3D<double> const& v) const {
+ return camera().inside(v - offset());
+ }
+
+ Eye& operator=(Eye const& e) {
+ return copyFrom(e);
+ }
+
+ /*! @brief 將資料寫入檔案
+ *
+ * @note 未完成
+ */
+ bool write(FILE* f, bool bin, unsigned int fg) const {
+ if (bin) {
+ double tmp;
+ for (size_t i = 0; i < 3; ++i) {
+ if (fwrite(&(tmp = offset()(i)), sizeof(tmp), 1, f) < 1)
+ return false;
+ }
+ }
+ else {
+ for (size_t i = 0; i < 3; ++i) {
+ if (fprintf(f, "%f ", offset()(i)) < 1) return false;
+ }
+ fprintf(f, "\n");
+ }
+ return camera().write(f, bin, fg);
+ }
+
+ /*! @brief 將資料讀入
+ *
+ * @note 未完成
+ */
+ bool read(FILE* f, bool bin, unsigned int fg) {
+ if (bin) {
+ double tmp[3];
+ if (fread(tmp, sizeof(double), 3, f) < 3) return false;
+ offsetGet().xyz(tmp[0], tmp[1], tmp[2]);
+ }
+ else {
+ double a, b, c;
+ if (fscanf(f, "%lf %lf %lf", &a, &b, &c) < 3) return false;
+ offsetGet().x(a);
+ offsetGet().y(b);
+ offsetGet().z(c);
+ }
+ return cameraGet().read(f, bin, fg);
+ }
+
+ /*! @brief new一個自己
+ *
+ * @return 一個new出來的pointer
+ */
+ ObjBase* create() const {
+ return new Eye();
+ }
+
+ /*! @brief 複製資料
+ *
+ * 輸入型別是 \c ObjBase \c const*
+ * 事實上這個method就只是幫忙轉型然後呼叫原本的\c copyFrom
+ *
+ * @param [in] b 資料來源
+ * @return this
+ */
+ ObjBase* copyFrom(ObjBase const* b) {
+ return &(copyFrom(*(Eye*)b));
+ }
+
+ /*! @brief 回傳class的type
+ *
+ * @return \c char \c const\c * 形式的typename
+ */
+ char const* ctype() const{
+ return typeid(*this).name();
+ }
+
+ /*! @brief 回傳class的type
+ *
+ * @return \c std::string 形式的typename
+ */
+ std::string type() const {
+ return std::string(ctype());
+ }
+};
+
+} // meow
+
+#endif // Eye_H__
diff --git a/meowpp/gra/FeaturePoint.h b/meowpp/gra/FeaturePoint.h
index 4b80a3d..c3ab8f3 100644
--- a/meowpp/gra/FeaturePoint.h
+++ b/meowpp/gra/FeaturePoint.h
@@ -75,6 +75,13 @@ public:
}
/*!
+ * @brief 回傳position (non-const reference)
+ */
+ Vector<Scalar>& positionGet() {
+ return pos_;
+ }
+
+ /*!
* @brief 回傳description
*/
Vector<Description> const& description() const {
@@ -82,6 +89,13 @@ public:
}
/*!
+ * @brief 回傳description (non-const reference)
+ */
+ Vector<Description>& descriptionGet() {
+ return des_;
+ }
+
+ /*!
* @brief 修改position
*/
Vector<Scalar> const& position(Vector<Scalar> const& p) const {
@@ -128,20 +142,6 @@ public:
}
/*!
- * @brief 取得position
- */
- Vector<Scalar>& positionGet() {
- return pos_;
- }
-
- /*!
- * @brief 取得description
- */
- Vector<Description>& descriptionGet() {
- return des_;
- }
-
- /*!
* @brief same as copyFrom(fp)
*/
FeaturePoint& operator=(FeaturePoint const& fp) {
@@ -163,11 +163,53 @@ public:
}
bool write(FILE* f, bool bin, unsigned int fg) const {
- return false;
+ if (bin) {
+ double tmp;
+ for (size_t i = 0, I = position().dimension(); i < I; ++i) {
+ if (fwrite(&(tmp = position(i)), sizeof(tmp), 1, f) < 1) return false;
+ }
+ for (size_t i = 0, I = description().dimension(); i < I; ++i) {
+ if (fwrite(&(tmp = description(i)), sizeof(tmp), 1, f) < 1)
+ return false;
+ }
+ }
+ else {
+ for (size_t i = 0, I = position().dimension(); i < I; ++i) {
+ if (fprintf(f, "%f ", (double)position(i)) < 1) return false;
+ }
+ fprintf(f, "\n");
+ for (size_t i = 0, I = description().dimension(); i < I; ++i) {
+ if (fprintf(f, "%f ", (double)description(i)) < 1) return false;
+ }
+ fprintf(f, "\n");
+ }
+ return true;
}
bool read (FILE* f, bool bin, unsigned int fg) {
- return false;
+ if (bin) {
+ double tmp;
+ for (size_t i = 0, I = position().dimension(); i < I; ++i) {
+ if (fread(&tmp, sizeof(tmp), 1, f) < 1) return false;
+ position(i, tmp);
+ }
+ for (size_t i = 0, I = description().dimension(); i < I; ++i) {
+ if (fread(&tmp, sizeof(tmp), 1, f) < 1) return false;
+ description(i, tmp);
+ }
+ }
+ else {
+ double tmp;
+ for (size_t i = 0, I = position().dimension(); i < I; ++i) {
+ if (fscanf(f, "%lf", &tmp) < 1) return false;
+ position(i, tmp);
+ }
+ for (size_t i = 0, I = description().dimension(); i < I; ++i) {
+ if (fscanf(f, "%lf", &tmp) < 1) return false;
+ description(i, tmp);
+ }
+ }
+ return true;
}
ObjBase* create() const {
@@ -179,8 +221,7 @@ public:
}
char const* ctype() const {
- static char const* ptr = typeid(*this).name();
- return ptr;
+ return typeid(*this).name();
}
std::string type() const {
@@ -188,6 +229,6 @@ public:
}
};
-}
+} // meow
#endif // gra_FeaturePoint_H__
diff --git a/meowpp/gra/FeaturePointsDetector.h b/meowpp/gra/FeaturePointsDetector.h
index 415419a..858c66a 100644
--- a/meowpp/gra/FeaturePointsDetector.h
+++ b/meowpp/gra/FeaturePointsDetector.h
@@ -18,9 +18,9 @@ public:
virtual ~FeaturePointsDetector() { }
virtual std::vector<FeaturePoint<double, double> >
- detect(Bitmap<Pixel> const& __bitmap) const = 0;
+ detect(Bitmap<Pixel> const& bitmap) const = 0;
};
-}
+} // meow
#endif // gra_FeaturePointsDetector_H__
diff --git a/meowpp/gra/FeaturePointsDetector_Harris.h b/meowpp/gra/FeaturePointsDetector_Harris.h
index 25a46b2..11529f0 100644
--- a/meowpp/gra/FeaturePointsDetector_Harris.h
+++ b/meowpp/gra/FeaturePointsDetector_Harris.h
@@ -13,7 +13,6 @@
#include <vector>
-
namespace meow {
/*!
@@ -33,27 +32,26 @@ private:
double lightL_;
double featureG_;
size_t boundB_;
-
- Myself() {
- ratioK_ = 0.03;
- thresholdR_ = 0.001;
- sizeW_ = 2.0;
- noiseN_ = 3.0;
- lightL_ = 30.0;
- featureG_ = 3.0;
- boundB_ = 10u;
+
+ Myself():
+ ratioK_(0.03),
+ thresholdR_(0.001),
+ sizeW_(2.0),
+ noiseN_(3.0),
+ lightL_(30.0),
+ featureG_(3.0),
+ boundB_(10u) {
}
- ~Myself() {
+ Myself(Myself const& m):
+ ratioK_(m.ratioK_),
+ thresholdR_(m.thresholdR_),
+ sizeW_(m.sizeW_),
+ noiseN_(m.noiseN_),
+ lightL_(m.lightL_),
+ featureG_(m.featureG_),
+ boundB_(m.boundB_){
}
- Myself& copyFrom(Myself const& b) {
- ratioK_ = b.ratioK_ ;
- thresholdR_ = b.thresholdR_ ;
- sizeW_ = b.sizeW_ ;
- noiseN_ = b.noiseN_ ;
- lightL_ = b.lightL_ ;
- featureG_ = b.featureG_ ;
- boundB_ = b.boundB_ ;
- return *this;
+ ~Myself() {
}
};
@@ -62,19 +60,11 @@ public:
typedef FeaturePoint<double, double> MyFeaturePoint;
typedef std::vector<MyFeaturePoint> MyFeaturePoints;
//! @brief constructor 使用預設參數
- FPD_Harris(): self(true) {
- self()->ratioK_ = 0.03;
- self()->thresholdR_ = 0.001;
- self()->sizeW_ = 2.0;
- self()->noiseN_ = 3.0;
- self()->lightL_ = 30.0;
- self()->featureG_ = 3.0;
- self()->boundB_ = 10u;
+ FPD_Harris(): self() {
}
//! @brief constructor 參數複製自另一個 FeaturePointsDetector_Harris
- FPD_Harris(FPD_Harris const& fps): self(false) {
- self().copyFrom(fps.self);
+ FPD_Harris(FPD_Harris const& fps): self(fps.self, Self<Myself>::COPY_FROM) {
}
//! @brief 解構子
@@ -178,9 +168,11 @@ public:
MyFeaturePoints detect(Bitmap<Pixel> const& bmp) const {
Bitmap<Pixel> input = bmp;
+ // gradiance
Bitmap<Pixel> input_gx(input.gradianceX(0, self->noiseN_));
Bitmap<Pixel> input_gy(input.gradianceY(self->noiseN_, 0));
+ // get Matrix I for each pixel
Bitmap<double> Ixx(input.height(), input.width(), 0.0);
Bitmap<double> Iyy(input.height(), input.width(), 0.0);
Bitmap<double> Ixy(input.height(), input.width(), 0.0);
@@ -194,10 +186,12 @@ public:
}
}
+ // blur
Ixx.gaussianed(self->sizeW_, self->sizeW_);
Iyy.gaussianed(self->sizeW_, self->sizeW_);
Ixy.gaussianed(self->sizeW_, self->sizeW_);
+ // filter too flat or on edge
Bitmap<double> R(input.height(), input.width(), 0.0);
Bitmap<bool> good(input.height(), input.width(), false);
ssize_t b = self->boundB_;
@@ -211,6 +205,7 @@ public:
}
}
+ // find union neighbor
DisjointSet dsj(input.size());
ssize_t dy[2] = {0, 1};
ssize_t dx[2] = {1, 0};
@@ -227,6 +222,7 @@ public:
}
}
+ // find local maximum
std::vector<size_t> max_i(input.size());
for (size_t i = 0, I = input.size(); i < I; i++) {
max_i[i] = i;
@@ -239,6 +235,7 @@ public:
}
}
+ // blur before get description
input.gaussianed(self->featureG_, self->featureG_);
MyFeaturePoints ret;
@@ -253,7 +250,7 @@ public:
}
ssize_t dx[4] = {1, 0, -1, 0};
ssize_t dy[4] = {0, 1, 0, -1};
- std::vector<double> desc;
+ std::vector<double> desc; // description
for (ssize_t d = 1; d <= (ssize_t)self->boundB_; d++) {
std::vector<double> light;
size_t max_id = 0;
diff --git a/meowpp/gra/FeaturePointsMatch.h b/meowpp/gra/FeaturePointsMatch.h
index 8b05632..ffdbe53 100644
--- a/meowpp/gra/FeaturePointsMatch.h
+++ b/meowpp/gra/FeaturePointsMatch.h
@@ -3,32 +3,15 @@
#include "FeaturePoint.h"
+#include "../utility.h"
#include "../oo/ObjBase.h"
-#include <utility>
#include <cstdlib>
namespace meow {
-struct FeaturePointIndexPair {
- std::pair<size_t, size_t> from;
- std::pair<size_t, size_t> to;
-
- FeaturePointIndexPair() {
- }
- FeaturePointIndexPair(size_t ff, size_t fs,
- size_t tf, size_t ts) {
- from.first = ff;
- from.second = fs;
- to.first = tf;
- to.second = ts;
- }
- bool operator==(FeaturePointIndexPair const& p) const {
- return (from == p.from && to == p.to);
- }
-};
-
-typedef std::vector<FeaturePointIndexPair> FeaturePointIndexPairs;
+typedef PairToPair<size_t, size_t, size_t, size_t> FeaturePointIndexPair ;
+typedef std::vector<FeaturePointIndexPair> FeaturePointIndexPairs;
template<class Scalar, class Description>
class FeaturePointsMatch: public ObjBase {
@@ -58,6 +41,6 @@ public:
FeaturePointss const& fpss) const = 0;
};
-}
+} // meow
#endif // gra_FeaturePointsMatch_H__
diff --git a/meowpp/gra/FeaturePointsMatch_K_Match.h b/meowpp/gra/FeaturePointsMatch_K_Match.h
index ca47d27..f1fff12 100644
--- a/meowpp/gra/FeaturePointsMatch_K_Match.h
+++ b/meowpp/gra/FeaturePointsMatch_K_Match.h
@@ -1,13 +1,10 @@
#ifndef gra_FeaturePointsMatch_K_Match_H__
#define gra_FeaturePointsMatch_K_Match_H__
-#include "../dsa/VP_Tree.h"
-
#include "FeaturePointsMatch.h"
#include "../Self.h"
-
-
+#include "../dsa/VP_Tree.h"
#include "../oo/ObjBase.h"
#include <cstdlib>
@@ -19,20 +16,20 @@ class FeaturePointsMatch_K_Match:
public FeaturePointsMatch<Scalar, Description> {
# define FPMKM FeaturePointsMatch_K_Match
public:
- typedef std::vector<FeaturePoint<Scalar, Description> > FeaturePoints;
+ typedef std::vector<FeaturePoint<Scalar, Description> > FeaturePoints ;
typedef std::vector<FeaturePoints > FeaturePointss;
private:
struct Node {
- size_t id_;
- size_t index_;
- FeaturePointss const* ptr_;
+ size_t id_;
+ size_t index_;
+ FeaturePointss const* ptr_;
Node() {
}
Node(Node const& nd) {
- id_ = nd.id_;
+ id_ = nd. id_;
index_ = nd.index_;
- ptr_ = nd.ptr_;
+ ptr_ = nd. ptr_;
}
Node(size_t id, size_t index, FeaturePointss const* ptr) {
id_ = id;
@@ -48,30 +45,30 @@ private:
return (*ptr_)[id_][index_][id];
}
};
+
struct Myself {
size_t k_;
Myself() {
k_ = 1;
}
- ~Myself() {
+ Myself(size_t k): k_(k) {
}
- Myself& copyFrom(Myself const& m) {
- k_ = m.k_;
- return *this;
+ Myself(Myself const& m): k_(m.k_) {
+ }
+ ~Myself() {
}
};
Self<Myself> const self;
public:
- FPMKM(): self(true) {
+ FPMKM(): self() {
}
- FPMKM(FPMKM const& m): self(false) {
+ FPMKM(FPMKM const& m): self(m.self, Self<Myself>::COPY_FROM) {
self().copyFrom(m.self);
}
- FPMKM(size_t k): self(true) {
- self()->k_ = k;
+ FPMKM(size_t k): self(Myself(k)) {
}
~FPMKM() {
@@ -175,8 +172,7 @@ public:
}
char const* ctype() const {
- static char const* ptr = typeid(*this).name();
- return ptr;
+ return typeid(*this).name();
}
std::string type() const {
@@ -185,6 +181,6 @@ public:
# undef FPMKM
};
-}
+} // meow
#endif // gra_FeaturePointsMatch_K_Match_H__
diff --git a/meowpp/gra/IdentityPoints.h b/meowpp/gra/IdentityPoints.h
index c33eb55..1646bf7 100644
--- a/meowpp/gra/IdentityPoints.h
+++ b/meowpp/gra/IdentityPoints.h
@@ -2,12 +2,11 @@
#define gra_IdentityPoints_H__
#include "../Self.h"
-
#include "../math/Vector.h"
-
#include "../oo/ObjBase.h"
#include <map>
+#include <set>
#include <cstdlib>
@@ -24,45 +23,42 @@ public:
typedef typename std::map<ID, Vector<Scalar> > IdentityPointsMap;
typedef typename IdentityPointsMap:: iterator IdentityPointsMapIter;
typedef typename IdentityPointsMap::const_iterator IdentityPointsMapIterK;
-
+
private:
struct Myself {
IdentityPointsMap points_;
size_t dimension_;
-
+
Myself() {
dimension_ = 1;
}
- ~Myself() {
+ Myself(Myself const& m): points_(m.points_), dimension_(m.dimension_) {
}
- Myself& copyFrom(Myself const& b) {
- points_ = b.points_;
- dimension_ = b.dimension_;
- return *this;
+ ~Myself() {
}
};
-
+
Self<Myself> const self;
public:
/*!
* @brief constructor
*/
- IdentityPoints(): self(true) {
+ IdentityPoints(): self() {
}
-
+
/*!
* @brief constructor, 並且複製資料
*/
- IdentityPoints(IdentityPoints const& b): self(false) {
- copyFrom(b);
+ IdentityPoints(IdentityPoints const& b):
+ self(b.self, Self<Myself>::COPY_FROM) {
}
-
+
/*!
* @brief destructor
*/
~IdentityPoints() {
}
-
+
/*!
* @brief 複製資料
*/
@@ -70,7 +66,7 @@ public:
self().copyFrom(b.self);
return *this;
}
-
+
/*!
* @brief 參照
*/
@@ -78,42 +74,42 @@ public:
self().referenceFrom(b.self);
return *this;
}
-
+
/*!
* @brief 清除一切identity points
*/
void clear() {
self()->points_.clear();
}
-
+
/*!
* @brief 回傳有幾個identity points
*/
size_t size() const {
return self->points_.size();
}
-
+
/*!
* @brief 回傳是否沒有identity points
*/
bool empty() const {
return (size() == 0u);
}
-
+
/*!
* @brief 檢查某id是否有使用
*/
bool exist(ID const& id) const {
return (self->points_.find(id) != self->points_.end());
}
-
+
/*!
* @brief 回傳dimension
*/
size_t dimension() const {
return self->dimension_;
}
-
+
/*!
* @brief 設定dimension, 並且清空資料
*/
@@ -122,7 +118,7 @@ public:
clear();
return dimension();
}
-
+
/*!
* @brief 設定dimension, 並且針對每個identity point指定重設dimension
*/
@@ -134,14 +130,14 @@ public:
}
return dimension();
}
-
+
/*!
* @brief 取得所有identity points
*/
IdentityPointsMap const& identityPoints() const {
return self->points_;
}
-
+
/*!
* @brief 設定所有identity points
*/
@@ -149,7 +145,7 @@ public:
clear();
return identityPointsAdd(points);
}
-
+
/*!
* @brief 加入identity Points
*/
@@ -159,7 +155,7 @@ public:
}
return identityPoints();
}
-
+
/*!
* @brief 移除identity Points
*/
@@ -170,14 +166,14 @@ public:
}
return identityPoints();
}
-
+
/*!
* @brief 取得一個identity point
*/
Vector<Scalar> identityPoint(ID const& id) const {
return (exist(id) ? self->points_.find(id)->second : Vector<Scalar>());
}
-
+
/*!
* @brief 修改一個identity point
*/
@@ -187,7 +183,7 @@ public:
}
return identityPoint(id);
}
-
+
/*!
* @brief 新增一個identity point
*/
@@ -197,42 +193,99 @@ public:
}
return identityPoint(id);
}
-
+
/*!
* @brief 刪除一個identity point
*/
void identityPointDel(ID const& id) {
self()->points_.erase(id);
}
-
+
/*!
* @brief 取得一個identity point, non-constant reference
*/
Vector<Scalar>& identityPointGet(ID const& id) {
return self()->points_[id];
}
-
+
/*!
* @brief same as \c copyFrom(b)
*/
IdentityPoints& operator=(IdentityPoints const& b) {
return copyFrom(b);
}
-
+
/*! @brief 將資料寫入檔案
*
* @note 未完成
*/
bool write(FILE* f, bool bin, unsigned int fg) const {
- return false;
+ if (bin) {
+ long dim, ct;
+ if (fwrite(&(dim = dimension()), sizeof(dim), 1, f) < 1) return false;
+ if (fwrite(&(ct = size()), sizeof(ct), 1, f) < 1) return false;
+ for (IdentityPointsMapIterK
+ it = identityPoints().begin(), ed = identityPoints().end();
+ it != ed; ++it) {
+ double tmp;
+ if (fwrite(&(tmp = it->first), sizeof(tmp), 1, f) < 1) return false;
+ for (long i = 0; i < dim; ++i) {
+ if (fwrite(&(tmp = it->second(i)), sizeof(tmp), 1, f) < 1)
+ return false;
+ }
+ }
+ }
+ else {
+ if (fprintf(f, "%ld %lu\n", dimension(), size()) < 1) return false;
+ for (IdentityPointsMapIterK
+ it = identityPoints().begin(), ed = identityPoints().end();
+ it != ed; ++it) {
+ if (fprintf(f, "%f ", (double)it->first) < 1) return false;
+ for (long i = 0, I = dimension(); i < I; ++i) {
+ if (fprintf(f, "%f ", (double)it->second(i)) < 1) return false;
+ }
+ fprintf(f, "\n");
+ }
+ }
+ return true;
}
-
+
/*! @brief 將資料讀入
*
* @note 未完成
*/
bool read(FILE* f, bool bin, unsigned int fg) {
- return false;
+ long dim, ct;
+ if (bin) {
+ if (fread(&dim, sizeof(dim), 1, f) < 1) return false;
+ dimension(dim);
+ if (fread(&ct, sizeof(ct), 1, f) < 1) return false;
+ double id, tt;
+ Vector<Scalar> tmp(dim, 0);
+ for (int i = 0; i < ct; ++i) {
+ if (fread(&id, sizeof(id), 1, f) < 1) return false;
+ for (size_t j = 0, J = dim; j < J; ++j) {
+ if (fread(&tt, sizeof(tt), 1, f) < 1) return false;
+ tmp.entry(j, tt);
+ }
+ identityPointAdd((ID)id, tmp);
+ }
+ }
+ else {
+ if (fscanf(f, "%ld %ld", &dim, &ct) < 2) return false;
+ dimension(dim);
+ double id, tt;
+ Vector<Scalar> tmp(dim, 0);
+ for (int i = 0; i < ct; ++i) {
+ if (fscanf(f, "%lf", &id) < 1) return false;
+ for (int j = 0, J = dim; j < J; ++j) {
+ if (fscanf(f, "%lf", &tt) < 1) return false;
+ tmp.entry(j, tt);
+ }
+ identityPointAdd((ID)id, tmp);
+ }
+ }
+ return true;
}
/*! @brief new一個自己
@@ -242,7 +295,7 @@ public:
ObjBase* create() const {
return new IdentityPoints();
}
-
+
/*! @brief 複製資料
*
* 輸入型別是 \c ObjBase \c const*
@@ -255,16 +308,15 @@ public:
ObjBase* copyFrom(ObjBase const* b) {
return &(copyFrom(*(IdentityPoints*)b));
}
-
+
/*! @brief 回傳class的type
*
* @return \c char \c const\c * 形式的typename
*/
- char const* ctype() const{
- static char const* ptr = typeid(*this).name();
- return ptr;
+ char const* ctype() const {
+ return typeid(*this).name();
}
-
+
/*! @brief 回傳class的type
*
* @return \c std::string 形式的typename
diff --git a/meowpp/gra/Photo.h b/meowpp/gra/Photo.h
index 15768aa..1837727 100644
--- a/meowpp/gra/Photo.h
+++ b/meowpp/gra/Photo.h
@@ -1,8 +1,11 @@
#ifndef gra_Photo_H__
#define gra_Photo_H__
+#include "Bitmap.h"
+
#include "../Self.h"
+#include "../geo/Vectors.h"
#include "../math/utility.h"
#include "../math/Matrix.h"
#include "../math/Transformations.h"
@@ -20,7 +23,7 @@ namespace meow {
/*!
* @brief 底片
*
- * 基本上就是一個 \c Photo 加上 \c focal
+ * 基本上就是一個 \c Bitmap 加上 \c focal
*
* @author cat_leopard
*/
@@ -33,13 +36,9 @@ private:
PhotoProjection<double> proj_;
Myself(): proj_(3) {
}
- ~Myself() {
+ Myself(Myself const& b): bmp_(b.bmp_), c_(b.c_), proj_(b.proj_) {
}
- Myself& copyFrom(Myself const& b) {
- bmp_ .copyFrom(b. bmp_);
- c_ .copyFrom(b. c_);
- proj_.copyFrom(b.proj_);
- return *this;
+ ~Myself() {
}
};
@@ -57,7 +56,7 @@ public:
*
* focal 預設為 1
*/
- Photo(): self(true) {
+ Photo(): self() {
self()->proj_.focal(1.0);
}
@@ -68,8 +67,7 @@ public:
*
* @param [in] b 資料來源
*/
- Photo(Photo const& b): self(false) {
- copyFrom(b);
+ Photo(Photo const& b): self(b.self, Self<Myself>::COPY_FROM) {
}
/*!
@@ -79,7 +77,7 @@ public:
*
* @param [in] bmp 給定的圖片
*/
- Photo(Bitmap<Pixel> const& bmp): self(true) {
+ Photo(Bitmap<Pixel> const& bmp): self() {
reset(bmp);
}
@@ -91,7 +89,7 @@ public:
* @param [in] bmp 給定的圖片
* @param [in] f 給定的焦距
*/
- Photo(Bitmap<Pixel> const& bmp, double f): self(true) {
+ Photo(Bitmap<Pixel> const& bmp, double f): self() {
reset(bmp, f);
}
@@ -104,8 +102,7 @@ public:
* @param [in] f 給定的焦距
* @param [in] c 中心點作標
*/
- Photo(Bitmap<Pixel> const& bmp, double f, Vector2D<double> const& c):
- self(true) {
+ Photo(Bitmap<Pixel> const& bmp, double f, Vector2D<double> const& c): self() {
reset(bmp, f, c);
}
@@ -196,7 +193,7 @@ public:
* @return 新的 \c bitmap
*/
Bitmap<Pixel> const& bitmap(Bitmap<Pixel> const& bmp) {
- self()->bmp_ = bmp;
+ self()->bmp_.copyFrom(bmp);
return bitmap();
}
@@ -219,6 +216,23 @@ public:
}
/*!
+ * @brief 回傳相應的 photo projection
+ */
+ PhotoProjection<double> projection() const {
+ return self->proj_;
+ }
+
+ /*!
+ * @brief 設定 photo projection
+ */
+ PhotoProjection<double> projection(PhotoProjection<double> const& p) {
+ if (p.dimension() == 3) {
+ self()->proj_ = p;
+ }
+ return projection();
+ }
+
+ /*!
* @brief 取得照片中心點底片座標
*
* @return 一個二維vector
@@ -299,6 +313,7 @@ public:
* @return \c true/false
*/
bool inside(Vector3D<double> const& p) const {
+ if (p.z() > 0) return false;
return inside(Vector2D<double>(self->proj_.transformate(p.matrix())));
}
@@ -352,7 +367,18 @@ public:
* @note 未完成
*/
bool write(FILE* f, bool bin, unsigned int fg) const {
- return false;
+ if (bitmap().write(f, bin, fg) == false) return false;
+ if (bin) {
+ double tmp;
+ if (fwrite(&(tmp = center().x()), sizeof(tmp), 1, f) < 1) return false;
+ if (fwrite(&(tmp = center().y()), sizeof(tmp), 1, f) < 1) return false;
+ if (fwrite(&(tmp = focal()), sizeof(tmp), 1, f) < 1) return false;
+ }
+ else {
+ if (fprintf(f, "%f %f\n", center().x(), center().y()) < 2) return false;
+ if (fprintf(f, "%f\n", focal()) < 1) return false;
+ }
+ return true;
}
/*! @brief 將資料讀入
@@ -360,12 +386,23 @@ public:
* @note 未完成
*/
bool read(FILE* f, bool bin, unsigned int fg) {
- return false;
+ if (bitmapGet().read(f, bin, fg) == false) return false;
+ double tmp[3];
+ if (bin) {
+ if (fread(tmp, sizeof(double), 3, f) < 3) return false;
+ }
+ else {
+ if (fscanf(f, "%lf %lf %lf", tmp + 0, tmp + 1, tmp + 2) < 3) return false;
+ }
+ centerGet().x(tmp[0]);
+ centerGet().y(tmp[1]);
+ focal(tmp[2]);
+ return true;
}
/*! @brief new一個自己
*
- * @return 一個new出來的Bitmap<Pixel>
+ * @return 一個new出來的Photo<Pixel>
*/
ObjBase* create() const {
return new Photo();
@@ -389,8 +426,7 @@ public:
* @return \c char \c const\c * 形式的typename
*/
char const* ctype() const{
- static char const* ptr = typeid(*this).name();
- return ptr;
+ return typeid(*this).name();
}
/*! @brief 回傳class的type
@@ -402,6 +438,6 @@ public:
}
};
-}
+} // meow
#endif // gra_Photo_H__
diff --git a/meowpp/gra/WatchBall.h b/meowpp/gra/WatchBall.h
index c72e2a5..f3d2044 100644
--- a/meowpp/gra/WatchBall.h
+++ b/meowpp/gra/WatchBall.h
@@ -43,14 +43,13 @@ public:
/*!
* @brief constructor
*/
- WatchBall(): self(true) {
+ WatchBall(): self() {
}
/*!
* @brief copy constructor
*/
- WatchBall(WatchBall const& b): self(false) {
- copyFrom(b);
+ WatchBall(WatchBall const& b): self(b.self, Self<Myself>::COPY_FROM) {
}
/*!
@@ -176,12 +175,12 @@ public:
Bitmap<Pixel> ret(height, width, Pixel(0));
for (size_t i = 0; i < height; ++i) {
for (size_t j = 0; j < width; ++j) {
- double theta = (1.0 * j / width - 0.5) * 2 * PI;
+ double theta = (1.0 * j / width - 0.5) * 2 * PI;
double phi = asin(-(1.0 * i / height - 0.5) * 2.0);
ret.pixel(i, j, color(Vector3D<double>(
- sin(-theta) * cos(phi),
+ sin(theta) * cos(phi),
sin(phi),
- cos(-theta) * cos(phi)
+ -cos(theta) * cos(phi)
)));
}
}