bool PatternDetector::refineMatchesWithHomography
    (
    const std::vector<cv::KeyPoint>& queryKeypoints,
    const std::vector<cv::KeyPoint>& trainKeypoints, 
    float reprojectionThreshold,
    std::vector<cv::DMatch>& matches,
    cv::Mat& homography
    )
{
    const int minNumberMatchesAllowed = 8;

    if (matches.size() < minNumberMatchesAllowed)
        return false;

    // Prepare data for cv::findHomography
    std::vector<cv::Point2f> srcPoints(matches.size());
    std::vector<cv::Point2f> dstPoints(matches.size());

    for (size_t i = 0; i < matches.size(); i++)
    {
        srcPoints[i] = trainKeypoints[matches[i].trainIdx].pt;
        dstPoints[i] = queryKeypoints[matches[i].queryIdx].pt;
    }

    // Find homography matrix and get inliers mask
    std::vector<unsigned char> inliersMask(srcPoints.size());
    homography = cv::findHomography(srcPoints, 
                                    dstPoints, 
                                    CV_FM_RANSAC, 
                                    reprojectionThreshold, 
                                    inliersMask);

    std::vector<cv::DMatch> inliers;
    for (size_t i=0; i<inliersMask.size(); i++)
    {
        if (inliersMask[i])
            inliers.push_back(matches[i]);
    }

    matches.swap(inliers);
    return matches.size() > minNumberMatchesAllowed;
}
Exemple #2
0
void CModelQuery2D::computePoseEstimation()
{
    std::vector<cv::DMatch> & validCorr = matchingResults_;

    if ( best_k_sorted_2D_ > 0 )
    {
        std::sort (validCorr.begin (), validCorr.end (),
                   sort2DCorrespondencesByDistance ());

        validCorr.resize(best_k_sorted_2D_);
    }

    vector<cv::KeyPoint>	modelKeyPoints = modelFeatures_.getKeypoints();
    vector<cv::KeyPoint>	queryKeyPoints = queryFeatures_.getKeypoints();

    for ( unsigned i = 0; i < validCorr.size(); i++ )
    {
        modelPoints_.push_back(modelKeyPoints[ validCorr[i].queryIdx].pt);
        queryPoints_.push_back(queryKeyPoints[ validCorr[i].trainIdx].pt);
    }

    vector<unsigned char> inliersMask(modelPoints_.size());

    H_ = findHomography(modelPoints_ , queryPoints_,  CV_RANSAC, inputParams_.ransac_inlier_threshold_2D, inliersMask );
    
    vector<cv::DMatch> inliers;
    unsigned inliersCount = 0;

    for ( unsigned i = 0; i < inliersMask.size(); i++ )
    {
        if ( inliersMask[i] )
        {
            inliersCount++;
            inliers.push_back(validCorr[i]);
        }
    }

    // fill our performance data structure

    perfData  & pd = pGlobalPerf_->pd[descriptorType_];

    pd.descID = descriptorType_;
    pd.actualRotation = inputParams_.rot_deg;
    pd.inlierCount = inliersCount; 
    pd.inlierRate  = (float) inliersCount / validCorr.size(); 

    if ( inputParams_.live_sensor )	// assumes horizontal rotation
    {
        pd.computedRotation = pcl::rad2deg ((atan(H_.at<double>(6)/H_.at<double>(0))));
        // if live_sensor, perfData_.actualRotation is ignored.
    }
    else  // simulated rotation
    {
        pd.computedRotation = pcl::rad2deg ((atan(H_.at<double>(3)/H_.at<double>(0))));
    }

    pd.rotEstError = abs(abs(pd.computedRotation) - abs(pd.actualRotation));

    pd.averageDistance = -1.0;	//## not in use

    if ( inputParams_.debug_level > OUTPUT_TRANSFORMATIONS )
    {
        // print out our H matrix
        pcl::console::print_info ("----------------------------------------------------------------------------\n");
        pcl::console::print_info ("2D DescID: %d,  Computed Rotation: %8.3f, actual Rotation: %8.3f\n",
                                   pd.descID,pd.computedRotation, pd.actualRotation);
        pcl::console::print_info ("inlierCount: %d, inlierRate: %8.3f\n", pd.inlierCount, pd.inlierRate);
        pcl::console::print_info ("\n");
        pcl::console::print_info ("    | %8.3f %8.3f %8.3f | \n", H_.at<double>(0), H_.at<double>(1), H_.at<double>(2) );
        pcl::console::print_info ("R = | %8.3f %8.3f %8.3f | \n", H_.at<double>(3), H_.at<double>(4), H_.at<double>(5) );
        pcl::console::print_info ("    | %8.3f %8.3f %8.3f | \n", H_.at<double>(6), H_.at<double>(7), H_.at<double>(8) );
        pcl::console::print_info ("\n");
    }
}