8

我正在尝试创建一个 C++ 程序,与一个输入图像相比,列表中有很多图像。我得到了整个工作,程序正在创建DMatch匹配项。

现在我正在尝试确定与源图像进行比较的图像列表中的哪一个是最佳匹配。我首先尝试通过比较图像之间有多少匹配来做到这一点,但问题是当生成的图像有很多关键点时;他们也往往有很多比赛,至少在我的节目中。

那么如何确定图像数组中的哪一个与源图像最匹配?我正在使用此循环来确定匹配项,但它并没有真正起作用:

vector< vector<DMatch> > filteredMatches;
vector<int> goodIds;
Ptr<DescriptorMatcher> matcher(new BFMatcher(NORM_HAMMING, false));

printf("bad matches: ");

for(size_t i = 0; i < images.size();i++){
    vector<DMatch> matches, good_matches;

    matcher->clear();
    matcher->match(images[i], tex_des, matches);
    if(matches.size() < 8){
        printf("F%d,", (int)i + 1);
        continue;
    }

    double min_dist = 100;

    for(size_t j = 0; j < matches.size(); j++ ){ 
        double dist = matches[j].distance;
        if( dist < min_dist ) 
            min_dist = dist;
    }

    if(min_dist > 50.0){
        printf("D%d,", (int)i + 1);
        continue;
    }

    double good_dist = min_dist * 3;
    for(size_t j = 0; j < matches.size(); j++ ){
        if(matches[j].distance < good_dist)
            good_matches.push_back(matches[j]);
    }

    size_t size = good_matches.size();
    if(size < 8){
        printf("M%d,", (int)i + 1);
        continue;
    }

    vector<Point2f> srcPoints(size);
    vector<Point2f> dstPoints(size);

    for(size_t j = 0; j < size; j++){
        srcPoints[j] = destination[good_matches[j].trainIdx].pt;    
        dstPoints[j] = keyPoints[i][good_matches[j].queryIdx].pt;   
    }

    vector<unsigned char> inliersMask(srcPoints.size());
    Mat H = findHomography(srcPoints, dstPoints, CV_FM_RANSAC, 3.0, inliersMask);

    vector<DMatch> inliers;
    for(size_t j = 0; j < inliersMask.size(); j++){
        if(inliersMask[j]){
            inliers.push_back(good_matches[j]);
        }
    }
    if(inliers.size() < 4){
        printf("S%d,", (int)i + 1);
        continue;
    }

    filteredMatches.push_back(inliers);
    goodIds.push_back((int)i);

    H.release();
}

printf(" good matches: ");

int best = -1;
int amount = 0;
for(size_t i = 0; i < filteredMatches.size(); i++){
    int size = (int)filteredMatches.at(i).size();
    if(size < 8) continue;

    printf("%d,", goodIds[i] + 1);

    if(amount < size){
        amount = size;
        best = i;
    }
}

if(best >= 0) printf(" best match on image: %d, keypoints: %d, ", goodIds[best] + 1, amount);

如果有人能指出我必须使用的功能或逻辑,我将不胜感激!

4

4 回答 4

1

没有任何直截了当的答案。为了获得更好的结果,您必须实施某种变换并在变换后的地图上进行聚类,而不仅仅是对距离求和。这很困难,甚至可以发表

否则,您将不得不使用更实用的技术,例如维度和直方图过滤。你可以看看OpenCV的stitcher,隔离你感兴趣的模块,并根据你的需要定制源代码。

于 2013-03-12T15:51:30.500 回答
1

It depends what are the image in the list. You can't have one solution for every vision problem in the world. For example, the project I work on needs to recognize material in pictures of walls. You can't just compare it to different picture of wall with different material and hope to get a match.

In my case, I needed to create descriptors. Descriptors are algorithm that output value that can be compared to other value of another picture. There are a lot of descriptors already available in openCV like LBP, SURF, etc.. To put it simply, you don't compare the image anymore, you compare the output value of the descriptor of image 1 to the descriptor value of all the image in the list.

You need to pick up the descriptors that your eyes/brain use to find a match in real life. For example, if the matching is based on color, you could use CLD or DCD. If the matching is based on texture, use LBP. You can also do like I did in my project and use a lot of descriptor and use Machine Learning with trained data algorithms to find the best match.

So, to summarize, there is no silver bullet that can fix all vision problem. You need to adapt your solution to the problem.

Hope it helps!

于 2013-03-12T15:42:46.343 回答
0

你应该只选择真正稳定的对应关系。我建议阅读:OpenCV 2 Computer Vision Application Programming Cookbook - 第 9 章 - 使用随机样本共识匹配图像(http://opencv-cookbook.googlecode.com/svn/trunk/Chapter%2009/)。

于 2013-03-11T16:47:53.743 回答
0

对您的问题的简短搜索为我提供了 opencv 答案部分中的以下条目:

/简历答疑论坛

这似乎为您似乎遇到的问题提供了答案。要按照答案中的建议过滤您得到的结果,我会查看 RANSAC 算法,以在您的匹配选择中找到最佳结果。

RANSAC 说明维基百科

至少这应该为您指明正确的方向。

于 2013-03-12T07:57:22.730 回答