bool ImageTransformation::findHomography( const Keypoints& source, const Keypoints& result, const Matches& input, Matches& inliers, cv::Mat& homography)
{
    if (input.size() < 8)
        return false;

    std::vector<cv::Point2f> srcPoints, dstPoints;
    const int pointsCount = input.size();

    for (int i=0; i<pointsCount; i++)
    {
        srcPoints.push_back(source[input[i].trainIdx].pt);
        dstPoints.push_back(result[input[i].queryIdx].pt);
    }

    std::vector<unsigned char> status;
    cv::findHomography(srcPoints, dstPoints, CV_FM_RANSAC, 3, status);

    inliers.clear();
    for (int i=0; i<pointsCount; i++)
    {
        if (status[i])
        {
            inliers.push_back(input[i]);
        }
    }

    return true;
}
Пример #2
0
/* 
 * Find the closest match in db, return as element of matches
 */
void SemanticDescriptor::findClosestMatch(Database & db, Matches & matches) 
{
    SemanticDescriptor bestMatch = (*(db.dDB.begin())).first;

    //matches.insert((*(db.dDB.begin())).second);

    SemanticDescriptor compareID;
    int matchStrength;

    map<SemanticDescriptor, string>::iterator iter;
    for (iter = db.dDB.begin(); iter != db.dDB.end(); ++iter) {
        compareID = iter->first;
        matchStrength = closerMatch(compareID, bestMatch, db);
        /* If compareID is a better match, reset matches */
        if (matchStrength > 0)
            if (compareID.coverage(*this, db) >= .5) {
                matches.clear();
                matches.insert(iter->second);
                bestMatch = compareID;
            }
        /* If compareID is an equal match, then add it to the set of matches */
        if (matchStrength == 0)
            if (compareID.coverage(*this, db) >= .5)
                matches.insert(iter->second);
    }
}
Пример #3
0
bool HybridTracker::Localize(const Marker& target, const Frame& scene, Matches& out) {
   vector<cv::DMatch> matches;
   methods.Match(target.descriptor, scene.descriptor, matches);

   out.clear();
   for(auto& it : matches) {
      out._targetPts.push_back(target.keys[it.queryIdx]);
      out._scenePts.push_back(scene.keys[it.trainIdx]);
      out._error.push_back(it.distance);
   }

   return matches.size() > 20;
}
void ratioTest(const std::vector<Matches>& knMatches, float maxRatio, Matches& goodMatches)
{
  goodMatches.clear();

  for (size_t i=0; i< knMatches.size(); i++)
  {
    const cv::DMatch& best = knMatches[i][0];
    const cv::DMatch& good = knMatches[i][1];

    assert(best.distance <= good.distance);
    float ratio = (best.distance / good.distance);

    if (ratio <= maxRatio)
    {
      goodMatches.push_back(best);
    }
  }
}
bool ImageTransformation::findHomography( const Keypoints& source, const Keypoints& result, const Matches& input, Matches& inliers, cv::Mat& homography)
{
    if (input.size() < 4)
        return false;
    
    const int pointsCount = input.size();
    const float reprojectionThreshold = 2;

    //Prepare src and dst points
    std::vector<cv::Point2f> srcPoints, dstPoints;    
    for (int i = 0; i < pointsCount; i++)
    {
        srcPoints.push_back(source[input[i].trainIdx].pt);
        dstPoints.push_back(result[input[i].queryIdx].pt);
    }
      
    // Find homography using RANSAC algorithm
    std::vector<unsigned char> status;
    homography = cv::findHomography(srcPoints, dstPoints, cv::RANSAC, reprojectionThreshold, status);
    
    // Warp dstPoints to srcPoints domain using inverted homography transformation
    std::vector<cv::Point2f> srcReprojected;
    cv::perspectiveTransform(dstPoints, srcReprojected, homography.inv());

    // Pass only matches with low reprojection error (less than reprojectionThreshold value in pixels)
    inliers.clear();
    for (int i = 0; i < pointsCount; i++)
    {
        cv::Point2f actual = srcPoints[i];
        cv::Point2f expect = srcReprojected[i];
        cv::Point2f v = actual - expect;
        float distanceSquared = v.dot(v);
        
        if (/*status[i] && */distanceSquared <= reprojectionThreshold * reprojectionThreshold)
        {
            inliers.push_back(input[i]);
        }
    }
    
    // Test for bad case
    if (inliers.size() < 4)
        return false;
    
    // Now use only good points to find refined homography:
    std::vector<cv::Point2f> refinedSrc, refinedDst;
    for (int i = 0; i < inliers.size(); i++)
    {
        refinedSrc.push_back(source[inliers[i].trainIdx].pt);
        refinedDst.push_back(result[inliers[i].queryIdx].pt);
    }
    
    // Use least squares method to find precise homography
    cv::Mat homography2 = cv::findHomography(refinedSrc, refinedDst, 0, reprojectionThreshold);

    // Reproject again:
    cv::perspectiveTransform(dstPoints, srcReprojected, homography2.inv());
    inliers.clear();

    for (int i = 0; i < pointsCount; i++)
    {
        cv::Point2f actual = srcPoints[i];
        cv::Point2f expect = srcReprojected[i];
        cv::Point2f v = actual - expect;
        float distanceSquared = v.dot(v);

        if (distanceSquared <= reprojectionThreshold * reprojectionThreshold)
        {
            inliers.push_back(input[i]);
        }
    }
 
    homography = homography2;
    return inliers.size() >= 4;
}