尝试在OpenCv中使用sift匹配两个图像,但匹配太多 [英] Trying to match two images using sift in OpenCv, but too many matches

查看:299
本文介绍了尝试在OpenCv中使用sift匹配两个图像,但匹配太多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个程序,它将输入两个图像,一个是单独的图像,另一个是包含场景中的框。基本上,该程序应该在这两个图像中找到关键点,并将显示匹配关键点的图像。最后我希望看到两个输入图像的附加图像以及它们匹配的关键点连接。我的代码如下:

  #include< opencv2 \opencv.hpp> 
#include< iostream>

int main(int argc,const char * argv []){
cv :: Mat input1 = cv :: imread(input.jpg,1); //加载为灰度
// cv :: cvtColor(input1,input1,CV_BGR2GRAY);
//第二个输入加载为灰度
cv :: Mat input2 = cv :: imread(input2.jpg,1);
cv :: SiftFeatureDetector探测器;
// cv :: SiftFeatureDetector
探测器(
1,1,
cv :: SIFT :: CommonParams :: DEFAULT_NOCTAVES,
cv :: SIFT :: CommonParams :: DEFAULT_NOCTAVE_LAYERS,
cv :: SIFT :: CommonParams :: DEFAULT_FIRST_OCTAVE,
cv :: SIFT :: CommonParams :: FIRST_ANGLE);
std :: vector< cv :: KeyPoint> keypoints1;
detector.detect(input1,keypoints1);
//将结果添加到图像并保存。
cv :: Mat output1;
cv :: drawKeypoints(input1,keypoints1,output1);
cv :: imshow(Sift_result1.jpg,output1);
cv :: imwrite(Sift_result1.jpg,output1);
//输入2的关键点数组
std :: vector< cv :: KeyPoint> keypoints2;
//输出数组输出2
cv :: Mat output2;
//提取opencv的提取器
cv :: SiftDescriptorExtractor提取器;
cv :: Mat描述符1,描述符2;
cv :: BruteForceMatcher< cv :: L2< float>>匹配器;
cv :: vector< cv :: DMatch>火柴;
cv :: Mat img_matches;
detector.detect(input2,keypoints2);
cv :: drawKeypoints(input2,keypoints2,output2);
cv :: imshow(Sift_result2.jpg,output2);
cv :: imwrite(Sift_result2.jpg,output2);
extractor.compute(input1,keypoints1,descriptors1);
extractor.compute(input2,keypoints2,descriptors2);
matcher.match(descriptors1,descriptors2,matches);
//显示结果
cv :: drawMatches(input1,keypoints1,input2,keypoints2,matches,img_matches);
cv :: imshow(matches,img_matches);
cv :: imwrite(matches.jpg,img_matches);
cv :: waitKey();
返回0;
}

问题是有两个比预期多的比赛。我尝试调试程序并查看关键点向量内部的内容,等等,一切看起来都很好,至少我认为它们是关键点,检测方向等。



我正在使用OpenCV v2.3并检查其文档中我正在使用的类的类型,并试图解决问题,但这不起作用。我在这3天的工作并没有太大的改善。



这是我从程序中获得的输出。



我应该删除图像。



我知道不应该给我太多匹配了,因为我用matlab中的另一个实现测试了完全相同的图像,非常好。

解决方案

不要使用BruteForceMatcher尝试使用FlannBasedMatcher,还要计算关键点之间的最大和最小距离,以保持良好匹配。有关示例,请参阅与FLANN进行功能匹配。 / p>

I am trying to implement a program which will input two images one is an image of a box alone and one which includes the box in the scene. Basically, the program is supposed to find keypoints in these two images and will show the images with keypoints matched. That is in the end I expect to see an appended image of two input images together with their matched keypoints connected. My code is as follows:

#include <opencv2\opencv.hpp>
#include <iostream>

int main(int argc, const char* argv[]) {
   cv::Mat input1 = cv::imread("input.jpg", 1); //Load as grayscale
   //cv::cvtColor(input1,input1,CV_BGR2GRAY);
   //second input load as grayscale
   cv::Mat input2 = cv::imread("input2.jpg",1);
   cv::SiftFeatureDetector detector;
   //cv::SiftFeatureDetector
   detector(
      1, 1,
      cv::SIFT::CommonParams::DEFAULT_NOCTAVES,
      cv::SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
      cv::SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
      cv::SIFT::CommonParams::FIRST_ANGLE );
   std::vector<cv::KeyPoint> keypoints1;
   detector.detect(input1, keypoints1);
   // Add results to image and save.
   cv::Mat output1;
   cv::drawKeypoints(input1, keypoints1, output1);
   cv::imshow("Sift_result1.jpg", output1);
   cv::imwrite("Sift_result1.jpg",output1);
   //keypoints array for input 2
   std::vector<cv::KeyPoint> keypoints2;
   //output array for ouput 2
   cv::Mat output2;
   //Sift extractor of opencv
   cv::SiftDescriptorExtractor extractor;
   cv::Mat descriptors1,descriptors2;
   cv::BruteForceMatcher<cv::L2<float>> matcher;
   cv::vector<cv::DMatch> matches;
   cv::Mat img_matches;
   detector.detect(input2,keypoints2);
   cv::drawKeypoints(input2,keypoints2,output2);
   cv::imshow("Sift_result2.jpg",output2);
   cv::imwrite("Sift_result2.jpg",output2);
   extractor.compute(input1,keypoints1,descriptors1);
   extractor.compute(input2,keypoints2,descriptors2);
   matcher.match(descriptors1,descriptors2,matches);
   //show result
   cv::drawMatches(input1,keypoints1,input2,keypoints2,matches,img_matches);
   cv::imshow("matches",img_matches);
   cv::imwrite("matches.jpg",img_matches);
   cv::waitKey();
   return 0;
}

The problem is there are two many many matches than expected. I tried to debug the program and looked what is inside the keypoints vectors and so on, everything looks to be fine, at least I think they are, the keypoints are detected with orientation etc.

I am using OpenCV v2.3 and checked its documentation for the types of classes I am using and tried to solve the problem but that did not work. I am working on this for a 3 days did not make much of an improvement.

Here is an output i get from my program.

I should have remove the image.

I know that should not give me too much matches, because I have tested the exact same images with another implemenation in matlab that was quite good.

解决方案

Rather than using BruteForceMatcher try to use FlannBasedMatcher and also calculate max and min distances between keypoints to keep only the good matches. See "Feature Matching with FLANN" for an example.

这篇关于尝试在OpenCv中使用sift匹配两个图像,但匹配太多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