bug-2325-surf.diff

patch for surf - Mr. Luk, 2012-08-31 02:09 pm

Download (14.4 kB)

 
b/modules/nonfree/include/opencv2/nonfree/features2d.hpp
52 52

  
53 53
/*!
54 54
 SIFT implementation.
55
 
55

  
56 56
 The class implements SIFT algorithm by D. Lowe.
57 57
*/
58 58
class CV_EXPORTS_W SIFT : public Feature2D
......
64 64

  
65 65
    //! returns the descriptor size in floats (128)
66 66
    CV_WRAP int descriptorSize() const;
67
    
67

  
68 68
    //! returns the descriptor type
69 69
    CV_WRAP int descriptorType() const;
70
    
70

  
71 71
    //! finds the keypoints using SIFT algorithm
72 72
    void operator()(InputArray img, InputArray mask,
73 73
                    vector<KeyPoint>& keypoints) const;
......
77 77
                    vector<KeyPoint>& keypoints,
78 78
                    OutputArray descriptors,
79 79
                    bool useProvidedKeypoints=false) const;
80
    
80

  
81 81
    AlgorithmInfo* info() const;
82
    
82

  
83 83
    void buildGaussianPyramid( const Mat& base, vector<Mat>& pyr, int nOctaves ) const;
84 84
    void buildDoGPyramid( const vector<Mat>& pyr, vector<Mat>& dogpyr ) const;
85 85
    void findScaleSpaceExtrema( const vector<Mat>& gauss_pyr, const vector<Mat>& dog_pyr,
......
88 88
protected:
89 89
    void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
90 90
    void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
91
    
91

  
92 92
    CV_PROP_RW int nfeatures;
93 93
    CV_PROP_RW int nOctaveLayers;
94 94
    CV_PROP_RW double contrastThreshold;
......
98 98

  
99 99
typedef SIFT SiftFeatureDetector;
100 100
typedef SIFT SiftDescriptorExtractor;
101
    
101

  
102 102
/*!
103 103
 SURF implementation.
104
 
104

  
105 105
 The class implements SURF algorithm by H. Bay et al.
106 106
 */
107
class CV_EXPORTS_W SURF : public Feature2D
107

  
108
class CV_EXPORTS_W SurfFeatureDetector : public FeatureDetector
108 109
{
109 110
public:
110 111
    //! the default constructor
111
    CV_WRAP SURF();
112
    CV_WRAP SurfFeatureDetector();
113

  
112 114
    //! the full constructor taking all the necessary parameters
113
    explicit CV_WRAP SURF(double hessianThreshold,
114
                  int nOctaves=4, int nOctaveLayers=2,
115
                  bool extended=true, bool upright=false);
115
    explicit CV_WRAP SurfFeatureDetector(double hessianThreshold,
116
                      int nOctaves=4, int nOctaveLayers=2);
116 117

  
117
    //! returns the descriptor size in float's (64 or 128)
118
    CV_WRAP int descriptorSize() const;
119
    
120
    //! returns the descriptor type
121
    CV_WRAP int descriptorType() const;
122
    
123 118
    //! finds the keypoints using fast hessian detector used in SURF
124 119
    void operator()(InputArray img, InputArray mask,
125
                    CV_OUT vector<KeyPoint>& keypoints) const;
126
    //! finds the keypoints and computes their descriptors. Optionally it can compute descriptors for the user-provided keypoints
127
    void operator()(InputArray img, InputArray mask,
128
                    CV_OUT vector<KeyPoint>& keypoints,
129
                    OutputArray descriptors,
130
                    bool useProvidedKeypoints=false) const;
131
    
120
            CV_OUT vector<KeyPoint>& keypoints) const;
121

  
132 122
    AlgorithmInfo* info() const;
133
    
123

  
134 124
    CV_PROP_RW double hessianThreshold;
135 125
    CV_PROP_RW int nOctaves;
136 126
    CV_PROP_RW int nOctaveLayers;
127

  
128
protected:
129
    void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat()) const;
