void getMatches(cv::BFMatcher &m_matcher, const cv::Mat &trainDescriptors, const cv::Mat& queryDescriptors, std::vector<cv::DMatch>& good_matches) { std::vector<std::vector<cv::DMatch> > m_knnMatches; good_matches.clear(); // To avoid NaNs when best match has // zero distance we will use inverse ratio. const float minRatio =1.f / 1.5f; // KNN match will return 2 nearest // matches for each query descriptor m_matcher.knnMatch(trainDescriptors, queryDescriptors, m_knnMatches,10); for (size_t i=0; i < m_knnMatches.size(); i++) { const cv::DMatch& bestMatch = m_knnMatches[i][0]; const cv::DMatch& betterMatch = m_knnMatches[i][1]; float distanceRatio = bestMatch.distance / betterMatch.distance; // Pass only matches where distance ratio between // nearest matches is greater than 1.5 // (distinct criteria) if (distanceRatio < minRatio) { good_matches.push_back(bestMatch); } } }
cv::Point2f calcLocation(cv::Mat query_img) { std::vector<cv::KeyPoint> kp_query; // Keypoints of the query image cv::Mat des_query; cv::Mat query_img_gray; cv::cvtColor(query_img, query_img_gray, cv::COLOR_BGR2GRAY); detector->detectAndCompute(query_img_gray, cv::noArray(), kp_query, des_query); std::vector< std::vector<cv::DMatch> > matches; matcher.knnMatch(des_ref, des_query, matches, 2); std::vector<cv::KeyPoint> matched_query, matched_ref, inliers_query, inliers_ref; std::vector<cv::DMatch> good_matches; //-- Localize the object std::vector<cv::Point2f> pts_query; std::vector<cv::Point2f> pts_ref; for(size_t i = 0; i < matches.size(); i++) { cv::DMatch first = matches[i][0]; float dist_query = matches[i][0].distance; float dist_ref = matches[i][1].distance; if (dist_query < match_ratio * dist_ref) { matched_query.push_back(kp_query[first.queryIdx]); matched_ref.push_back(kp_ref[first.trainIdx]); pts_query.push_back(kp_query[first.queryIdx].pt); pts_ref.push_back(kp_ref[first.trainIdx].pt); } } cv::Mat mask; // Homograpy cv::Mat homography; homography = cv::findHomography(pts_query, pts_ref, cv::RANSAC, 5, mask); // Input Quadilateral or Image plane coordinates std::vector<cv::Point2f> centers(1), centers_transformed(1); cv::Point2f center(query_img_gray.rows / 2, query_img_gray.cols / 2); cv::Point2f center_transformed(query_img.rows / 2, query_img.cols / 2); centers[0] = center; // Workaround for using perspective transform cv::perspectiveTransform(centers, centers_transformed, homography); center_transformed = centers_transformed[0]; return center_transformed; }