Templates -- Meow  204.13.18
A C++ template contains kinds of interesting classes and functions
FeaturePointsDetector_Harris.h
Go to the documentation of this file.
1 #ifndef gra_FeaturePointsDetector_Harris
2 #define gra_FeaturePointsDetector_Harris
3 
5 
6 #include "Bitmap.h"
7 #include "FeaturePoint.h"
9 
10 #include "../dsa/DisjointSet.h"
11 
12 #include "../Self.h"
13 
14 #include <vector>
15 
16 namespace meow {
17 
23 template<class Pixel>
25 # define FPD_Harris FeaturePointsDetector_Harris
26 private:
27  struct Myself {
28  double ratioK_;
29  double thresholdR_;
30  double sizeW_;
31  double noiseN_;
32  double lightL_;
33  double featureG_;
34  size_t boundB_;
35 
36  Myself():
37  ratioK_(0.03),
38  thresholdR_(0.001),
39  sizeW_(2.0),
40  noiseN_(3.0),
41  lightL_(30.0),
42  featureG_(3.0),
43  boundB_(10u) {
44  }
45  Myself(Myself const& m):
46  ratioK_(m.ratioK_),
47  thresholdR_(m.thresholdR_),
48  sizeW_(m.sizeW_),
49  noiseN_(m.noiseN_),
50  lightL_(m.lightL_),
51  featureG_(m.featureG_),
52  boundB_(m.boundB_){
53  }
54  ~Myself() {
55  }
56  };
57 
58  Self<Myself> const self;
59 public:
61  typedef std::vector<MyFeaturePoint> MyFeaturePoints;
63  FPD_Harris(): self() {
64  }
65 
67  FPD_Harris(FPD_Harris const& fps): self(fps.self, Self<Myself>::COPY_FROM) {
68  }
69 
72  }
73 
76  self().copyFrom(fps.self);
77  return *this;
78  }
79 
82  self().referenceFrom(fps.self);
83  return *this;
84  }
85 
87  double paramK() const {
88  return self->ratioK_;
89  }
90 
92  double paramR() const {
93  return self->thresholdR_;
94  }
95 
97  double paramW() const {
98  return self->sizeW_;
99  }
100 
102  double paramN() const {
103  return self->noiseN_;
104  }
105 
107  double paramG() const {
108  return self->featureG_;
109  }
110 
112  double paramL() const {
113  return self->lightL_;
114  }
115 
117  size_t paramB() const {
118  return self->boundB_;
119  }
120 
122  double paramK(double k) {
123  self()->ratioK_ = k;
124  return paramK();
125  }
126 
128  double paramR(double r) {
129  self()->thresholdR_ = r;
130  return paramR();
131  }
132 
134  double paramW(double w) {
135  self()->sizeW_ = w;
136  return paramW();
137  }
138 
140  double paramN(double n){
141  self()->noiseN_ = n;
142  return paramN();
143  }
144 
146  double paramL(double l) {
147  self()->lightL_ = l;
148  return paramL();
149  }
150 
152  double paramG(double g) {
153  self()->featureG_ = g;
154  return paramG();
155  }
156 
158  size_t paramB(size_t b) {
159  self()->boundB_ = b;
160  return paramB();
161  }
162 
169  Bitmap<Pixel> input = bmp;
170 
171  // gradiance
172  Bitmap<Pixel> input_gx(input.gradianceX(0, self->noiseN_));
173  Bitmap<Pixel> input_gy(input.gradianceY(self->noiseN_, 0));
174 
175  // get Matrix I for each pixel
176  Bitmap<double> Ixx(input.height(), input.width(), 0.0);
177  Bitmap<double> Iyy(input.height(), input.width(), 0.0);
178  Bitmap<double> Ixy(input.height(), input.width(), 0.0);
179  for (ssize_t y = 0, Y = input.height(); y < Y; y++) {
180  for (ssize_t x = 0, X = input.width(); x < X; x++) {
181  Pixel gx(input_gx(y, x));
182  Pixel gy(input_gy(y, x));
183  Ixx.pixel(y, x, gx * gx);
184  Iyy.pixel(y, x, gy * gy);
185  Ixy.pixel(y, x, gx * gy);
186  }
187  }
188 
189  // blur
190  Ixx.gaussianed(self->sizeW_, self->sizeW_);
191  Iyy.gaussianed(self->sizeW_, self->sizeW_);
192  Ixy.gaussianed(self->sizeW_, self->sizeW_);
193 
194  // filter too flat or on edge
195  Bitmap<double> R(input.height(), input.width(), 0.0);
196  Bitmap<bool> good(input.height(), input.width(), false);
197  ssize_t b = self->boundB_;
198  for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) {
199  for (ssize_t x = b, X = -b + input.width(); x < X; x++) {
200  double det = Ixx(y, x) * Iyy(y, x) - squ(Ixy(y, x));
201  double tra = Ixx(y, x) + Iyy(y, x);
202  double r = det - self->ratioK_ * squ(tra);
203  R.pixel(y, x, r);
204  good.pixel(y, x, (r >= self->thresholdR_));
205  }
206  }
207 
208  // find union neighbor
209  DisjointSet dsj(input.size());
210  ssize_t dy[2] = {0, 1};
211  ssize_t dx[2] = {1, 0};
212  for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) {
213  for (ssize_t x = b, X = -b + input.width(); x < X; x++) {
214  if(good.pixel((size_t)y, (size_t)x)){
215  for (size_t k = 0; k < 2u; k++) {
216  if (good.pixel((size_t)(y + dy[k]), (size_t)(x + dx[k]))) {
217  dsj.merge( y * input.width() + x,
218  (y + dy[k]) * input.width() + (x + dx[k]));
219  }
220  }
221  }
222  }
223  }
224 
225  // find local maximum
226  std::vector<size_t> max_i(input.size());
227  for (size_t i = 0, I = input.size(); i < I; i++) {
228  max_i[i] = i;
229  }
230  for (size_t i = 0, I = input.size(); i < I; i++) {
231  size_t ri = dsj.root(i);
232  if (R.pixel( i / input.width(), i % input.width()) >
233  R.pixel(max_i[ri] / input.width(), max_i[ri] % input.width())) {
234  max_i[ri] = i;
235  }
236  }
237 
238  // blur before get description
239  input.gaussianed(self->featureG_, self->featureG_);
240 
241  MyFeaturePoints ret;
242  for (ssize_t y = b, Y = -b + input.height(); y < Y; y++) {
243  for (ssize_t x = b, X = -b + input.width(); x < X; x++) {
244  if (!good.pixel((size_t)y, (size_t)x)) {
245  continue;
246  }
247  size_t i = y * input.width() + x;
248  if (max_i[dsj.root(i)] != i) {
249  continue;
250  }
251  ssize_t dx[4] = {1, 0, -1, 0};
252  ssize_t dy[4] = {0, 1, 0, -1};
253  std::vector<double> desc; // description
254  for (ssize_t d = 1; d <= (ssize_t)self->boundB_; d++) {
255  std::vector<double> light;
256  size_t max_id = 0;
257  size_t x0 = x - d, y0 = y - d;
258  for (size_t k = 0; k < 4; k++) {
259  for (ssize_t n = 0;
260  n < (ssize_t)b * 2;
261  n++, x0 += dx[k], y0 += dy[k]){
262  Pixel diff = input.pixel(y0, x0) - input.pixel(y, x) * 0.2;
263  light.push_back(diff * diff * self->lightL_);
264  if (light[max_id] < light[-1 + light.size()]) {
265  max_id = -1 + (ssize_t)light.size();
266  }
267  }
268  }
269  for (ssize_t n = 0, N = light.size(); n < N; n++) {
270  desc.push_back((max_id + n) % N);
271  desc.push_back(light[(max_id + n) % N]);
272  }
273  }
274  MyFeaturePoint now(2, desc.size());
275  now.position(0, x);
276  now.position(1, y);
277  now.description(Vector<double>(desc));
278  ret.push_back(now);
279  }
280  }
281  return ret;
282  }
283 
286  return copyFrom(fps);
287  }
288 
291  return detect(bmp);
292  }
293 
298  bool write(FILE* f, bool bin, unsigned int fg) const {
299  // TODO
300  return false;
301  }
302 
307  bool read (FILE* f, bool bin, unsigned int fg) {
308  // TODO
309  return false;
310  }
311 
316  ObjBase* create() const {
317  return (ObjBase*)new FPD_Harris<Pixel>();
318  }
319 
329  ObjBase* copyFrom(ObjBase const* b) {
330  return &(copyFrom(*(FPD_Harris const*)b));
331  }
332 
337  char const* ctype() const {
338  return typeid(*this).name();
339  }
340 
345  std::string type() const {
346  return std::string(ctype());
347  }
348 # undef FPD_Harris
349 };
350 
351 }
352 
353 #endif // gra_FeaturePointsDetector_Harris
Bitmap< Pixel > gradianceY(double radiusY, double radiusX) const
回傳對y偏微分
Definition: Bitmap.h:314
size_t height() const
回傳高度
Definition: Bitmap.h:146
char const * ctype() const
回傳class的type
FPD_Harris & referenceFrom(FPD_Harris const &fps)
參照
MyFeaturePoints detect(Bitmap< Pixel > const &bmp) const
找出特徵點
std::string type() const
回傳class的type
ObjBase * copyFrom(ObjBase const *b)
複製資料
用來維護一堆互斥集的資訊
Definition: DisjointSet.h:25
二維點陣資料
Definition: Bitmap.h:25
MyFeaturePoints operator()(Bitmap< Pixel > const &bmp) const
same as detect(bmp)
FeaturePoint< double, double > MyFeaturePoint
Pixel pixel(size_t y, size_t x) const
取得 (y, x) 的pixel
Definition: Bitmap.h:205
size_t width() const
回傳寬度
Definition: Bitmap.h:153
一切物件的Base, 並要求每個物件都要有read, write, create, ... 等功能
Definition: ObjBase.h:15
vector
Definition: Vector.h:19
size_t merge(size_t a, size_t b)
合併
Definition: DisjointSet.h:128
FPD_Harris(FPD_Harris const &fps)
constructor 參數複製自另一個 FeaturePointsDetector_Harris
FPD_Harris & operator=(FPD_Harris const &fps)
same as copyFrom(fps)
size_t size() const
回傳高度乘以寬度
Definition: Bitmap.h:160
bool read(FILE *f, bool bin, unsigned int fg)
將資料讀入
Bitmap gradianceX(double radiusY, double radiusX) const
回傳對x偏微分
Definition: Bitmap.h:291
std::vector< MyFeaturePoint > MyFeaturePoints
FPD_Harris()
constructor 使用預設參數
FPD_Harris & copyFrom(FPD_Harris const &fps)
複製
ObjBase * create() const
new一個自己
A little class use for packing the data part of another class. With this technique, it can achieve Copy-On-Write(COR) mechanism at background and have a reference mechanism which much more flexible then the one C++ has.
Definition: Self.h:104
Vector< Scalar > const & position() const
回傳position
Definition: FeaturePoint.h:73
bool write(FILE *f, bool bin, unsigned int fg) const
寫到檔案裡
Bitmap & gaussianed(double radiusY, double radiusX)
把自己高斯模糊
Definition: Bitmap.h:280
T squ(T const &x)
x*x
Definition: utility.h:67