opencv-ffi 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +15 -0
- data/README.md +126 -0
- data/Rakefile +52 -0
- data/docs/DocsIndex.md +1 -0
- data/docs/examples/load_image.rb +25 -0
- data/ext/Rakefile +13 -0
- data/ext/aishack-sift/.gitignore +4 -0
- data/ext/aishack-sift/Descriptor.h +34 -0
- data/ext/aishack-sift/KeyPoint.h +38 -0
- data/ext/aishack-sift/README +20 -0
- data/ext/aishack-sift/SIFT.cpp +1036 -0
- data/ext/aishack-sift/SIFT.h +84 -0
- data/ext/aishack-sift/example/.gitignore +2 -0
- data/ext/aishack-sift/example/Makefile +24 -0
- data/ext/aishack-sift/example/MySIFT.cpp +29 -0
- data/ext/aishack-sift/mkrf_conf.rb +13 -0
- data/ext/aishack-sift/siftlib.cpp +85 -0
- data/ext/eigen/.gitignore +4 -0
- data/ext/eigen/eigen_polynomial.cpp +41 -0
- data/ext/eigen/eigen_svd.cpp +100 -0
- data/ext/eigen/mkrf_conf.rb +14 -0
- data/ext/mkrf-monkey.rb +85 -0
- data/ext/mkrf-rakehelper-monkey.rb +52 -0
- data/ext/mkrf_conf.rb +3 -0
- data/ext/opencv-ffi/.gitignore +4 -0
- data/ext/opencv-ffi/matcher_helper.cpp +56 -0
- data/ext/opencv-ffi/mkrf_conf.rb +12 -0
- data/ext/opencv-ffi/vector_math.cpp +39 -0
- data/ext/opensurf/.gitignore +4 -0
- data/ext/opensurf/README +38 -0
- data/ext/opensurf/fasthessian.cpp +376 -0
- data/ext/opensurf/fasthessian.h +108 -0
- data/ext/opensurf/integral.cpp +58 -0
- data/ext/opensurf/integral.h +55 -0
- data/ext/opensurf/ipoint.cpp +108 -0
- data/ext/opensurf/ipoint.h +76 -0
- data/ext/opensurf/kmeans.h +172 -0
- data/ext/opensurf/mkrf_conf.rb +10 -0
- data/ext/opensurf/responselayer.h +92 -0
- data/ext/opensurf/surf.cpp +317 -0
- data/ext/opensurf/surf.h +66 -0
- data/ext/opensurf/surflib.cpp +98 -0
- data/ext/opensurf/surflib.h +96 -0
- data/ext/opensurf/utils.cpp +357 -0
- data/ext/opensurf/utils.h +63 -0
- data/lib/.gitignore +1 -0
- data/lib/opencv-ffi-ext/eigen.rb +84 -0
- data/lib/opencv-ffi-ext/features2d.rb +4 -0
- data/lib/opencv-ffi-ext/matcher_helper.rb +24 -0
- data/lib/opencv-ffi-ext/opensurf.rb +217 -0
- data/lib/opencv-ffi-ext/sift.rb +118 -0
- data/lib/opencv-ffi-ext/vector_math.rb +115 -0
- data/lib/opencv-ffi-wrappers.rb +7 -0
- data/lib/opencv-ffi-wrappers/core.rb +24 -0
- data/lib/opencv-ffi-wrappers/core/iplimage.rb +50 -0
- data/lib/opencv-ffi-wrappers/core/mat.rb +268 -0
- data/lib/opencv-ffi-wrappers/core/misc_draw.rb +44 -0
- data/lib/opencv-ffi-wrappers/core/point.rb +286 -0
- data/lib/opencv-ffi-wrappers/core/rect.rb +40 -0
- data/lib/opencv-ffi-wrappers/core/scalar.rb +104 -0
- data/lib/opencv-ffi-wrappers/core/size.rb +88 -0
- data/lib/opencv-ffi-wrappers/enumerable.rb +10 -0
- data/lib/opencv-ffi-wrappers/features2d.rb +17 -0
- data/lib/opencv-ffi-wrappers/features2d/image_patch.rb +322 -0
- data/lib/opencv-ffi-wrappers/features2d/star.rb +111 -0
- data/lib/opencv-ffi-wrappers/features2d/surf.rb +115 -0
- data/lib/opencv-ffi-wrappers/highgui.rb +10 -0
- data/lib/opencv-ffi-wrappers/imgproc.rb +4 -0
- data/lib/opencv-ffi-wrappers/imgproc/features.rb +35 -0
- data/lib/opencv-ffi-wrappers/imgproc/geometric.rb +39 -0
- data/lib/opencv-ffi-wrappers/matcher.rb +297 -0
- data/lib/opencv-ffi-wrappers/matrix.rb +37 -0
- data/lib/opencv-ffi-wrappers/misc.rb +41 -0
- data/lib/opencv-ffi-wrappers/misc/params.rb +34 -0
- data/lib/opencv-ffi-wrappers/sequence.rb +37 -0
- data/lib/opencv-ffi-wrappers/vectors.rb +38 -0
- data/lib/opencv-ffi.rb +12 -0
- data/lib/opencv-ffi/calib3d.rb +26 -0
- data/lib/opencv-ffi/core.rb +15 -0
- data/lib/opencv-ffi/core/draw.rb +68 -0
- data/lib/opencv-ffi/core/dynamic.rb +13 -0
- data/lib/opencv-ffi/core/library.rb +5 -0
- data/lib/opencv-ffi/core/operations.rb +122 -0
- data/lib/opencv-ffi/core/point.rb +22 -0
- data/lib/opencv-ffi/core/types.rb +172 -0
- data/lib/opencv-ffi/cvffi.rb +8 -0
- data/lib/opencv-ffi/features2d.rb +7 -0
- data/lib/opencv-ffi/features2d/library.rb +6 -0
- data/lib/opencv-ffi/features2d/star.rb +30 -0
- data/lib/opencv-ffi/features2d/surf.rb +38 -0
- data/lib/opencv-ffi/highgui.rb +31 -0
- data/lib/opencv-ffi/imgproc.rb +9 -0
- data/lib/opencv-ffi/imgproc/features.rb +37 -0
- data/lib/opencv-ffi/imgproc/geometric.rb +42 -0
- data/lib/opencv-ffi/imgproc/library.rb +6 -0
- data/lib/opencv-ffi/imgproc/misc.rb +39 -0
- data/lib/opencv-ffi/version.rb +3 -0
- data/opencv-ffi.gemspec +26 -0
- data/test/core/test_draw.rb +46 -0
- data/test/core/test_operations.rb +135 -0
- data/test/core/test_size.rb +14 -0
- data/test/core/test_text.rb +52 -0
- data/test/ext/test_eigen.rb +105 -0
- data/test/ext/test_opensurf.rb +35 -0
- data/test/ext/test_sift.rb +26 -0
- data/test/ext/test_vector_math.rb +85 -0
- data/test/features2d/test_surf.rb +63 -0
- data/test/imgproc/test_goodfeatures.rb +18 -0
- data/test/setup.rb +65 -0
- data/test/test_calib3d.rb +38 -0
- data/test/test_core.rb +26 -0
- data/test/test_ext.rb +8 -0
- data/test/test_features2d.rb +9 -0
- data/test/test_files/images/IMG_7088.JPG +0 -0
- data/test/test_files/images/IMG_7088_small.JPG +0 -0
- data/test/test_files/images/IMG_7089.JPG +0 -0
- data/test/test_highgui.rb +26 -0
- data/test/test_imgproc.rb +35 -0
- data/test/test_wrappers.rb +8 -0
- data/test/wrappers/core/test_draw.rb +41 -0
- data/test/wrappers/core/test_mat.rb +40 -0
- data/test/wrappers/core/test_operations.rb +35 -0
- data/test/wrappers/core/test_types.rb +235 -0
- data/test/wrappers/features2d/test_image_patch.rb +108 -0
- data/test/wrappers/test_imgproc.rb +87 -0
- data/test/wrappers/test_matcher.rb +96 -0
- data/test/wrappers/test_star.rb +28 -0
- data/test/wrappers/test_surf.rb +36 -0
- metadata +234 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
/***********************************************************
|
2
|
+
* --- OpenSURF --- *
|
3
|
+
* This library is distributed under the GNU GPL. Please *
|
4
|
+
* use the contact form at http://www.chrisevansdev.com *
|
5
|
+
* for more information. *
|
6
|
+
* *
|
7
|
+
* C. Evans, Research Into Robust Visual Features, *
|
8
|
+
* MSc University of Bristol, 2008. *
|
9
|
+
* *
|
10
|
+
************************************************************/
|
11
|
+
|
12
|
+
#ifndef FASTHESSIAN_H
|
13
|
+
#define FASTHESSIAN_H
|
14
|
+
|
15
|
+
#include <opencv2/core/core.hpp>
|
16
|
+
#include <opencv2/core/core_c.h>
|
17
|
+
#include "ipoint.h"
|
18
|
+
|
19
|
+
#include <vector>
|
20
|
+
|
21
|
+
class ResponseLayer;
|
22
|
+
static const int OCTAVES = 5;
|
23
|
+
static const int INTERVALS = 4;
|
24
|
+
static const float THRES = 0.0004f;
|
25
|
+
static const int INIT_SAMPLE = 2;
|
26
|
+
|
27
|
+
|
28
|
+
class FastHessian {
|
29
|
+
|
30
|
+
public:
|
31
|
+
|
32
|
+
//! Constructor without image
|
33
|
+
FastHessian(std::vector<Ipoint> &ipts,
|
34
|
+
const int octaves = OCTAVES,
|
35
|
+
const int intervals = INTERVALS,
|
36
|
+
const int init_sample = INIT_SAMPLE,
|
37
|
+
const float thres = THRES);
|
38
|
+
|
39
|
+
//! Constructor with image
|
40
|
+
FastHessian(IplImage *img,
|
41
|
+
std::vector<Ipoint> &ipts,
|
42
|
+
const int octaves = OCTAVES,
|
43
|
+
const int intervals = INTERVALS,
|
44
|
+
const int init_sample = INIT_SAMPLE,
|
45
|
+
const float thres = THRES);
|
46
|
+
|
47
|
+
//! Destructor
|
48
|
+
~FastHessian();
|
49
|
+
|
50
|
+
//! Save the parameters
|
51
|
+
void saveParameters(const int octaves,
|
52
|
+
const int intervals,
|
53
|
+
const int init_sample,
|
54
|
+
const float thres);
|
55
|
+
|
56
|
+
//! Set or re-set the integral image source
|
57
|
+
void setIntImage(IplImage *img);
|
58
|
+
|
59
|
+
//! Find the image features and write into vector of features
|
60
|
+
void getIpoints();
|
61
|
+
|
62
|
+
private:
|
63
|
+
|
64
|
+
//---------------- Private Functions -----------------//
|
65
|
+
|
66
|
+
//! Build map of DoH responses
|
67
|
+
void buildResponseMap();
|
68
|
+
|
69
|
+
//! Calculate DoH responses for supplied layer
|
70
|
+
void buildResponseLayer(ResponseLayer *r);
|
71
|
+
|
72
|
+
//! 3x3x3 Extrema test
|
73
|
+
int isExtremum(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b);
|
74
|
+
|
75
|
+
//! Interpolation functions - adapted from Lowe's SIFT implementation
|
76
|
+
void interpolateExtremum(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b);
|
77
|
+
void interpolateStep(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b,
|
78
|
+
double* xi, double* xr, double* xc );
|
79
|
+
CvMat* deriv3D(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b);
|
80
|
+
CvMat* hessian3D(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b);
|
81
|
+
|
82
|
+
//---------------- Private Variables -----------------//
|
83
|
+
|
84
|
+
//! Pointer to the integral Image, and its attributes
|
85
|
+
IplImage *img;
|
86
|
+
int i_width, i_height;
|
87
|
+
|
88
|
+
//! Reference to vector of features passed from outside
|
89
|
+
std::vector<Ipoint> &ipts;
|
90
|
+
|
91
|
+
//! Response stack of determinant of hessian values
|
92
|
+
std::vector<ResponseLayer *> responseMap;
|
93
|
+
|
94
|
+
//! Number of Octaves
|
95
|
+
int octaves;
|
96
|
+
|
97
|
+
//! Number of Intervals per octave
|
98
|
+
int intervals;
|
99
|
+
|
100
|
+
//! Initial sampling step for Ipoint detection
|
101
|
+
int init_sample;
|
102
|
+
|
103
|
+
//! Threshold value for blob resonses
|
104
|
+
float thresh;
|
105
|
+
};
|
106
|
+
|
107
|
+
|
108
|
+
#endif
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/***********************************************************
|
2
|
+
* --- OpenSURF --- *
|
3
|
+
* This library is distributed under the GNU GPL. Please *
|
4
|
+
* use the contact form at http://www.chrisevansdev.com *
|
5
|
+
* for more information. *
|
6
|
+
* *
|
7
|
+
* C. Evans, Research Into Robust Visual Features, *
|
8
|
+
* MSc University of Bristol, 2008. *
|
9
|
+
* *
|
10
|
+
************************************************************/
|
11
|
+
|
12
|
+
#include <opencv2/imgproc/imgproc_c.h>
|
13
|
+
|
14
|
+
#include "utils.h"
|
15
|
+
|
16
|
+
#include "integral.h"
|
17
|
+
|
18
|
+
//! Computes the integral image of image img. Assumes source image to be a
|
19
|
+
//! 32-bit floating point. Returns IplImage of 32-bit float form.
|
20
|
+
IplImage *Integral(IplImage *source)
|
21
|
+
{
|
22
|
+
// convert the image to single channel 32f
|
23
|
+
IplImage *img = getGray(source);
|
24
|
+
IplImage *int_img = cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1);
|
25
|
+
|
26
|
+
// set up variables for data access
|
27
|
+
int height = img->height;
|
28
|
+
int width = img->width;
|
29
|
+
int step = img->widthStep/sizeof(float);
|
30
|
+
float *data = (float *) img->imageData;
|
31
|
+
float *i_data = (float *) int_img->imageData;
|
32
|
+
|
33
|
+
// first row only
|
34
|
+
float rs = 0.0f;
|
35
|
+
for(int j=0; j<width; j++)
|
36
|
+
{
|
37
|
+
rs += data[j];
|
38
|
+
i_data[j] = rs;
|
39
|
+
}
|
40
|
+
|
41
|
+
// remaining cells are sum above and to the left
|
42
|
+
for(int i=1; i<height; ++i)
|
43
|
+
{
|
44
|
+
rs = 0.0f;
|
45
|
+
for(int j=0; j<width; ++j)
|
46
|
+
{
|
47
|
+
rs += data[i*step+j];
|
48
|
+
i_data[i*step+j] = rs + i_data[(i-1)*step+j];
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
// release the gray image
|
53
|
+
cvReleaseImage(&img);
|
54
|
+
|
55
|
+
// return the integral image
|
56
|
+
return int_img;
|
57
|
+
}
|
58
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
/***********************************************************
|
2
|
+
* --- OpenSURF --- *
|
3
|
+
* This library is distributed under the GNU GPL. Please *
|
4
|
+
* use the contact form at http://www.chrisevansdev.com *
|
5
|
+
* for more information. *
|
6
|
+
* *
|
7
|
+
* C. Evans, Research Into Robust Visual Features, *
|
8
|
+
* MSc University of Bristol, 2008. *
|
9
|
+
* *
|
10
|
+
************************************************************/
|
11
|
+
|
12
|
+
#ifndef INTEGRAL_H
|
13
|
+
#define INTEGRAL_H
|
14
|
+
|
15
|
+
#include <algorithm> // req'd for std::min/max
|
16
|
+
|
17
|
+
// undefine VS macros
|
18
|
+
#ifdef min
|
19
|
+
#undef min
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#ifdef max
|
23
|
+
#undef max
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#include <opencv2/core/core.hpp>
|
27
|
+
|
28
|
+
//! Computes the integral image of image img. Assumes source image to be a
|
29
|
+
//! 32-bit floating point. Returns IplImage in 32-bit float form.
|
30
|
+
IplImage *Integral(IplImage *img);
|
31
|
+
|
32
|
+
|
33
|
+
//! Computes the sum of pixels within the rectangle specified by the top-left start
|
34
|
+
//! co-ordinate and size
|
35
|
+
inline float BoxIntegral(IplImage *img, int row, int col, int rows, int cols)
|
36
|
+
{
|
37
|
+
float *data = (float *) img->imageData;
|
38
|
+
int step = img->widthStep/sizeof(float);
|
39
|
+
|
40
|
+
// The subtraction by one for row/col is because row/col is inclusive.
|
41
|
+
int r1 = std::min(row, img->height) - 1;
|
42
|
+
int c1 = std::min(col, img->width) - 1;
|
43
|
+
int r2 = std::min(row + rows, img->height) - 1;
|
44
|
+
int c2 = std::min(col + cols, img->width) - 1;
|
45
|
+
|
46
|
+
float A(0.0f), B(0.0f), C(0.0f), D(0.0f);
|
47
|
+
if (r1 >= 0 && c1 >= 0) A = data[r1 * step + c1];
|
48
|
+
if (r1 >= 0 && c2 >= 0) B = data[r1 * step + c2];
|
49
|
+
if (r2 >= 0 && c1 >= 0) C = data[r2 * step + c1];
|
50
|
+
if (r2 >= 0 && c2 >= 0) D = data[r2 * step + c2];
|
51
|
+
|
52
|
+
return std::max(0.f, A - B - C + D);
|
53
|
+
}
|
54
|
+
|
55
|
+
#endif
|
@@ -0,0 +1,108 @@
|
|
1
|
+
/***********************************************************
|
2
|
+
* --- OpenSURF --- *
|
3
|
+
* This library is distributed under the GNU GPL. Please *
|
4
|
+
* use the contact form at http://www.chrisevansdev.com *
|
5
|
+
* for more information. *
|
6
|
+
* *
|
7
|
+
* C. Evans, Research Into Robust Visual Features, *
|
8
|
+
* MSc University of Bristol, 2008. *
|
9
|
+
* *
|
10
|
+
************************************************************/
|
11
|
+
|
12
|
+
#include <opencv2/core/core.hpp>
|
13
|
+
#include <opencv2/calib3d/calib3d.hpp>
|
14
|
+
#include <vector>
|
15
|
+
|
16
|
+
#include "ipoint.h"
|
17
|
+
|
18
|
+
using namespace cv;
|
19
|
+
|
20
|
+
//! Populate IpPairVec with matched ipts
|
21
|
+
void getMatches(IpVec &ipts1, IpVec &ipts2, IpPairVec &matches)
|
22
|
+
{
|
23
|
+
float dist, d1, d2;
|
24
|
+
Ipoint *match;
|
25
|
+
|
26
|
+
matches.clear();
|
27
|
+
|
28
|
+
for(unsigned int i = 0; i < ipts1.size(); i++)
|
29
|
+
{
|
30
|
+
d1 = d2 = FLT_MAX;
|
31
|
+
|
32
|
+
for(unsigned int j = 0; j < ipts2.size(); j++)
|
33
|
+
{
|
34
|
+
dist = ipts1[i] - ipts2[j];
|
35
|
+
|
36
|
+
if(dist<d1) // if this feature matches better than current best
|
37
|
+
{
|
38
|
+
d2 = d1;
|
39
|
+
d1 = dist;
|
40
|
+
match = &ipts2[j];
|
41
|
+
}
|
42
|
+
else if(dist<d2) // this feature matches better than second best
|
43
|
+
{
|
44
|
+
d2 = dist;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
// If match has a d1:d2 ratio < 0.65 ipoints are a match
|
49
|
+
if(d1/d2 < 0.65)
|
50
|
+
{
|
51
|
+
// Store the change in position
|
52
|
+
ipts1[i].dx = match->x - ipts1[i].x;
|
53
|
+
ipts1[i].dy = match->y - ipts1[i].y;
|
54
|
+
matches.push_back(std::make_pair(ipts1[i], *match));
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
//
|
60
|
+
// This function uses homography with CV_RANSAC (OpenCV 1.1)
|
61
|
+
// Won't compile on most linux distributions
|
62
|
+
//
|
63
|
+
|
64
|
+
//-------------------------------------------------------
|
65
|
+
|
66
|
+
//! Find homography between matched points and translate src_corners to dst_corners
|
67
|
+
int translateCorners(IpPairVec &matches, const CvPoint src_corners[4], CvPoint dst_corners[4])
|
68
|
+
{
|
69
|
+
#ifndef LINUX
|
70
|
+
double h[9];
|
71
|
+
CvMat _h = cvMat(3, 3, CV_64F, h);
|
72
|
+
std::vector<CvPoint2D32f> pt1, pt2;
|
73
|
+
CvMat _pt1, _pt2;
|
74
|
+
|
75
|
+
int n = (int)matches.size();
|
76
|
+
if( n < 4 ) return 0;
|
77
|
+
|
78
|
+
// Set vectors to correct size
|
79
|
+
pt1.resize(n);
|
80
|
+
pt2.resize(n);
|
81
|
+
|
82
|
+
// Copy Ipoints from match vector into cvPoint vectors
|
83
|
+
for(int i = 0; i < n; i++ )
|
84
|
+
{
|
85
|
+
pt1[i] = cvPoint2D32f(matches[i].second.x, matches[i].second.y);
|
86
|
+
pt2[i] = cvPoint2D32f(matches[i].first.x, matches[i].first.y);
|
87
|
+
}
|
88
|
+
_pt1 = cvMat(1, n, CV_32FC2, &pt1[0] );
|
89
|
+
_pt2 = cvMat(1, n, CV_32FC2, &pt2[0] );
|
90
|
+
|
91
|
+
// Find the homography (transformation) between the two sets of points
|
92
|
+
if(!cvFindHomography(&_pt1, &_pt2, &_h, CV_RANSAC, 5)) // this line requires opencv 1.1
|
93
|
+
return 0;
|
94
|
+
|
95
|
+
// Translate src_corners to dst_corners using homography
|
96
|
+
for(int i = 0; i < 4; i++ )
|
97
|
+
{
|
98
|
+
double x = src_corners[i].x, y = src_corners[i].y;
|
99
|
+
double Z = 1./(h[6]*x + h[7]*y + h[8]);
|
100
|
+
double X = (h[0]*x + h[1]*y + h[2])*Z;
|
101
|
+
double Y = (h[3]*x + h[4]*y + h[5])*Z;
|
102
|
+
dst_corners[i] = cvPoint(cvRound(X), cvRound(Y));
|
103
|
+
}
|
104
|
+
#endif
|
105
|
+
return 1;
|
106
|
+
}
|
107
|
+
|
108
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
/***********************************************************
|
2
|
+
* --- OpenSURF --- *
|
3
|
+
* This library is distributed under the GNU GPL. Please *
|
4
|
+
* use the contact form at http://www.chrisevansdev.com *
|
5
|
+
* for more information. *
|
6
|
+
* *
|
7
|
+
* C. Evans, Research Into Robust Visual Features, *
|
8
|
+
* MSc University of Bristol, 2008. *
|
9
|
+
* *
|
10
|
+
************************************************************/
|
11
|
+
|
12
|
+
#ifndef IPOINT_H
|
13
|
+
#define IPOINT_H
|
14
|
+
|
15
|
+
#include <vector>
|
16
|
+
#include <math.h>
|
17
|
+
|
18
|
+
//-------------------------------------------------------
|
19
|
+
|
20
|
+
class Ipoint; // Pre-declaration
|
21
|
+
typedef std::vector<Ipoint> IpVec;
|
22
|
+
typedef std::vector<std::pair<Ipoint, Ipoint> > IpPairVec;
|
23
|
+
|
24
|
+
//-------------------------------------------------------
|
25
|
+
|
26
|
+
//! Ipoint operations
|
27
|
+
void getMatches(IpVec &ipts1, IpVec &ipts2, IpPairVec &matches);
|
28
|
+
int translateCorners(IpPairVec &matches, const CvPoint src_corners[4], CvPoint dst_corners[4]);
|
29
|
+
|
30
|
+
//-------------------------------------------------------
|
31
|
+
|
32
|
+
class Ipoint {
|
33
|
+
|
34
|
+
public:
|
35
|
+
|
36
|
+
//! Destructor
|
37
|
+
~Ipoint() {};
|
38
|
+
|
39
|
+
//! Constructor
|
40
|
+
Ipoint() : orientation(0) {};
|
41
|
+
|
42
|
+
//! Gets the distance in descriptor space between Ipoints
|
43
|
+
float operator-(const Ipoint &rhs)
|
44
|
+
{
|
45
|
+
float sum=0.f;
|
46
|
+
for(int i=0; i < 64; ++i)
|
47
|
+
sum += (this->descriptor[i] - rhs.descriptor[i])*(this->descriptor[i] - rhs.descriptor[i]);
|
48
|
+
return sqrt(sum);
|
49
|
+
};
|
50
|
+
|
51
|
+
//! Coordinates of the detected interest point
|
52
|
+
float x, y;
|
53
|
+
|
54
|
+
//! Detected scale
|
55
|
+
float scale;
|
56
|
+
|
57
|
+
//! Orientation measured anti-clockwise from +ve x-axis
|
58
|
+
float orientation;
|
59
|
+
|
60
|
+
//! Sign of laplacian for fast matching purposes
|
61
|
+
int laplacian;
|
62
|
+
|
63
|
+
//! Vector of descriptor components
|
64
|
+
float descriptor[64];
|
65
|
+
|
66
|
+
//! Placeholds for point motion (can be used for frame to frame motion analysis)
|
67
|
+
float dx, dy;
|
68
|
+
|
69
|
+
//! Used to store cluster index
|
70
|
+
int clusterIndex;
|
71
|
+
};
|
72
|
+
|
73
|
+
//-------------------------------------------------------
|
74
|
+
|
75
|
+
|
76
|
+
#endif
|
@@ -0,0 +1,172 @@
|
|
1
|
+
/***********************************************************
|
2
|
+
* --- OpenSURF --- *
|
3
|
+
* This library is distributed under the GNU GPL. Please *
|
4
|
+
* use the contact form at http://www.chrisevansdev.com *
|
5
|
+
* for more information. *
|
6
|
+
* *
|
7
|
+
* C. Evans, Research Into Robust Visual Features, *
|
8
|
+
* MSc University of Bristol, 2008. *
|
9
|
+
* *
|
10
|
+
************************************************************/
|
11
|
+
|
12
|
+
#include "ipoint.h"
|
13
|
+
|
14
|
+
#include <vector>
|
15
|
+
#include <time.h>
|
16
|
+
#include <stdlib.h>
|
17
|
+
|
18
|
+
//-----------------------------------------------------------
|
19
|
+
// Kmeans clustering class (under development)
|
20
|
+
// - Can be used to cluster points based on their location.
|
21
|
+
// - Create Kmeans object and call Run with IpVec.
|
22
|
+
// - Planned improvements include clustering based on motion
|
23
|
+
// and descriptor components.
|
24
|
+
//-----------------------------------------------------------
|
25
|
+
|
26
|
+
class Kmeans {
|
27
|
+
|
28
|
+
public:
|
29
|
+
|
30
|
+
//! Destructor
|
31
|
+
~Kmeans() {};
|
32
|
+
|
33
|
+
//! Constructor
|
34
|
+
Kmeans() {};
|
35
|
+
|
36
|
+
//! Do it all!
|
37
|
+
void Run(IpVec *ipts, int clusters, bool init = false);
|
38
|
+
|
39
|
+
//! Set the ipts to be used
|
40
|
+
void SetIpoints(IpVec *ipts);
|
41
|
+
|
42
|
+
//! Randomly distribute 'n' clusters
|
43
|
+
void InitRandomClusters(int n);
|
44
|
+
|
45
|
+
//! Assign Ipoints to clusters
|
46
|
+
bool AssignToClusters();
|
47
|
+
|
48
|
+
//! Calculate new cluster centers
|
49
|
+
void RepositionClusters();
|
50
|
+
|
51
|
+
//! Function to measure the distance between 2 ipoints
|
52
|
+
float Distance(Ipoint &ip1, Ipoint &ip2);
|
53
|
+
|
54
|
+
//! Vector stores ipoints for this run
|
55
|
+
IpVec *ipts;
|
56
|
+
|
57
|
+
//! Vector stores cluster centers
|
58
|
+
IpVec clusters;
|
59
|
+
|
60
|
+
};
|
61
|
+
|
62
|
+
//-------------------------------------------------------
|
63
|
+
|
64
|
+
void Kmeans::Run(IpVec *ipts, int clusters, bool init)
|
65
|
+
{
|
66
|
+
if (!ipts->size()) return;
|
67
|
+
|
68
|
+
SetIpoints(ipts);
|
69
|
+
|
70
|
+
if (init) InitRandomClusters(clusters);
|
71
|
+
|
72
|
+
while (AssignToClusters());
|
73
|
+
{
|
74
|
+
RepositionClusters();
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
//-------------------------------------------------------
|
79
|
+
|
80
|
+
void Kmeans::SetIpoints(IpVec *ipts)
|
81
|
+
{
|
82
|
+
this->ipts = ipts;
|
83
|
+
}
|
84
|
+
|
85
|
+
//-------------------------------------------------------
|
86
|
+
|
87
|
+
void Kmeans::InitRandomClusters(int n)
|
88
|
+
{
|
89
|
+
// clear the cluster vector
|
90
|
+
clusters.clear();
|
91
|
+
|
92
|
+
// Seed the random number generator
|
93
|
+
srand((int)time(NULL));
|
94
|
+
|
95
|
+
// add 'n' random ipoints to clusters list as initial centers
|
96
|
+
for (int i = 0; i < n; ++i)
|
97
|
+
{
|
98
|
+
clusters.push_back(ipts->at(rand() % ipts->size()));
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
//-------------------------------------------------------
|
103
|
+
|
104
|
+
bool Kmeans::AssignToClusters()
|
105
|
+
{
|
106
|
+
bool Updated = false;
|
107
|
+
|
108
|
+
// loop over all Ipoints and assign each to closest cluster
|
109
|
+
for (unsigned int i = 0; i < ipts->size(); ++i)
|
110
|
+
{
|
111
|
+
float bestDist = FLT_MAX;
|
112
|
+
int oldIndex = ipts->at(i).clusterIndex;
|
113
|
+
|
114
|
+
for (unsigned int j = 0; j < clusters.size(); ++j)
|
115
|
+
{
|
116
|
+
float currentDist = Distance(ipts->at(i), clusters[j]);
|
117
|
+
if (currentDist < bestDist)
|
118
|
+
{
|
119
|
+
bestDist = currentDist;
|
120
|
+
ipts->at(i).clusterIndex = j;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
// determine whether point has changed cluster
|
125
|
+
if (ipts->at(i).clusterIndex != oldIndex) Updated = true;
|
126
|
+
}
|
127
|
+
|
128
|
+
return Updated;
|
129
|
+
}
|
130
|
+
|
131
|
+
//-------------------------------------------------------
|
132
|
+
|
133
|
+
void Kmeans::RepositionClusters()
|
134
|
+
{
|
135
|
+
float x, y, dx, dy, count;
|
136
|
+
|
137
|
+
for (unsigned int i = 0; i < clusters.size(); ++i)
|
138
|
+
{
|
139
|
+
x = y = dx = dy = 0;
|
140
|
+
count = 1;
|
141
|
+
|
142
|
+
for (unsigned int j = 0; j < ipts->size(); ++j)
|
143
|
+
{
|
144
|
+
if (ipts->at(j).clusterIndex == i)
|
145
|
+
{
|
146
|
+
Ipoint ip = ipts->at(j);
|
147
|
+
x += ip.x;
|
148
|
+
y += ip.y;
|
149
|
+
dx += ip.dx;
|
150
|
+
dy += ip.dy;
|
151
|
+
++count;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
clusters[i].x = x/count;
|
156
|
+
clusters[i].y = y/count;
|
157
|
+
clusters[i].dx = dx/count;
|
158
|
+
clusters[i].dy = dy/count;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
//-------------------------------------------------------
|
163
|
+
|
164
|
+
float Kmeans::Distance(Ipoint &ip1, Ipoint &ip2)
|
165
|
+
{
|
166
|
+
return sqrt(pow(ip1.x - ip2.x, 2)
|
167
|
+
+ pow(ip1.y - ip2.y, 2)
|
168
|
+
/*+ pow(ip1.dx - ip2.dx, 2)
|
169
|
+
+ pow(ip1.dy - ip2.dy, 2)*/);
|
170
|
+
}
|
171
|
+
|
172
|
+
//-------------------------------------------------------
|