opencv-ffi 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
//-------------------------------------------------------
|