有人知道OpenCV 2.4到Brief实现的链接吗?问候。

PS:我知道这样的问题通常不受欢迎,因为主要的重点是您所做的工作。但是有一个类似的question受到了广泛的欢迎。

对这些问题的答案之一表明了SIFT的一种通用方式,可以扩展到Brief。这是我稍作修改的代码。

#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/highgui/highgui.hpp>

//using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{
  Mat image = imread("load02.jpg", CV_LOAD_IMAGE_GRAYSCALE);
  cv::initModule_nonfree();
  // Create smart pointer for SIFT feature detector.
  Ptr<FeatureDetector> featureDetector = FeatureDetector::create("HARRIS"); // "BRIEF was initially written. Changed after answer."
  vector<KeyPoint> keypoints;

  // Detect the keypoints
  featureDetector->detect(image, keypoints); // NOTE: featureDetector is a pointer hence the '->'.

  //Similarly, we create a smart pointer to the SIFT extractor.
  Ptr<DescriptorExtractor> featureExtractor = DescriptorExtractor::create("BRIEF");

  // Compute the 128 dimension SIFT descriptor at each keypoint.
  // Each row in "descriptors" correspond to the SIFT descriptor for each keypoint
  Mat descriptors;
  featureExtractor->compute(image, keypoints, descriptors);

  // If you would like to draw the detected keypoint just to check
  Mat outputImage;
  Scalar keypointColor = Scalar(255, 0, 0);     // Blue keypoints.
  drawKeypoints(image, keypoints, outputImage, keypointColor, DrawMatchesFlags::DEFAULT);

  namedWindow("Output");
  imshow("Output", outputImage);

  char c = ' ';
  while ((c = waitKey(0)) != 'q');  // Keep window there until user presses 'q' to quit.

  return 0;

}

此代码的问题是它给出了一个错误:First-chance exception at 0x00007FFB84698B9C in Project2.exe: Microsoft C++ exception: cv::Exception at memory location 0x00000071F4FBF8E0.
该错误导致函数执行中断。标记表示执行将在namedWindow("Output");行处恢复。

有人可以帮忙解决此问题,还是建议一个新的代码?谢谢。

编辑:终端现在显示错误:Assertion failed (!outImage.empty()) in cv::drawKeypoints, file ..\..\..\..opencv\modules\features2d\src\draw.cpp, line 115。从中继续执行代码的下一条语句保持不变,因为drawKepoints在其之前被调用。

最佳答案

在OpenCV中,Brief是 DescriptorExtractor ,而不是 FeatureDetector 。根据FeatureDetector::create,此工厂方法不支持"BRIEF"算法。换句话说,FeatureDetector::create("BRIEF")返回一个空指针,并且您的程序崩溃。

特征匹配的一般步骤是:

  • 在图像中找到一些有趣的(特征)点:FeatureDetector
  • 找到描述这些要点的方法:DescriptorExtractor
  • 尝试匹配两个图像中的描述符(特征 vector ):DescriptorMatcher

  • Brief是仅针对步骤2的算法。您可以在步骤1中使用其他方法HARRIS,ORB等,然后使用Brief将结果传递到步骤2。此外,SIFT可以在步骤1和2中使用,因为该算法为这两个步骤提供了方法。

    这是在OpenCV中使用Brief的简单示例。第一步,找到图像中看起来有趣的点(关键点):
    vector<KeyPoint> DetectKeyPoints(const Mat &image)
    {
        auto featureDetector = FeatureDetector::create("HARRIS");
        vector<KeyPoint> keyPoints;
        featureDetector->detect(image, keyPoints);
        return keyPoints;
    }
    

    您可以尝试使用任何FeatureDetector algorithm而不是"HARRIS"。下一步,从关键点计算描述符:
    Mat ComputeDescriptors(const Mat &image, vector<KeyPoint> &keyPoints)
    {
        auto featureExtractor = DescriptorExtractor::create("BRIEF");
        Mat descriptors;
        featureExtractor->compute(image, keyPoints, descriptors);
        return descriptors;
    }
    

    您也可以使用不同于"BRIEF"algorithm。并且您可以看到 DescriptorExtractor 中的算法与 FeatureDetector 中的算法不同。最后一步,匹配两个描述符:
    vector<DMatch> MatchTwoImage(const Mat &descriptor1, const Mat &descriptor2)
    {
        auto matcher = DescriptorMatcher::create("BruteForce");
        vector<DMatch> matches;
        matcher->match(descriptor1, descriptor2, matches);
        return matches;
    }
    

    同样,您可以尝试使用"BruteForce"以外的其他matching algorithm。最后回到主程序,您可以从这些功能构建应用程序:
    auto img1 = cv::imread("image1.jpg");
    auto img2 = cv::imread("image2.jpg");
    
    auto keyPoints1 = DetectKeyPoints(img1);
    auto keyPoints2 = DetectKeyPoints(img2);
    
    auto descriptor1 = ComputeDescriptors(img1, keyPoints1);
    auto descriptor2 = ComputeDescriptors(img2, keyPoints2);
    
    auto matches = MatchTwoImage(descriptor1, descriptor2);
    

    并使用matches vector 完成您的应用程序。如果要检查结果,OpenCV还提供functions在图像中绘制步骤1和3的结果。例如,在最后一步中绘制匹配项:
    Mat result;
    drawMatches(img1, keyPoints1, img2, keyPoints2, matches, result);
    imshow("result", result);
    waitKey(0);
    

    08-16 03:28