使用 OpenCV 2.4.10 进行简要实现

问题描述 投票:0回答:2

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

PS:我知道这样的问题一般不受欢迎,因为主要关注的是你做了什么工作。但有一个类似的问题很受欢迎。

这些问题的答案之一提出了 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
在它之前被调用。

c++ opencv
2个回答
8
投票

在 OpenCV 中,BRIEF 是一个 DescriptorExtractor,而不是 FeatureDetector。根据FeatureDetector::create,该工厂方法不支持

"BRIEF"
算法。换句话说,
FeatureDetector::create("BRIEF")
返回一个空指针并且你的程序崩溃。

特征匹配的一般步骤是:

  1. 在图像中找到一些有趣的(特征)点:
    FeatureDetector
  2. 找到一种方法来描述这些要点:
    DescriptorExtractor
  3. 尝试匹配两个图像中的描述符(特征向量):
    DescriptorMatcher

BRIEF 是仅适用于步骤 2 的算法。您可以在步骤 1 中使用其他一些方法,HARRISORB...,并使用 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 算法 而不是

"HARRIS"
。下一步,从关键点计算描述符:

Mat ComputeDescriptors(const Mat &image, vector<KeyPoint> &keyPoints)
{
    auto featureExtractor = DescriptorExtractor::create("BRIEF");
    Mat descriptors;
    featureExtractor->compute(image, keyPoints, descriptors);
    return descriptors;
}

您也可以使用与 "BRIEF" 不同的

算法
。并且可以看到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"以外的不同

匹配算法
。最后回到主程序,您可以从这些函数构建应用程序:

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
矢量来完成您的应用程序。如果你想检查结果,OpenCV 还提供了 functions 来在图像中绘制步骤 1 和 3 的结果。例如,在最后一步中绘制火柴:

Mat result;
drawMatches(img1, keyPoints1, img2, keyPoints2, matches, result);
imshow("result", result);
waitKey(0);

0
投票

对于任何使用较新 OpenCV 版本的人来说,之前答案中的

::create
方法似乎已被删除。将行更改为
auto featureDetector = SIFT::create();
auto featureExtractor = xfeatures2d::BriefDescriptorExtractor::create();
,并且有效。请注意,BRIEF 需要 opencv[contrib] 和
#include <opencv2/xfeatures2d.hpp>

© www.soinside.com 2019 - 2024. All rights reserved.