代码之家  ›  专栏  ›  技术社区  ›  Alagiri

Opencv Feature Matching无法正确匹配不同大小的裁剪图像和来自不同来源的图像?

  •  1
  • Alagiri  · 技术社区  · 10 年前

    我正在尝试匹配两个图像,一个是手机屏幕截图,模板图像是任何应用程序图标。如果我匹配从相同图像中裁剪的源和模板,那么它将完美匹配。但当我使用从不同手机屏幕截取的应用程序图标时,它不匹配。

    对于图像匹配,我正在处理以下代码:

    int main( int argc, char** argv )
    {
    
    Mat objectImg = imread("source.jpg", cv::IMREAD_GRAYSCALE);
    Mat sceneImg = imread("note4-3.jpg", cv::IMREAD_GRAYSCALE);
    
    //cv::resize(sceneImg,sceneImg,objectImg.size(),0,0,CV_INTER_CUBIC);
    
    if( !objectImg.data || !sceneImg.data )
    {
        printf( " No image data \n " );
        return -1337;
    }
    
    std::vector<cv::KeyPoint> objectKeypoints;
    std::vector<cv::KeyPoint> sceneKeypoints;
    cv::Mat objectDescriptors;
    cv::Mat sceneDescriptors;
    
    Ptr<FeatureDetector> detector;
    detector = cv::MSER::create();
    detector->detect(objectImg, objectKeypoints);
    detector->detect(sceneImg, sceneKeypoints);
    
    Ptr<DescriptorExtractor> extractor = cv::ORB::create();
    extractor->compute( objectImg, objectKeypoints, objectDescriptors );
    extractor->compute( sceneImg, sceneKeypoints, sceneDescriptors );
    
    if(objectDescriptors.type()!=CV_32F) {
    objectDescriptors.convertTo(objectDescriptors, CV_32F);
    }
    
    if(sceneDescriptors.type()!=CV_32F) {
    sceneDescriptors.convertTo(sceneDescriptors, CV_32F);
    }
    
    vector< vector<DMatch> > matches;
    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");
    matcher->knnMatch( objectDescriptors, sceneDescriptors, matches, 8 );
    
    double max_dist = 0; double min_dist = 100;
    
    //-- Quick calculation of max and min distances between keypoints
    for( int i = 0; i < objectDescriptors.rows; i++ )
    { 
        double dist = matches[i][0].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }
    
    std::vector<cv::DMatch> good_matches;
    
    for( int i = 0; i < objectDescriptors.rows; i++ )
    { 
        if( matches[i][0].distance <= max(2*min_dist, 0.02) ) {
            good_matches.push_back( matches[i][0]); 
        }
    
    }
    
    //look whether the match is inside a defined area of the image
    //only 25% of maximum of possible distance
    /*double tresholdDist = 0.50 * sqrt(double(sceneImg.size().height*sceneImg.size().height + sceneImg.size().width*sceneImg.size().width));
    
    vector< DMatch > good_matches2;
    good_matches2.reserve(matches.size());  
    for (size_t i = 0; i < matches.size(); ++i)
    { 
        for (int j = 0; j < matches[i].size(); j++)
        {
            Point2f from = objectKeypoints[matches[i][j].queryIdx].pt;
            Point2f to = sceneKeypoints[matches[i][j].trainIdx].pt;
    
            //calculate local distance for each possible match
            double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y));
    
            //save as best match if local distance is in specified area and on same height
            if (dist < tresholdDist && abs(from.y-to.y)<5)
            {
                good_matches2.push_back(matches[i][j]);
                j = matches[i].size();
            }
        }
    }*/
    
    Mat allmatchs;
       drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,allmatchs,Scalar::all(-1), Scalar::all(-1),vector<char>(),0);
    namedWindow("Matchs" , CV_WINDOW_NORMAL);
    imshow( "Matchs",allmatchs);
    
    waitKey(0);
    
    }
    

    [从不同来源裁剪时匹配错误][1]

    当匹配来自一个移动屏幕快照的源和来自不同屏幕快照的模板时,获得上述结果。

    我正在使用opencv3.0

    请帮助我是否对代码进行了更改,或者我必须使用模板匹配或其他技术。我不能使用SUR检测器,因为我不能使用付费版本,因为许可证冲突??

    示例图像:

    Source Image

    Template

    2 回复  |  直到 10 年前
        1
  •  1
  •   nbsrujan    10 年前

    看看你们提供的图片,我可以建议一些改变,这将帮助你们。

    • 删除选择好的匹配项,这会在出现尖锐特征时产生问题。与其他优秀的比赛相比,犀利的特征具有更少的汉明距离。当选择2*min_dist时,间接忽略了可能的良好匹配。
    • 确保目标图像中有合理数量的特征点。
    • 如果这种特征检测器和描述符组合不起作用,请选择其他特征检测器和描述符,如STAR-BRIEF、SURF,它们比MSER-ORB要好得多。
    • 在您的情况下,检测器匹配器不需要是旋转不变的,它应该是缩放不变的。因此,请尝试重新调整对象图像的大小

    希望我的建议对你有所帮助

        2
  •  0
  •   Alagiri    10 年前

    我通过以下组合获得了更好的匹配: Kaze探测器 Kaze提取器 BruteForce-L1匹配器 结合以下链接中给出的交叉检查匹配

    http://ecee.colorado.edu/~siewerts/extra/ecen5043/ecen5043_code/sift/descriptor_extractor_matcher.cpp

    推荐文章