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; }
MatchPersistence MatchPersistenceFromJSON(const Value &value) { auto executableName = value["executableName"].GetString(); auto matcherName = value["matcherName"].GetString(); auto executableArchitecture = value["executableArchitecture"].GetString(); auto realTime = value["realTime"].GetDouble(); auto cpuTime = value["cpuTime"].GetDouble(); Matches matches; auto &matchesValue = value["matches"]; for (rapidjson::SizeType i = 0; i < matchesValue.Size(); ++i) { auto match = MatchFromJSON(matchesValue[i]); if (match) { matches.push_back(match); } } return MatchPersistence(executableName,matcherName,executableArchitecture,realTime,cpuTime,matches); }
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); } } }
/* * Function: initRouteMatrix() * Comments: Initializes global route matrix for this Solution */ void Solution::initRouteMatrix() { if(matrixInitType == FLUSH || myInternalMatrix.use_count() == 0) { Matches matches; Riders riders; for(MatchesMap::iterator it = myMatches.begin(); it != myMatches.end(); it++) { matches.push_back(it->second); for(Riders::iterator rider = it->second.confirmedRiders.begin(); rider != it->second.confirmedRiders.end(); rider++){ riders.push_back(*rider); } } for(RidersMap::iterator it = myRiders.begin(); it != myRiders.end(); it++) { riders.push_back(it->second); } Drivers emptyDrivers; if(useLocalMatrix){ myInternalMatrix.reset(new RouteMatrixLocal(emptyDrivers,riders,matches)); }else{ myInternalMatrix.reset(new RouteMatrix<>(emptyDrivers,riders,matches)); } } else { //std::cout << "Using old route Matrix" <<std::endl; } routeMatrix = myInternalMatrix; }
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; }