OpenCV:使用ORB比较多个图像

时间:2013-03-04 13:26:29

标签: c++ opencv orb

我正在尝试创建一个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 个答案:

答案 0 :(得分:1)

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

否则,您将不得不使用更多实用技术,如尺寸和直方图滤波。您可以查看OpenCV的stitcher,隔离您感兴趣的模块,并根据需要自定义源代码。

答案 1 :(得分:0)

你应该选择非常稳定的通信。我建议阅读:OpenCV 2计算机视觉应用程序设计指南 - 第9章 - 使用随机样本共识(http://opencv-cookbook.googlecode.com/svn/trunk/Chapter%2009/)匹配图像。

答案 2 :(得分:0)

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

/ CV Answer forum

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

RANSAC desctiption Wikipedia

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

答案 3 :(得分:0)

这取决于列表中的图像。对于世界上的每个视力问题,您都无法找到解决方案。例如,我工作的项目需要识别墙壁图片中的材料。你不能只用不同的材料将它与不同的墙壁图片进行比较,并希望得到一个匹配。

就我而言,我需要创建描述符。 Descriptors是输出值的算法,可以与另一个图片的其他值进行比较。在openCV中已经有很多描述符可用,如LBP,SURF等。简单地说,你不再比较图像,你将图像1的描述符的输出值与所有的描述符值进行比较。列表中的图像。

你需要拿起你的眼睛/大脑用来在现实生活中找到匹配的描述符。例如,如果匹配基于颜色,则可以使用CLD或DCD。如果匹配基于纹理,请使用LBP。你也可以像我在我的项目中那样做,并使用大量的描述符,并使用机器学习和训练有素的数据算法来找到最佳匹配。

因此,总而言之,没有可以解决所有视力问题的银弹。您需要根据问题调整解决方案。

希望它有所帮助!