diff options
Diffstat (limited to 'meowpp/gra/FeaturePointsDetector_Harris.h')
-rw-r--r-- | meowpp/gra/FeaturePointsDetector_Harris.h | 108 |
1 files changed, 46 insertions, 62 deletions
diff --git a/meowpp/gra/FeaturePointsDetector_Harris.h b/meowpp/gra/FeaturePointsDetector_Harris.h index 8f0f8fe..fb3e2be 100644 --- a/meowpp/gra/FeaturePointsDetector_Harris.h +++ b/meowpp/gra/FeaturePointsDetector_Harris.h @@ -8,10 +8,12 @@ #include "FeaturePointsDetector.h" #include "../dsa/DisjointSet.h" +#include "../math/utility.h" #include "../Self.h" #include <vector> +#include <algorithm> namespace meow { @@ -56,9 +58,10 @@ private: }; Self<Myself> const self; -public: + typedef FeaturePoint<double, double> MyFeaturePoint; typedef std::vector<MyFeaturePoint> MyFeaturePoints; +public: //! @brief constructor 使用預設參數 FPD_Harris(): self() { } @@ -160,6 +163,10 @@ public: return paramB(); } + size_t descriptionDimension() const { + return (squ(self->boundB_ * 2 + 1) - 1) * 2; + } + /*! @brief 找出特徵點 * * @param [in] bmp 要抓特徵點的點陣圖 @@ -172,60 +179,45 @@ public: 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); - for (ssize_t y = 0, Y = input.height(); y < Y; y++) { + // get Matrix Ixx, Iyy, Ixy for each pixel + Bitmap<Vector3D<double> > Ixys(input.height(), input.width(), + Vector3D<double>(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); + Ixys.pixel(y, x, Vector3D<double>(gx * gx, gy * gy, gx * gy)); } - } - // blur - Ixx.gaussianed(self->sizeW_, self->sizeW_); - Iyy.gaussianed(self->sizeW_, self->sizeW_); - Ixy.gaussianed(self->sizeW_, self->sizeW_); + // blur for window size + Ixys.gaussianed(self->sizeW_, self->sizeW_); input_gx.clear(); input_gy.clear(); // 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_; - 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); + for (ssize_t y = 0, Y = input.height(); y < Y; y++) + for (ssize_t x = 0, X = input.width(); x < X; x++) { + double det = Ixys(y, x)(0) * Ixys(y, x)(1) - squ(Ixys(y, x)(2)); + double tra = Ixys(y, x)(0) + Ixys(y, x)(1); double r = det - self->ratioK_ * squ(tra); R.pixel(y, x, r); good.pixel(y, x, (r >= self->thresholdR_)); } - } - Ixx.clear(); - Iyy.clear(); - Ixy.clear(); + Ixys.clear(); // find union neighbor 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]))) { + for (ssize_t y = 0, Y = input.height(); y + 1 < Y; y++) + for (ssize_t x = 0, X = input.width(); x + 1 < 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])); - } - } - } - } - } // find local maximum std::vector<size_t> max_i(input.size()); @@ -243,46 +235,38 @@ public: // blur before get description input.gaussianed(self->featureG_, self->featureG_); + // Ignore side + ssize_t b = std::max<int>(std::max<int>(self->boundB_, + 2 * self->sizeW_), + 2 * self->noiseN_); MyFeaturePoints ret; - for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) { + Vector<double> desc(descriptionDimension(), 0.0); // description + 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; - } + 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; // description - for (ssize_t d = 1; d <= (ssize_t)self->boundB_; d++) { + size_t ct = 0; + 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]){ + size_t max_id = 0, x0 = x - d, y0 = y - d; + for (size_t k = 0; k < 4; k++) + for (ssize_t n = 0; n < (ssize_t)d * 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(); - } + if (light[max_id] < light[(ssize_t)light.size() - 1]) + max_id = (ssize_t)light.size() - 1; } - } 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]); + desc.scalar(ct++, (max_id + n) % N ); + desc.scalar(ct++, 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); + ret.push_back(MyFeaturePoint(Vector2D<double>(x, y).matrix(), desc)); } - } return ret; } @@ -353,6 +337,6 @@ public: # undef FPD_Harris }; -} +} // meow #endif // gra_FeaturePointsDetector_Harris |