SurfRegistration.cpp

The function GetHomography function is what causes the error - Clark Taylor, 2010-05-07 08:27 pm

Download (5.2 kB)

 
1
#include "Registration/SurfRegistration/SurfRegistration.h"
2
3
#include <cv.h>
4
#include <cxcore.h>
5
#include <highgui.h>
6
7
using namespace cv;
8
9
#define BROKEN 1
10
11
//Code copied from cvsurf.cpp
12
/* Wavelet size at first layer of first octave. */ 
13
const int HAAR_SIZE0 = 9;    
14
15
/* Wavelet size increment between layers. This should be an even number, 
16
 such that the wavelet sizes in an octave are either all even or all odd.
17
 This ensures that when looking for the neighbours of a sample, the layers
18
 above and below are aligned correctly. */
19
const int HAAR_SIZE_INC = 6;
20
21
static int getPointOctave(const CvSURFPoint& kpt, const CvSURFParams& params)
22
{
23
    int octave = 0, layer = 0, best_octave = 0;
24
    float min_diff = FLT_MAX;
25
    for( octave = 1; octave < params.nOctaves; octave++ )
26
        for( layer = 0; layer < params.nOctaveLayers; layer++ )
27
        {
28
            float diff = std::abs(kpt.size - (float)((HAAR_SIZE0 + HAAR_SIZE_INC*layer) << octave));
29
            if( min_diff > diff )
30
            {
31
                min_diff = diff;
32
                best_octave = octave;
33
                if( min_diff == 0 )
34
                    return best_octave;
35
            }
36
        }
37
    return best_octave;
38
}
39
40
//End of Code copied from cvsurf.cpp
41
42
43
SurfRegistration::SurfRegistration() {
44
        surf_class=cv::SURF(0.1);
45
};
46
47
SurfRegistration::~SurfRegistration() {};
48
49
bool SurfRegistration::GetHomography(IplImage *img1_gray, IplImage *img2_gray, 
50
                                                                         CvMat *homography)
51
{
52
        assert(homography->cols==3 && homography->rows==3); //assert type too?
53
        
54
        Mat going_out;
55
        Mat no_info;
56
        vector<KeyPoint> img1_points, img2_points;
57
        vector<float> img1_descriptors, img2_descriptors;
58
        Seq<CvSURFPoint> img1_points_seq, img2_points_seq;
59
        CvSeq* img1_descriptors_seq = 0;
60
        CvSeq* img2_descriptors_seq = 0;
61
        CvSURFParams params = cvSURFParams(500,0);
62
        CvMemStorage* storage = cvCreateMemStorage(0);
63
64
        Mat match_indices, match_distances;
65
        vector<Point2f> img1_inliers, img2_inliers;
66
        
67
        cv::flann::AutotunedIndexParams my_params;
68
        my_params.build_weight=1;
69
        my_params.memory_weight=.1;
70
        my_params.sample_fraction=.5;
71
        my_params.target_precision=0.9;
72
73
        Mat tmp5=Mat(img1_gray);
74
#ifdef BROKEN
75
        surf_class(tmp5,no_info,img1_points,img1_descriptors);
76
        assert( _CrtCheckMemory()  );
77
        return true; // it dies in the return when cleaning up img1_descriptors
78
#endif
79
80
        cvExtractSURF (img1_gray,0,&img1_points_seq.seq,&img1_descriptors_seq,storage,params);
81
        cvExtractSURF (img2_gray,0,&img2_points_seq.seq,&img2_descriptors_seq,storage,params);
82
        //surf_class(Mat(img2_gray),no_info,img2_points,img2_descriptors);
83
        //This code was essentially copied from operator() in cvsurf.cpp
84
    img1_descriptors.resize(img1_descriptors_seq ? img1_descriptors_seq->total*img1_descriptors_seq->elem_size/sizeof(float) : 0);
85
    if(img1_descriptors.size() != 0)
86
        cvCvtSeqToArray(img1_descriptors_seq, &img1_descriptors[0]);
87
    img2_descriptors.resize(img2_descriptors_seq ? img2_descriptors_seq->total*img2_descriptors_seq->elem_size/sizeof(float) : 0);
88
    if(img2_descriptors.size() != 0)
89
        cvCvtSeqToArray(img2_descriptors_seq, &img2_descriptors[0]);
90
91
        {
92
        Seq<CvSURFPoint>::iterator it = img1_points_seq.begin();
93
        size_t i, n = img1_points_seq.size();
94
        img1_points.resize(n);
95
        for( i = 0; i < n; i++, ++it )
96
        {
97
            const CvSURFPoint& kpt = *it;
98
            img1_points[i] = KeyPoint(kpt.pt, (float)kpt.size, kpt.dir,
99
                                    kpt.hessian, getPointOctave(kpt, params));
100
        }
101
    }
102
        {
103
        Seq<CvSURFPoint>::iterator it = img2_points_seq.begin();
104
        size_t i, n = img2_points_seq.size();
105
        img2_points.resize(n);
106
        for( i = 0; i < n; i++, ++it )
107
        {
108
            const CvSURFPoint& kpt = *it;
109
            img2_points[i] = KeyPoint(kpt.pt, (float)kpt.size, kpt.dir,
110
                                    kpt.hessian, getPointOctave(kpt, params));
111
        }
112
    }
113
114
115
        //end of copied code...
116
        Mat tmp=Mat(img1_descriptors).reshape(1,img1_descriptors.size()/surf_class.descriptorSize());
117
        
118
        cv::flann::Index flann_class(tmp,
119
                //Mat(img1_descriptors).reshape(1,img1_descriptors.size()/surf_class.descriptorSize()),
120
                my_params);
121
122
        match_indices.create(img2_points.size(),2,CV_32S);
123
        match_distances.create(img2_points.size(),2,CV_32F);
124
        Mat tmp2=Mat(img2_descriptors).reshape(1,img2_descriptors.size()/surf_class.descriptorSize());
125
        flann_class.knnSearch(tmp2,match_indices,match_distances,2,
126
                cv::flann::SearchParams()); //SearchParams is ignored as I used auto-create above
127
        for (int i=0;i<img2_points.size();i++) {
128
                float dist1=match_distances.at<float>(i,0);
129
                if (dist1<0.6*match_distances.at<float>(i,1)) {
130
                        img1_inliers.push_back(img1_points.at(match_indices.at<int>(i,0)).pt);
131
                        img2_inliers.push_back(img2_points.at(i).pt);
132
                }
133
        }        
134
        if (img1_inliers.size()<4) {
135
                printf ("The number of inliers was only %d\n",img1_inliers.size());
136
                return false;
137
        }
138
        // All the point matches have now been found.  Run RANSAC homography finder to compute
139
        // the homography
140
        going_out=findHomography(Mat(img1_inliers),Mat(img2_inliers),(int)cv::RANSAC,DISTANCE_THRESHOLD);
141
        for (int i=0;i<3;i++)
142
                memcpy(homography->data.ptr+homography->step*i,going_out.ptr(i),sizeof(float)*3);
143
        return true;
144
145
}
146