OpenCV 中的重复率

repeatability rate in OpenCV

本文关键字:复率 OpenCV      更新时间:2023-10-16

我使用以下代码来检测 OpenCV 2.4.10 中的描述和评估功能,Microsoft Visual Studio 2012 中的C++。

#include <iostream>
#include <fstream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/legacy/legacy.hpp>
using namespace cv;
using namespace std;
int main(int argc, char ** argv)
{
  Mat image1;
  image1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); // Read the first file
  Mat image2;
  image2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
  if ((!image1.data) || (!image2.data)) {
    std::cout << "ERROR: Cannot load images inn" << argv[1] << "n" << argv[2] << endl;
    return -1;
  }
  vector < KeyPoint > keypoints1, keypoints2;
  cv::Mat descriptors1, descriptors2;
  /** Construction of the feature detector
   */
  double ExTime = (double) cv::getTickCount();
  cv::SurfFeatureDetector surf(800);
  /** Detection of the features
   */
  surf.detect(image1, keypoints1);
  surf.detect(image2, keypoints2);
  cv::SurfDescriptorExtractor surfDesc;
  surfDesc.compute(image1, keypoints1, descriptors1);
  surfDesc.compute(image2, keypoints2, descriptors2);
  //Calculate the time needed for code execution
  ExTime = ((double) cv::getTickCount() - ExTime) / cv::getTickFrequency();
  /** Draw the keypoints
   */
  Mat ImageKP1, ImageKP2;
  drawKeypoints(image1, keypoints1, ImageKP1, cv::Scalar(255, 0, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
  drawKeypoints(image2, keypoints2, ImageKP2, cv::Scalar(255, 0, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
  // Construction of the matcher 
  cv::Mat ImageMatch;
  cv::FlannBasedMatcher matcher;
  // Match the two image descriptors    
  std::vector < DMatch > matches;
  matcher.match(descriptors1, descriptors2, matches);
  double max_dist = 0;
  double min_dist = 100;
  //-- Quick calculation of max and min distances between keypoints
  for (int i = 0; i < descriptors1.rows; i++) {
    double dist = matches[i].distance;
    if (dist < min_dist) min_dist = dist;
    if (dist > max_dist) max_dist = dist;
  }
  //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
  //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
  //-- small)
  std::vector < DMatch > good_matches;
  for (int i = 0; i < descriptors1.rows; i++) {
    if (matches[i].distance <= 2 * min_dist) {
      good_matches.push_back(matches[i]);
    }
  }
  cout << "Number of good matches: " << good_matches.size() << endl;
  drawMatches(image1, keypoints1, image2, keypoints2, good_matches, ImageMatch, cv::Scalar(255, 0, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
  /** Evaluation of detected points
   */
  std::cout << ">" << std::endl;
  cout << "Evaluating feature detector..." << endl;
  float repeatability;
  int corrCounter;
  cv::Mat Homog;
  std::vector < cv::Point2f > srcKey;
  std::vector < cv::Point2f > refKey;
  for (int i = 0; i < matches.size(); i++) {
    srcKey.push_back(keypoints1[matches[i].queryIdx].pt);
    refKey.push_back(keypoints2[matches[i].queryIdx].pt);
  }
  Homog = cv::findHomography(srcKey, refKey, CV_RANSAC, 1);
  cv::evaluateFeatureDetector(image1, image2, Homog, & keypoints1, & keypoints2, repeatability, corrCounter);
  std::cout << "repeatability = " << repeatability << std::endl;
  std::cout << "correspCount = " << corrCounter << std::endl;
  std::cout << ">" << std::endl;
  system("pause");
  return 0;
}

问题是repeatability率总是 -1,以及correspCount.我使用我的图像,这些图像有很大的重叠并且检测到许多特征。我在OpenCV的官方网站上找不到有关该功能的教程

cv::EvaluateFeatureDetector

但只是像这样的网站中的一些教程。有一些类似的问题,但没有人总是将 -1 作为回报。可能出了什么问题?

如果检查evaluateFeatureDetector函数的源代码,它将检查关键点并调用calculateRepeatability函数。在该函数的第 436 行中:

correspondencesCount = -1;
repeatability = -1.f;
if( overlaps.empty() )
    return;

这些值设置为 -1,如果两个图像中筛选的关键点之间没有重叠,则返回这些值。在这种情况下,由于您的实际关键点向量不为空,我会说您的单调不正确。这可能是由于图像不够相似,或者单应性计算不正确造成的。既然你确定第一个不是这种情况,我建议你怀疑由此产生的单应性矩阵。您可以使用本教程通过生成的同形异义词在透视变换下绘制图像,这样如果图像意外失真,您将了解上述函数如何/为什么失败。