OpenCV中的FlannBasedMatcher

3
我遇到了一个问题: cv :: FlannBasedMatcher 更准确地说,是knnMatch方法。 我的程序以IplImage *作为输入并检测人脸,然后剪切人脸并将其与存储在计算机上的图像进行比较。如果我得到超过10个良好匹配项,则会在标准输出中写入匹配项。
加载的图像不是灰度图像。这重要吗?
我的问题是它运行了一段随机时间,从大约1分钟到3分钟不等。
错误消息始终出现在knnMatch方法中。以下是它们(请注意,每次只有一个):
OpenCV Error: Assertion failed ((globalDescIdx>=0) && (globalDescIdx < size())) in           getLocalIdx, file    /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-  2.4.9/modules/features2d/src/matchers.cpp, line 163
 libc++abi.dylib: terminating with uncaught exception of type cv::Exception:   /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-2.4.9/modules/features2d/src/matchers.cpp:163: error: (-215) (globalDescIdx>=0) && (globalDescIdx < size()) in function getLocalIdx

我不明白为什么会抛出这个异常...
下面是我的代码:
int        DroneCV::matchFaces()
{
std::vector<cv::KeyPoint> keypointsO;
std::vector<cv::KeyPoint> keypointsS;
cv::Mat descriptors_object, descriptors_scene;
cv::Mat foundFaces(this->_faceCut);
cv::FlannBasedMatcher matcher;
std::vector<std::vector<cv::DMatch>> matches;
std::vector<cv::DMatch> good_matches;
cv::SurfDescriptorExtractor extractor;
cv::SurfFeatureDetector surf(this->_minHessian);

surf.detect(foundFaces,keypointsS);
surf.detect(this->_faceToRecognize,keypointsO);
if (!this->_faceToRecognize.data || !foundFaces.data)
{
    this->log("Fail to init data in DronceCV::matchFaces");
    return (0);
}

extractor.compute(foundFaces, keypointsS, descriptors_scene);
extractor.compute(this->_faceToRecognize, keypointsO, descriptors_object);

if(descriptors_scene.empty())//descriptors_scene.type()!=CV_32F)
{
    this->log("Descriptor got wrong type");
    descriptors_scene.convertTo(descriptors_scene, CV_32F);
    return 0;
 }
if(descriptors_object.type()!=CV_32F || descriptors_scene.type()!=CV_32F)
{
    this->log("TYPE OBJECT " + std::to_string(descriptors_object.type()));
    this->log("TYPE SCENE " + std::to_string(descriptors_scene.type()));
    return (0);
}
//Both image must be in grayscale ???
try {
    matcher.knnMatch( descriptors_object, descriptors_scene, matches, 5 ); // find the 2 nearest neighbors

} catch (cv::Exception e) {
    this->log(e.err);
}
good_matches.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
    if (matches[i].size() < 2)
        continue;
    const cv::DMatch &m1 = matches[i][0];
    const cv::DMatch &m2 = matches[i][1];

    if(m1.distance <= this->_nndrRatio * m2.distance)
        good_matches.push_back(m1);
}
this->log("Number of good matches" + std::to_string(good_matches.size()));
foundFaces.release();
if (good_matches.size() > 8)
    return (1);
else
    return (0);

}

void        DroneCV::analyzeFrame(IplImage *img)
{
if (!img)
{
    this->log("Frame empty");
    return;
}

if (this->detectFaces(img) == 1)
{
    if (this->matchFaces() == 1)
    {
        this->log("Matched");
        cvReleaseImage(&this->_faceCut);
    }
}
}

Thanks in advance for your help


我注意到k越大,我就越容易出现异常。 - Ayrton Werck
嗨,我现在也遇到了同样的错误。你解决了吗? - dephinera
1个回答

13

我也曾经卡在这里,花了将近3-4个小时才解决。当你应用knn匹配时,请确保测试和查询图像中的特征数量大于或等于knn匹配中最近邻居的数量。
例如,我们有以下代码:

Mat img1,img2,desc1,desc2;
vector<KeyPoint> kpt1,kpt2;

FAST(img1,kpt1,30,true) ;
FAST(img2,kpt1,30,true) ;

SurfDescriptorExtractor sfdesc1,sfdesc2;
sfdesc1.compute(img1,kpt1,desc1);
sfdesc2.compute(img2,kpt2,desc2);

FlannBasedMatcher matcher;
vector< vector<DMatch> > matches1,matches2;
matcher.knnMatch(desc1,desc2,matches1,2);

这段代码会像文章中一样返回异常,只需按照下面所示修改代码:

if(kpt1.size()>=2 && kpt2.size()>=2) 
matcher.knnMatch(desc1,desc2,matches1,2);

这种方法对我很有效..!!


@dudu 你有找到解决方案吗?我和原帖作者一样遇到了断言错误,但这个答案并没有解决我的问题。 - ChocolateAndCheese
@ChocolateAndCheese 像这样初始化Flann匹配器:FlannBasedMatcher matcher(new flann::LshIndexParams(20, 10, 2));。阅读此关闭问题页面。好的,这解决了我的问题。希望对你有用。 - dudu
@ChocolateAndCheese 实际上,我并没有完全理解描述符或匹配器的工作原理,以及它们应该如何组合工作。我只是一直尝试直到它能够正常工作。我不确定我的解决方案是否适用于您。因为我使用的是ORB+Flann,此外,现在我也无法清楚地记得错误信息了。 - dudu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接