130
    void detectImplCached( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask, Mat& integralImage) const;
131

  
132
};
133

  
134

  
135
class CV_EXPORTS_W SurfDescriptorExtractor : public DescriptorExtractor
136
{
137
public:
138
    //! the default constructor
139
    CV_WRAP SurfDescriptorExtractor();
140

  
141
    //! the full constructor taking all the necessary parameters
142
    explicit CV_WRAP SurfDescriptorExtractor(bool extended, bool upright=false);
143

  
144
    //! returns the descriptor size in float's (64 or 128)
145
    CV_WRAP int descriptorSize() const;
146

  
147
    //! returns the descriptor type
148
    CV_WRAP int descriptorType() const;
149

  
150
    AlgorithmInfo* info() const;
151

  
137 152
    CV_PROP_RW bool extended;
138 153
    CV_PROP_RW bool upright;
139
    
154

  
140 155
protected:
141
    
142
    void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
143 156
    void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
157
    void computeImplCached( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors, Mat& integralImage) const;
158
};
159

  
160
class CV_EXPORTS_W SURF : public SurfDescriptorExtractor, SurfFeatureDetector
161
{
162
public:
163
    //! the default constructor
164
    CV_WRAP SURF();
165
    //! the full constructor taking all the necessary parameters
166
    explicit CV_WRAP SURF(double hessianThreshold,
167
                  int nOctaves=4, int nOctaveLayers=2,
168
                  bool extended=true, bool upright=false);
169

  
170
    //! finds the keypoints and computes their descriptors. Optionally it can compute descriptors for the user-provided keypoints
171
    void operator()(InputArray img, InputArray mask,
172
            CV_OUT vector<KeyPoint>& keypoints,
173
            OutputArray descriptors,
174
            bool useProvidedKeypoints=false) const;
175

  
176
    //! finds the keypoints using fast hessian detector used in SURF
177
    void operator()(InputArray img, InputArray mask,
178
            CV_OUT vector<KeyPoint>& keypoints) const;
179

  
180
    AlgorithmInfo* info() const;
181

  
144 182
};
145
    
146
typedef SURF SurfFeatureDetector;
147
typedef SURF SurfDescriptorExtractor;
148 183

  
149 184
} /* namespace cv */
150 185

  
b/modules/nonfree/src/nonfree_init.cpp
54 54
                  obj.info()->addParam(obj, "extended", obj.extended);
55 55
                  obj.info()->addParam(obj, "upright", obj.upright));
56 56

  
57
CV_INIT_ALGORITHM(SurfFeatureDetector, "Feature2D.SurfDetector",
58
                  obj.info()->addParam(obj, "hessianThreshold", obj.hessianThreshold);
59
                  obj.info()->addParam(obj, "nOctaves", obj.nOctaves);
60
                  obj.info()->addParam(obj, "nOctaveLayers", obj.nOctaveLayers));
61

  
62
CV_INIT_ALGORITHM(SurfDescriptorExtractor, "Feature2D.SurfExtractor",
63
                  obj.info()->addParam(obj, "extended", obj.extended);
64
                  obj.info()->addParam(obj, "upright", obj.upright));
