1 /**************************************************************************** 2 * 3 * ViSP, open source Visual Servoing Platform software. 4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved. 5 * 6 * This software is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * See the file LICENSE.txt at the root directory of this source 11 * distribution for additional information about the GNU GPL. 12 * 13 * For using ViSP with software that can not be combined with the GNU 14 * GPL, please contact Inria about acquiring a ViSP Professional 15 * Edition License. 16 * 17 * See http://visp.inria.fr for more information. 18 * 19 * This software was developed at: 20 * Inria Rennes - Bretagne Atlantique 21 * Campus Universitaire de Beaulieu 22 * 35042 Rennes Cedex 23 * France 24 * 25 * If you have questions regarding the use of this file, please contact 26 * Inria at visp@inria.fr 27 * 28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 30 * 31 * Description: 32 * Key point Surf. 33 * 34 * Authors: 35 * Nicolas Melchior 36 * 37 *****************************************************************************/ 38 39 #ifndef vpKeyPointSurf_H 40 #define vpKeyPointSurf_H 41 42 /*! 43 \file vpKeyPointSurf.h 44 \ingroup group_detection_keypoint 45 46 \brief Class that implements the SURF key points and technics thanks 47 to the OpenCV library. 48 */ 49 50 #include <visp3/vision/vpBasicKeyPoint.h> 51 52 #include <list> 53 #include <vector> 54 55 #if defined(VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION < 0x030000) 56 57 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400) // Require opencv >= 1.1.0 < 3.0.0 58 #include <opencv2/core/core.hpp> 59 #include <opencv2/features2d/features2d.hpp> 60 #include <opencv2/legacy/compat.hpp> 61 #include <opencv2/nonfree/nonfree.hpp> 62 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1 63 #include <opencv2/features2d/features2d.hpp> 64 #elif (VISP_HAVE_OPENCV_VERSION >= 0x010100) // Require opencv >= 1.1.0 65 #include <cv.h> 66 #include <cxcore.h> 67 #endif 68 69 /*! 70 \class vpKeyPointSurf 71 \ingroup group_vision_keypoints 72 73 \brief Class that implements the SURF key points and technics thanks 74 to OpenCV library. 75 76 \deprecated This class is deprecated with OpenCV 3.0.0 or more recent. 77 You should rather use vpKeyPoint class that is more generic. 78 79 The goal of this class is to provide a tool to match points from a 80 model and points belonging to an image in which the model appears. 81 The coordinates of the different reference points and matched points 82 are given in pixel thanks to the class vpImagePoint. In this 83 documentation we do not explain the SURF technics. So if you want to 84 learn more about it you can refer to the following article : 85 Herbert Bay, Tinne Tuytelaars and Luc Van Gool "SURF: Speeded Up 86 Robust Features", Proceedings of the 9th European Conference on 87 Computer Vision, Springer LNCS volume 3951, part 1, pp 404--417, 88 2006. 89 90 If you use this class the first things you have to do is to create 91 the reference thanks to a reference image which contains the 92 interesting object to detect. Then you have to grab other images 93 containing the object. After calling the specific method to match 94 points you can access to the lists of matched points thanks to the 95 methods getMatchedPointsInReferenceImage() and 96 getMatchedPointsInCurrentImage(). These two methods return a list of 97 matched points. The nth element of the first list is matched with 98 the nth element of the second list. The following small example show 99 how to use the class. 100 101 \code 102 #include <visp3/core/vpConfig.h> 103 #include <visp3/core/vpImage.h> 104 #include <visp3/vision/vpKeyPointSurf.h> 105 106 int main() 107 { 108 #if defined (VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION < 0x030000) 109 vpImage<unsigned char> Ireference; vpImage<unsigned char> Icurrent; 110 vpKeyPointSurf surf; 111 112 // First grab the reference image Ireference 113 114 // Build the reference SURF points. 115 surf.buildReference(Ireference); 116 117 // Then grab another image which represents the current image Icurrent 118 119 // Match points between the reference points and the SURF points computed in the current image. 120 surf.matchPoint(Icurrent); 121 122 // Display the matched points 123 surf.display(Ireference, Icurrent); 124 125 return (0); 126 #endif 127 } 128 \endcode 129 130 It is also possible to create the reference thanks to only a part of the 131 reference image (not the whole image) and find points to match in only a 132 part of the current image. The small following example shows how to this 133 134 \code 135 #include <visp3/core/vpDisplay.h> 136 #include <visp3/core/vpImage.h> 137 #include <visp3/vision/vpKeyPointSurf.h> 138 139 int main() 140 { 141 #if defined (VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION < 0x030000) 142 vpImage<unsigned char> Ireference; vpImage<unsigned char> Icurrent; 143 vpKeyPointSurf surf; 144 145 //First grab the reference image Ireference 146 147 //Select a part of the image by clincking on two points which define a rectangle 148 vpImagePoint corners[2]; for (int i=0 ; i < 2 ; i++) { 149 vpDisplay::getClick(Ireference, corners[i]); 150 } 151 152 //Build the reference SURF points. 153 int nbrRef; 154 unsigned int height, width; 155 height = (unsigned int)(corners[1].get_i() - corners[0].get_i()); 156 width = (unsigned int)(corners[1].get_j() - corners[0].get_j()); 157 nbrRef = surf.buildReference(Ireference, corners[0], height, width); 158 159 //Then grab another image which represents the current image Icurrent 160 161 //Select a part of the image by clincking on two points which define a rectangle 162 for (int i=0 ; i < 2 ; i++) { 163 vpDisplay::getClick(Icurrent, corners[i]); 164 } 165 166 //Match points between the reference points and the SURF points computed in the current image. 167 int nbrMatched; 168 height = (unsigned int)(corners[1].get_i() - corners[0].get_i()); 169 width = (unsigned int)(corners[1].get_j() - corners[0].get_j()); 170 nbrMatched = surf.matchPoint(Icurrent, corners[0], height, width); 171 172 //Display the matched points 173 surf.display(Ireference, Icurrent); 174 175 return(0); 176 #endif 177 } 178 \endcode 179 180 This class is also described in \ref tutorial-matching. 181 */ 182 183 class VISP_EXPORT vpKeyPointSurf : public vpBasicKeyPoint 184 { 185 public: 186 /*! 187 This enumerate enables to set the detail level of the 188 descriptors. 189 */ 190 typedef enum { 191 basicDescriptor, /*<! basicDescriptor means that the descriptors are 192 composed by 64 elements floating-point vector. */ 193 extendedDescriptor /*<! Means that the descriptors are composed by 194 128 elements floating-point vector. */ 195 } vpDescriptorType; 196 197 public: 198 vpKeyPointSurf(); 199 200 virtual ~vpKeyPointSurf(); 201 202 unsigned int buildReference(const vpImage<unsigned char> &I); 203 unsigned int buildReference(const vpImage<unsigned char> &I, const vpImagePoint &iP, unsigned int height, 204 unsigned int width); 205 unsigned int buildReference(const vpImage<unsigned char> &I, const vpRect &rectangle); 206 unsigned int matchPoint(const vpImage<unsigned char> &I); 207 unsigned int matchPoint(const vpImage<unsigned char> &I, const vpImagePoint &iP, unsigned int height, 208 unsigned int width); 209 unsigned int matchPoint(const vpImage<unsigned char> &I, const vpRect &rectangle); 210 void display(const vpImage<unsigned char> &Iref, const vpImage<unsigned char> &Icurrent, unsigned int size = 3); 211 void display(const vpImage<unsigned char> &Icurrent, unsigned int size = 3, const vpColor &color = vpColor::green); 212 std::list<int *> *matchPoint(std::list<float *> descriptorList, std::list<int> laplacianList); 213 float *getDescriptorReferencePoint(int index); 214 int getLaplacianReferencePoint(int index); 215 void getDescriptorParamReferencePoint(int index, int &size, float &dir); 216 /*! 217 218 Sets the value of the hessian threhold. Note that during the 219 computation of the hessian for each potential points, only the 220 points which have a hessian value higher than the threshold are 221 keeped. Fore more details about the threshold see the article 222 Herbert Bay, Tinne Tuytelaars and Luc Van Gool "SURF: Speeded Up 223 Robust Features", Proceedings of the 9th European Conference on 224 Computer Vision, Springer LNCS volume 3951, part 1, pp 404--417, 225 2006. 226 227 \param hessian_threshold : Desired hessian threshold value. 228 */ setHessianThreshold(double hessian_threshold)229 void setHessianThreshold(double hessian_threshold) 230 { 231 this->hessianThreshold = hessian_threshold; 232 params = cvSURFParams(this->hessianThreshold, this->descriptorType); 233 }; 234 235 /*! 236 237 Sets the type of descriptors to use. 238 239 \param descriptor_type : Type of descriptor to use. 240 */ setDescriptorType(vpDescriptorType descriptor_type)241 void setDescriptorType(vpDescriptorType descriptor_type) 242 { 243 this->descriptorType = descriptor_type; 244 params = cvSURFParams(this->hessianThreshold, this->descriptorType); 245 }; 246 247 /*! 248 Gets the value of the hessian threhold. 249 250 \return the hessian threshold value. 251 */ getHessianThreshold()252 double getHessianThreshold() { return hessianThreshold; } 253 254 /*! 255 Gets the type of descriptor used. 256 257 \return the type of descriptor used. 258 */ getDescriptorType()259 vpDescriptorType getDescriptorType() { return descriptorType; } 260 261 private: 262 void init(); 263 264 private: 265 // OpenCV Parameters 266 CvMemStorage *storage; 267 CvSURFParams params; 268 CvMemStorage *storage_cur; 269 270 CvSeq *image_keypoints; 271 CvSeq *image_descriptors; 272 273 CvSeq *ref_keypoints; 274 CvSeq *ref_descriptors; 275 276 /*! 277 only features with keypoint.hessian larger than that are extracted. 278 Good default value is ~300-500 (can depend on the average 279 local contrast and sharpness of the image). 280 User can further filter out some features based on their hessian values 281 and other characteristics. 282 */ 283 double hessianThreshold; 284 vpDescriptorType descriptorType; 285 }; 286 287 #endif 288 289 #endif 290