aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/gra/FeaturePointsDetector_Harris.h
diff options
context:
space:
mode:
authorcathook <b01902109@csie.ntu.edu.tw>2014-06-01 13:56:57 +0800
committercathook <b01902109@csie.ntu.edu.tw>2014-06-01 13:56:57 +0800
commitd5052f1c296dddf51b3e83d59bf3e3c1952cb2d0 (patch)
tree16f7920c5079e0aefcf9509d2dbab59c464d42bd /meowpp/gra/FeaturePointsDetector_Harris.h
parentbd58f63900410ec4764031f2e6de2d75e91434b3 (diff)
downloadmeow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.gz
meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.zst
meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.zip
big chnage
Diffstat (limited to 'meowpp/gra/FeaturePointsDetector_Harris.h')
-rw-r--r--meowpp/gra/FeaturePointsDetector_Harris.h356
1 files changed, 356 insertions, 0 deletions
diff --git a/meowpp/gra/FeaturePointsDetector_Harris.h b/meowpp/gra/FeaturePointsDetector_Harris.h
new file mode 100644
index 0000000..25a46b2
--- /dev/null
+++ b/meowpp/gra/FeaturePointsDetector_Harris.h
@@ -0,0 +1,356 @@
+#ifndef gra_FeaturePointsDetector_Harris
+#define gra_FeaturePointsDetector_Harris
+
+#include "FeaturePointsDetector.h"
+
+#include "Bitmap.h"
+#include "FeaturePoint.h"
+#include "FeaturePointsDetector.h"
+
+#include "../dsa/DisjointSet.h"
+
+#include "../Self.h"
+
+#include <vector>
+
+
+namespace meow {
+
+/*!
+ * @brief Harris corner detect
+ *
+ * @author cat_leopard
+ */
+template<class Pixel>
+class FeaturePointsDetector_Harris: public FeaturePointsDetector<Pixel> {
+# define FPD_Harris FeaturePointsDetector_Harris
+private:
+ struct Myself {
+ double ratioK_;
+ double thresholdR_;
+ double sizeW_;
+ double noiseN_;
+ 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() {
+ }
+ 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;
+ }
+ };
+
+ Self<Myself> const self;
+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;
+ }
+
+ //! @brief constructor 參數複製自另一個 FeaturePointsDetector_Harris
+ FPD_Harris(FPD_Harris const& fps): self(false) {
+ self().copyFrom(fps.self);
+ }
+
+ //! @brief 解構子
+ ~FPD_Harris() {
+ }
+
+ //! @brief 複製
+ FPD_Harris& copyFrom(FPD_Harris const& fps) {
+ self().copyFrom(fps.self);
+ return *this;
+ }
+
+ //! @brief 參照
+ FPD_Harris& referenceFrom(FPD_Harris const& fps) {
+ self().referenceFrom(fps.self);
+ return *this;
+ }
+
+ //! @brief K
+ double paramK() const {
+ return self->ratioK_;
+ }
+
+ //! @brief R
+ double paramR() const {
+ return self->thresholdR_;
+ }
+
+ //! @brief W
+ double paramW() const {
+ return self->sizeW_;
+ }
+
+ //! @brief N
+ double paramN() const {
+ return self->noiseN_;
+ }
+
+ //! @brief G
+ double paramG() const {
+ return self->featureG_;
+ }
+
+ //! @brief L
+ double paramL() const {
+ return self->lightL_;
+ }
+
+ //! @brief bound
+ size_t paramB() const {
+ return self->boundB_;
+ }
+
+ //! @brief K
+ double paramK(double k) {
+ self()->ratioK_ = k;
+ return paramK();
+ }
+
+ //! @brief R
+ double paramR(double r) {
+ self()->thresholdR_ = r;
+ return paramR();
+ }
+
+ //! @brief W
+ double paramW(double w) {
+ self()->sizeW_ = w;
+ return paramW();
+ }
+
+ //! @brief N
+ double paramN(double n){
+ self()->noiseN_ = n;
+ return paramN();
+ }
+
+ //! @brief L
+ double paramL(double l) {
+ self()->lightL_ = l;
+ return paramL();
+ }
+
+ //! @brief G
+ double paramG(double g) {
+ self()->featureG_ = g;
+ return paramG();
+ }
+
+ //! @brief B
+ size_t paramB(size_t b) {
+ self()->boundB_ = b;
+ return paramB();
+ }
+
+ /*! @brief 找出特徵點
+ *
+ * @param [in] bmp 要抓特徵點的點陣圖
+ * @return \c std::vector<FeaturePoint<double,double>> 型態的一堆特徵點
+ */
+ MyFeaturePoints detect(Bitmap<Pixel> const& bmp) const {
+ Bitmap<Pixel> input = bmp;
+
+ Bitmap<Pixel> input_gx(input.gradianceX(0, self->noiseN_));
+ Bitmap<Pixel> input_gy(input.gradianceY(self->noiseN_, 0));
+
+ 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);
+ for (ssize_t y = 0, Y = input.height(); y < Y; y++) {
+ for (ssize_t x = 0, X = input.width(); x < X; x++) {
+ Pixel gx(input_gx(y, x));
+ Pixel gy(input_gy(y, x));
+ Ixx.pixel(y, x, gx * gx);
+ Iyy.pixel(y, x, gy * gy);
+ Ixy.pixel(y, x, gx * gy);
+ }
+ }
+
+ Ixx.gaussianed(self->sizeW_, self->sizeW_);
+ Iyy.gaussianed(self->sizeW_, self->sizeW_);
+ Ixy.gaussianed(self->sizeW_, self->sizeW_);
+
+ Bitmap<double> R(input.height(), input.width(), 0.0);
+ Bitmap<bool> good(input.height(), input.width(), false);
+ ssize_t b = self->boundB_;
+ for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) {
+ for (ssize_t x = b, X = -b + input.width(); x < X; x++) {
+ double det = Ixx(y, x) * Iyy(y, x) - squ(Ixy(y, x));
+ double tra = Ixx(y, x) + Iyy(y, x);
+ double r = det - self->ratioK_ * squ(tra);
+ R.pixel(y, x, r);
+ good.pixel(y, x, (r >= self->thresholdR_));
+ }
+ }
+
+ DisjointSet dsj(input.size());
+ ssize_t dy[2] = {0, 1};
+ ssize_t dx[2] = {1, 0};
+ for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) {
+ for (ssize_t x = b, X = -b + input.width(); x < X; x++) {
+ if(good.pixel((size_t)y, (size_t)x)){
+ for (size_t k = 0; k < 2u; k++) {
+ if (good.pixel((size_t)(y + dy[k]), (size_t)(x + dx[k]))) {
+ dsj.merge( y * input.width() + x,
+ (y + dy[k]) * input.width() + (x + dx[k]));
+ }
+ }
+ }
+ }
+ }
+
+ std::vector<size_t> max_i(input.size());
+ for (size_t i = 0, I = input.size(); i < I; i++) {
+ max_i[i] = i;
+ }
+ for (size_t i = 0, I = input.size(); i < I; i++) {
+ size_t ri = dsj.root(i);
+ if (R.pixel( i / input.width(), i % input.width()) >
+ R.pixel(max_i[ri] / input.width(), max_i[ri] % input.width())) {
+ max_i[ri] = i;
+ }
+ }
+
+ input.gaussianed(self->featureG_, self->featureG_);
+
+ MyFeaturePoints ret;
+ for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) {
+ for (ssize_t x = b, X = -b + input.width(); x < X; x++) {
+ if (!good.pixel((size_t)y, (size_t)x)) {
+ continue;
+ }
+ size_t i = y * input.width() + x;
+ if (max_i[dsj.root(i)] != i) {
+ continue;
+ }
+ ssize_t dx[4] = {1, 0, -1, 0};
+ ssize_t dy[4] = {0, 1, 0, -1};
+ std::vector<double> desc;
+ for (ssize_t d = 1; d <= (ssize_t)self->boundB_; d++) {
+ std::vector<double> light;
+ size_t max_id = 0;
+ size_t x0 = x - d, y0 = y - d;
+ for (size_t k = 0; k < 4; k++) {
+ for (ssize_t n = 0;
+ n < (ssize_t)b * 2;
+ n++, x0 += dx[k], y0 += dy[k]){
+ Pixel diff = input.pixel(y0, x0) - input.pixel(y, x) * 0.2;
+ light.push_back(diff * diff * self->lightL_);
+ if (light[max_id] < light[-1 + light.size()]) {
+ max_id = -1 + (ssize_t)light.size();
+ }
+ }
+ }
+ for (ssize_t n = 0, N = light.size(); n < N; n++) {
+ desc.push_back((max_id + n) % N);
+ desc.push_back(light[(max_id + n) % N]);
+ }
+ }
+ MyFeaturePoint now(2, desc.size());
+ now.position(0, x);
+ now.position(1, y);
+ now.description(Vector<double>(desc));
+ ret.push_back(now);
+ }
+ }
+ return ret;
+ }
+
+ //! @brief same as \c copyFrom(fps)
+ FPD_Harris& operator=(FPD_Harris const& fps) {
+ return copyFrom(fps);
+ }
+
+ //! @brief same as \c detect(bmp)
+ MyFeaturePoints operator()(Bitmap<Pixel> const& bmp) const {
+ return detect(bmp);
+ }
+
+ /*! @brief 寫到檔案裡
+ *
+ * 未完成
+ */
+ bool write(FILE* f, bool bin, unsigned int fg) const {
+ // TODO
+ return false;
+ }
+
+ /*! @brief 將資料讀入
+ *
+ * 未完成
+ */
+ bool read (FILE* f, bool bin, unsigned int fg) {
+ // TODO
+ return false;
+ }
+
+ /*! @brief new一個自己
+ *
+ * @return 一個new出來的FeaturePointsDetector_Harris<Pixel>
+ */
+ ObjBase* create() const {
+ return (ObjBase*)new FPD_Harris<Pixel>();
+ }
+
+ /*! @brief 複製資料
+ *
+ * 輸入型別是 \c ObjBase \c const*
+ * 這裡假設實體其實是 \c FeaturePointsDetector_Harris.
+ * 事實上這個method就只是幫忙轉型然後呼叫原本的\c copyFrom
+ *
+ * @param [in] b 資料來源
+ * @return this
+ */
+ ObjBase* copyFrom(ObjBase const* b) {
+ return &(copyFrom(*(FPD_Harris const*)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());
+ }
+# undef FPD_Harris
+};
+
+}
+
+#endif // gra_FeaturePointsDetector_Harris