OpenCV图像特征匹配算法ORB/SURF/BRISK

  //必须转换为8位图像
  Img.convertTo(img1, CV_8UC1,255,0);
  current_image.convertTo(img2,CV_8UC1,255,0);
  
  std::vector<cv::KeyPoint> keypoints1, keypoints2;
  double minDistance = 10;
  int blockSize = CORNER_BLOCKSIZE, gradientSize = CORNER_BLOCKSIZE;
  bool useHarrisDetector = true;
  double k = 0.04;
  //使用Harris角点检测 keypoints 或者 SURF ORB
  //int minHessian = CANNY_LOWTHRESHOLD;
  //cv::Ptr<cv::xfeatures2d::SURF> detector = cv::xfeatures2d::SURF::create();
  //detector->setHessianThreshold(minHessian);
  cv::Ptr<cv::GFTTDetector> detector = cv::GFTTDetector::create(
                        MAX_CORNERS,
                        CORNER_QUALITYLEVEL,
                        minDistance,
                        blockSize,
                        useHarrisDetector,
                        k );
  detector->detect(img1,keypoints1);
  detector->detect(img2,keypoints2);
  
  
  // Calculate descriptors xfeatures2d
  //cv::Ptr<cv::ORB> extractor = cv::ORB::create();
  
  cv::Ptr<cv::xfeatures2d::FREAK> extractor = 
  cv::xfeatures2d::FREAK::create(true,false,30.0f,4);
  cv::Mat descriptors1, descriptors2;

  extractor->compute( img1, keypoints1, descriptors1 );
  extractor->compute( img2, keypoints2, descriptors2 );

  // Matching descriptors using Brute Force
  //cv::BFMatcher matcher(cv::NORM_L2,false);
  //std::vector<cv::DMatch> matches;
  //matcher.match(descriptors1, descriptors2, matches);
  //也可以采用KNN Matcher
  cv::Ptr<cv::DescriptorMatcher> matcher = 
  cv::DescriptorMatcher::create(cv::DescriptorMatcher::BRUTEFORCE);
  matcher->knnMatch(current_descriptors, image_template.descriptors, knn_matches, 2);
  //-- Filter matches using the Lowe's ratio test
  const float ratio_thresh = 0.7f;
  std::vector<cv::DMatch> good_matches;
  for (size_t i = 0; i < knn_matches.size(); i++)
  {
    if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance)
    {
      good_matches.push_back(knn_matches[i][0]);
    }
  }
  //-- Draw only "good" matches
  cv::Mat img_matches,img1, img2;
  current_image.convertTo(img1,CV_8UC1,255,0);
  image_template.Image.convertTo(img2,CV_8UC1,255,0);
  cv::drawMatches( img1, current_keypoints, img2, image_template.keypoints,
               good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1),
               vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

图像必须转换为8bit;

可以使用不同方法检测关键点和描述子;

两种方法来进行匹配BruteForce或者FLANNBased;

OpenCV参考:https://docs.opencv.org/3.4/d3/d46/classcv_1_1Algorithm.html

猜你喜欢

转载自blog.csdn.net/li4692625/article/details/109185688
今日推荐