65

  
57 66
///////////////////////////////////////////////////////////////////////////////////////////////////////////
58 67

  
59
CV_INIT_ALGORITHM(SIFT, "Feature2D.SIFT",    
68
CV_INIT_ALGORITHM(SIFT, "Feature2D.SIFT",
60 69
                  obj.info()->addParam(obj, "nFeatures", obj.nfeatures);
61 70
                  obj.info()->addParam(obj, "nOctaveLayers", obj.nOctaveLayers);
62 71
                  obj.info()->addParam(obj, "contrastThreshold", obj.contrastThreshold);
63 72
                  obj.info()->addParam(obj, "edgeThreshold", obj.edgeThreshold);
64 73
                  obj.info()->addParam(obj, "sigma", obj.sigma));
65 74

  
66
///////////////////////////////////////////////////////////////////////////////////////////////////////////    
67
    
75
///////////////////////////////////////////////////////////////////////////////////////////////////////////
76

  
68 77
bool initModule_nonfree(void)
69 78
{
70
    Ptr<Algorithm> sift = createSIFT(), surf = createSURF();
71
    return sift->info() != 0 && surf->info() != 0;
79
    Ptr<Algorithm>
80
            sift = createSIFT(),
81
            surf = createSURF(),
82
            surfDetector = createSurfFeatureDetector(),
83
            surfExtractor = createSurfFeatureDetector();
84
    return sift->info() != 0
85
            && surf->info() != 0
86
            && surfDetector->info() != 0
87
            && surfExtractor->info() != 0
88
            ;
72 89
}
73 90

  
74 91
}
75
    
b/modules/nonfree/src/surf.cpp
854 854
    nOctaveLayers = _nOctaveLayers;
855 855
}
856 856

  
857
int SURF::descriptorSize() const { return extended ? 128 : 64; }
858
int SURF::descriptorType() const { return CV_32F; }
857
int SurfDescriptorExtractor::descriptorSize() const { return extended ? 128 : 64; }
858
int SurfDescriptorExtractor::descriptorType() const { return CV_32F; }
859 859

  
860 860
void SURF::operator()(InputArray imgarg, InputArray maskarg,
861 861
                      CV_OUT vector<KeyPoint>& keypoints) const
......
868 868
                      OutputArray _descriptors,
869 869
                      bool useProvidedKeypoints) const
