PICCANTE  0.4
The hottest HDR imaging library!
general_corner_detector.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_FEATURES_MATCHING_GENERAL_CORNER_DETECTOR_HPP
19 #define PIC_FEATURES_MATCHING_GENERAL_CORNER_DETECTOR_HPP
20 
21 #include "../image.hpp"
22 #include "../util/string.hpp"
23 #include "../util/string.hpp"
24 
25 #ifndef PIC_DISABLE_EIGEN
26 
27 #ifndef PIC_EIGEN_NOT_BUNDLED
28  #include "../externals/Eigen/Dense"
29 #else
30  #include <Eigen/Dense>
31 #endif
32 
33 #endif
34 
35 namespace pic {
36 
37 #ifndef PIC_DISABLE_EIGEN
38 
43 {
44 protected:
46  bool bLum;
47 
48  static bool scD (Eigen::Vector3f i, Eigen::Vector3f j)
49  {
50  return (i[2] > j [2]);
51  }
52 
53  static bool scA (Eigen::Vector3f i, Eigen::Vector3f j)
54  {
55  return (i[2] < j [2]);
56  }
57 
58 public:
63  {
64  lum = NULL;
65  bLum = false;
66  }
67 
69  {
70  }
71 
77  virtual void execute(Image *img, std::vector< Eigen::Vector2f > *corners)
78  {
79 
80  }
81 
89  Image *getCornersImage(std::vector< Eigen::Vector2f > *corners,
90  Image *imgOut, unsigned int width, unsigned int height, bool bColor)
91  {
92  if(corners == NULL) {
93  return imgOut;
94  }
95 
96  if(imgOut == NULL) {
97  if((width < 1) || (height < 1)){
98  return NULL;
99  }
100 
101  imgOut = new Image(width, height, 1);
102  }
103 
104  imgOut->setZero();
105 
106  for(unsigned int i = 0; i < corners->size(); i++) {
107  int x = int((*corners)[i][0]);
108  int y = int((*corners)[i][1]);
109 
110  if(bColor) {
111  (*imgOut)(x, y)[0] = 1.0f;
112  } else {
113  (*imgOut)(x, y)[0] = (*corners)[i][2];
114  }
115  }
116 
117  return imgOut;
118  }
119 
127  static void sortCornersAndTransfer(std::vector< Eigen::Vector3f > *corners,
128  std::vector< Eigen::Vector2f > *cornersOut,
129  int nBestPoints = -1,
130  bool bDescend = true)
131  {
132  sortCorners(corners, bDescend);
133 
134  int a, b;
135 
136  int n = int(corners->size());
137  if(nBestPoints < 0) {
138  a = 0;
139  b = n;
140  } else {
141  if(bDescend) {
142  a = 0;
143  b = MIN(nBestPoints, n);
144  } else {
145  b = MIN(int(corners->size()), n);
146  a = MAX(b - nBestPoints, 0);
147  }
148  }
149 
150  for(int i = a; i < b; i++) {
151  Eigen::Vector3f tmp = corners->at(i);
152  Eigen::Vector2f p;
153  p[0] = tmp[0];
154  p[1] = tmp[1];
155 
156  cornersOut->push_back(p);
157  }
158  }
159 
164  static void sortCorners(std::vector< Eigen::Vector3f > *corners, bool bDescend = true)
165  {
166  if(bDescend) {
167  std::sort(corners->begin(), corners->end(), scD);
168  } else {
169  std::sort(corners->begin(), corners->end(), scA);
170  }
171  }
172 
178  static std::string exportToString(std::vector< Eigen::Vector2f > *corners)
179  {
180  std::string out = "[";
181  auto n = corners->size();
182 
183  for(auto i = 0; i < (n - 1); i++) {
184  out += fromNumberToString(corners->at(i)[0]) + " ";
185  out += fromNumberToString(corners->at(i)[1]) + "; ";
186  }
187  out += fromNumberToString(corners->at(n - 1)[0]) + " ";
188  out += fromNumberToString(corners->at(n - 1)[1]) + "]";
189  return out;
190  }
191 
195  static void removeClosestCorners(std::vector< Eigen::Vector2f > *corners,
196  std::vector< Eigen::Vector2f > *out,
197  float threshold,
198  int max_limit)
199  {
200  int n = MIN(int(corners->size()), max_limit);
201  bool *processed = new bool [n];
202  memset(processed, 0, sizeof(bool) * n);
203 
204  for(int i = 0; i < n; i++) {
205  //find the closest
206  if(!processed[i]) {
207  processed[i] = true;
208 
209  std::vector< int > indices;
210  for(int j = 0; j < n; j++) {
211  if(j != i) {
212  continue;
213  }
214 
215  if(!processed[j]) {
216  float dx = (*corners)[j][0] - (*corners)[i][0];
217  float dy = (*corners)[j][1] - (*corners)[i][1];
218  float dist = sqrtf(dx * dx + dy * dy);
219 
220  if(dist < threshold) {
221  //processed[j] = true;
222  indices.push_back(j);
223  }
224  }
225  }
226 
227  auto n_i = indices.size();
228  Eigen::Vector2f point;
229 
230  if(n_i > 0) {
231  point[0] = (*corners)[i][0];
232  point[1] = (*corners)[i][1];
233  int point_c = 1;
234 
235  for(auto j = 0; j < indices.size(); j++) {
236  auto k = indices[j];
237  if(!processed[k]) {
238  processed[k] = true;
239  point[0] += (*corners)[k][0];
240  point[1] += (*corners)[k][1];
241  point_c++;
242  }
243  }
244 
245  point[0] /= float(point_c);
246  point[1] /= float(point_c);
247  } else {
248  point[0] = (*corners)[i][0];
249  point[1] = (*corners)[i][1];
250  }
251  out->push_back(point);
252  }
253  }
254 
255  delete[] processed;
256  }
257 
262  static void test(GeneralCornerDetector *gcd)
263  {
264  if(gcd == NULL){
265  return;
266  }
267 
268  Image full_image(1, 512, 512, 3);
269  full_image.setZero();
270 
271  Image quad(1, 128, 128, 3);
272  quad = 1.0f;
273 
274  full_image.copySubImage(&quad, 192, 192);
275 
276  std::vector< Eigen::Vector2f > corners;
277  gcd->execute(&full_image, &corners);
278 
279  printf("\n Corner Detector Test:\n");
280 
281  for(unsigned int i = 0; i < corners.size(); i++) {
282  printf("X: %f Y: %f\n", corners[i][0], corners[i][1]);
283  }
284 
285  printf("\n");
286 
287  Image *img_corners = gcd->getCornersImage(&corners, NULL, 512, 512, true);
288  img_corners->Write("general_corner_test_image.hdr");
289  }
290 };
291 
292 #endif
293 
294 } // end namespace pic
295 
296 #endif /* PIC_FEATURES_MATCHING_GENERAL_CORNER_DETECTOR_HPP */
297 
std::string fromNumberToString(T num)
fromNumberToString converts a number into a string.
Definition: string.hpp:102
void setZero()
setZero sets data to 0.0f.
static void removeClosestCorners(std::vector< Eigen::Vector2f > *corners, std::vector< Eigen::Vector2f > *out, float threshold, int max_limit)
removeClosestCorners
Definition: general_corner_detector.hpp:195
GeneralCornerDetector()
GeneralCornerDetector.
Definition: general_corner_detector.hpp:62
static std::string exportToString(std::vector< Eigen::Vector2f > *corners)
exportToString
Definition: general_corner_detector.hpp:178
Image * getCornersImage(std::vector< Eigen::Vector2f > *corners, Image *imgOut, unsigned int width, unsigned int height, bool bColor)
getCornersImage
Definition: general_corner_detector.hpp:89
~GeneralCornerDetector()
Definition: general_corner_detector.hpp:68
static void test(GeneralCornerDetector *gcd)
test
Definition: general_corner_detector.hpp:262
static bool scD(Eigen::Vector3f i, Eigen::Vector3f j)
Definition: general_corner_detector.hpp:48
static void sortCorners(std::vector< Eigen::Vector3f > *corners, bool bDescend=true)
sortCorners
Definition: general_corner_detector.hpp:164
The GeneralCornerDetector class.
Definition: general_corner_detector.hpp:42
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
bool bLum
Definition: general_corner_detector.hpp:46
Definition: bilateral_separation.hpp:25
Image * lum
Definition: general_corner_detector.hpp:45
#define MAX(a, b)
Definition: math.hpp:73
void copySubImage(Image *imgIn, int startX, int startY)
copySubImage copies imgIn in the current image. The current image is written from (startX...
virtual void execute(Image *img, std::vector< Eigen::Vector2f > *corners)
execute
Definition: general_corner_detector.hpp:77
bool Write(std::string nameFile, LDR_type typeWrite, int writerCounter)
Write saves an Image into a file on the disk.
static bool scA(Eigen::Vector3f i, Eigen::Vector3f j)
Definition: general_corner_detector.hpp:53
static void sortCornersAndTransfer(std::vector< Eigen::Vector3f > *corners, std::vector< Eigen::Vector2f > *cornersOut, int nBestPoints=-1, bool bDescend=true)
sortCornersAndTransfer
Definition: general_corner_detector.hpp:127