OpenCV:使用ORB比较多个图像

OpenCV: Comparing multiple images using ORB

本文关键字:图像 比较 ORB 使用 OpenCV      更新时间:2023-10-16

我正在尝试创建一个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);

如果有人能指出我必须使用的函数或逻辑,我会非常感激!

这取决于列表中的图像是什么。你不可能对世界上所有的视力问题都有一个解决方案。例如,我所从事的项目需要识别墙壁图片中的材料。你不能只是拿不同材质的墙的不同图片来比较,就指望能找到匹配。

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

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

所以,总而言之,没有什么灵丹妙药可以解决所有的视力问题。你需要根据问题调整你的解决方案。

希望有帮助!

没有直接的答案。为了获得更好的结果,您必须实现某种转换,并在转换后的映射上进行聚类,而不仅仅是将距离相加。这很难,甚至是可以发表的。

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

您应该选择非常稳定的通信。我建议阅读:OpenCV 2计算机视觉应用编程食谱-第9章-使用随机样本一致性匹配图像(http://opencv-cookbook.googlecode.com/svn/trunk/Chapter%2009/)。

对您的问题进行简短搜索后,我在opencv答案部分找到了以下条目:

/CV答案论坛

似乎为你的问题提供了答案。为了过滤你得到的答案中建议的结果,我会看看RANSAC算法,在你的匹配选择中找到最好的结果。

RANSAC描述Wikipedia