870 870
{
871
    Mat img = _img.getMat(), mask = _mask.getMat(), mask1, sum, msum;
872
    bool doDescriptors = _descriptors.needed();
871
    Mat integralImage;
872
    Mat img = _img.getMat();
873

  
874
    // Compute keypoints only if we are not asked for evaluating the descriptors are some given locations:
875
    if( !useProvidedKeypoints )
876
    {
877
        this->detectImplCached(img, keypoints, _mask.getMat(), integralImage);
878
    }
879

  
880
    this->computeImplCached(img, keypoints, _descriptors.getMatRef(), integralImage);
881

  
882

  
883
}
884

  
885
SurfFeatureDetector::SurfFeatureDetector()
886
{
887
    hessianThreshold = 100;
888
    nOctaves = 4;
889
    nOctaveLayers = 2;
890
}
891

  
892
SurfFeatureDetector::SurfFeatureDetector(double _threshold, int _nOctaves, int _nOctaveLayers)
893
{
894
    hessianThreshold = _threshold;
895
    nOctaves = _nOctaves;
896
    nOctaveLayers = _nOctaveLayers;
897
}
898

  
899
void SurfFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
900
{
901
    Mat m;
902
    this->detectImplCached(image, keypoints, mask, m);
903
}
904

  
905
void SurfFeatureDetector::detectImplCached( const Mat& img, vector<KeyPoint>& keypoints, const Mat& mask, Mat& integralImg) const
906
{
907
    Mat mask1, msum;
908

  
873 909

  
874 910
    CV_Assert(!img.empty() && img.depth() == CV_8U);
875 911
    if( img.channels() > 1 )
......
880 916
    CV_Assert(nOctaves > 0);
881 917
    CV_Assert(nOctaveLayers > 0);
882 918

  
883
    integral(img, sum, CV_32S);
919
    integral(img, integralImg, CV_32S);
884 920

  
885
    // Compute keypoints only if we are not asked for evaluating the descriptors are some given locations:
886
    if( !useProvidedKeypoints )
921

  
922
    if( !mask.empty() )
887 923
    {
888
        if( !mask.empty() )
889
        {
890
            cv::min(mask, 1, mask1);
891
            integral(mask1, msum, CV_32S);
892
        }
893
        fastHessianDetector( sum, msum, keypoints, nOctaves, nOctaveLayers, (float)hessianThreshold );
924
        cv::min(mask, 1, mask1);
925
        integral(mask1, msum, CV_32S);
894 926
    }
927
    fastHessianDetector( integralImg, msum, keypoints, nOctaves, nOctaveLayers, (float)hessianThreshold );
928
}
929

  
930

  
931
SurfDescriptorExtractor::SurfDescriptorExtractor()
932
{
933
    extended = true;
934
    upright = false;
935
}
936

  
937
SurfDescriptorExtractor::SurfDescriptorExtractor(bool _extended, bool _upright)
938
{
939
    extended = _extended;
940
    upright = _upright;
941
}
942

  
943
void SurfDescriptorExtractor::computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const
944
{
945
    Mat m;
946
    this->computeImplCached(image, keypoints, descriptors, m);
947
}
948

  
949
void SurfDescriptorExtractor::computeImplCached( const Mat& img, vector<KeyPoint>& keypoints, Mat& descriptors, Mat& integralImg) const
950
{
951
    CV_Assert(!img.empty() && img.depth() == CV_8U);
952
    if( img.channels() > 1 )
953
        cvtColor(img, img, COLOR_BGR2GRAY);
954

  
955
    if (integralImg.empty())
956
        integral(img, integralImg, CV_32S);
895 957

  
896 958
    int i, j, N = (int)keypoints.size();
897 959
    if( N > 0 )
898 960
    {
899
        Mat descriptors;
900
        bool _1d = false;
901 961
        int dcols = extended ? 128 : 64;
902 962
        size_t dsize = dcols*sizeof(float);
903 963

  
904
        if( doDescriptors )
905
        {
906
            _1d = _descriptors.kind() == _InputArray::STD_VECTOR && _descriptors.type() == CV_32F;
907
            if( _1d )
908
            {
909
                _descriptors.create(N*dcols, 1, CV_32F);
910
                descriptors = _descriptors.getMat().reshape(1, N);
911
            }
912
            else
913
            {
914
                _descriptors.create(N, dcols, CV_32F);
915
                descriptors = _descriptors.getMat();
916
            }
917
        }
964
        descriptors.create(N, dcols, CV_32F);
918 965

  
919 966
        // we call SURFInvoker in any case, even if we do not need descriptors,
920 967
        // since it computes orientation of each feature.
921
        parallel_for(BlockedRange(0, N), SURFInvoker(img, sum, keypoints, descriptors, extended, upright) );
968
        parallel_for(BlockedRange(0, N), SURFInvoker(img, integralImg, keypoints, descriptors, extended, upright) );
922 969

  
923 970
        // remove keypoints that were marked for deletion
924 971
        for( i = j = 0; i < N; i++ )
......
928 975
                if( i > j )
929 976
                {
930 977
                    keypoints[j] = keypoints[i];
931
                    if( doDescriptors )
932
                        memcpy( descriptors.ptr(j), descriptors.ptr(i), dsize);
978
                    memcpy( descriptors.ptr(j), descriptors.ptr(i), dsize);
933 979
                }
934 980
                j++;
935 981
            }
936 982
        }
937
        if( N > j )
938
        {
939
            N = j;
940
            keypoints.resize(N);
941
            if( doDescriptors )
942
            {
943
                Mat d = descriptors.rowRange(0, N);
944
                if( _1d )
945
                    d = d.reshape(1, N*dcols);
946
                d.copyTo(_descriptors);
947
            }
948
        }
949 983
    }
950 984
}
951 985

  
952

  
953
void SURF::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
954
{
955
    (*this)(image, mask, keypoints, noArray(), false);
956
}
957

  
958
void SURF::computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const
959
{
960
    (*this)(image, Mat(), keypoints, descriptors, true);
961
}
962

  
963 986
}
964
-