Homography, inliers / Emgu CV / SURF in C #

How can I get inliers / outliers of matching kyepoints using homography or some other method in C #?

I am working on a SURF example provided at http://www.emgu.com/wiki/index.php/SURF_feature_detector_in_CSharp .

I got a match. The code uses HomographyMatrix (homography). I want to separate levels and emissions.

In C ++:

bgroup({findFundamentalMat}) int cvFindFundamentalMat(const CvMat* points1, const CvMat* points2, CvMat* fundamentalMatrix, int method=CV_FM_RANSAC, double param1=1., double param2=0.99, CvMat* status=NULL) 

returns values. Can I see similar code also in C #.

Again, I just need to highlight the emissions / molt.

+4
source share
3 answers

Your question is not so clear, because if you use homgus emgucv computation, it is evaluated using the CameraCalibration.FindHomography() function using RANSAC if there are more than 10 match pairs. I am working on these topics for my dissertation, so I will publish some appropriate code that should fully answer you and serve others.

 result = MatchingRefinement.VoteForSizeAndOrientation(result, 1.5, 20); homography = MatchingRefinement. GetHomographyMatrixFromMatchedFeatures(result, HomographyDirection.DIRECT, HOMOGRAPHY_METHOD.LMEDS); inverseHomography = MatchingRefinement.GetHomographyMatrixFromMatchedFeatures( result, HomographyDirection.INVERSE, HOMOGRAPHY_METHOD.LMEDS); PointF[] pts1 = new PointF[result.Length]; PointF[] pts1_t = new PointF[result.Length]; PointF[] pts2 = new PointF[result.Length]; for (int i = 0; i < result.Length; i++) { pts1[i] = result[i].ObservedFeature.KeyPoint.Point; pts1_t[i] = result[i].ObservedFeature.KeyPoint.Point; pts2[i] = result[i].SimilarFeatures[0].Feature.KeyPoint.Point; } // Project model features according to homography homography.ProjectPoints(pts1_t); Image<Bgr, Byte> finalCorrespondance = inputImage.Copy(); matchedInliersFeatures = new List<MatchedImageFeature>(); for (int i1 = 0; i1 < pts1_t.Length; i1++) { if (Math.Sqrt(Math.Pow(pts2[i1].X - pts1_t[i1].X, 2d) + Math.Pow(pts2[i1].Y - pts1_t[i1].Y, 2d)) <4d) // Inlier { PointF p_t = pts1_t[i1]; PointF p = pts1[i1]; finalCorrespondance.Draw(new CircleF(p, 2f), new Bgr(Color.Yellow), 2); finalCorrespondance.Draw(new CircleF(p_t, 2f), new Bgr(Color.Black), 2); finalCorrespondance.Draw(new LineSegment2DF(p, p_t), new Bgr(Color.Blue), 1); MatchedImageFeature feature = new MatchedImageFeature(); feature.SimilarFeatures = new SimilarFeature[] { result[i1].SimilarFeatures[0] }; feature.ObservedFeature = result[i1].ObservedFeature; matchedInliersFeatures.Add(feature); } } List<ImageFeature> inliers = new List<ImageFeature>(); foreach (MatchedImageFeature match in matchedInliersFeatures) { inliers.Add(match.ObservedFeature); inliers.Add(match.SimilarFeatures[0].Feature); } 
+6
source

If you want to split sheets / emissions and you already have matches, try the following:

 //**RANSAC OUTLIER REMOVAL **// Mat status; vector<Point2f> trainMatches; vector<Point2f> queryMatches; vector<DMatch> inliers; for( int i = 0; i < goodmatches.size(); i++ ) { //-- Get the keypoints from the good matches trainMatches.push_back( cv::Point2f(keypointsB[ goodmatches[i].trainIdx ].pt.x/640.0f, keypointsB[ goodmatches[i].trainIdx ].pt.y/480.0f) ); queryMatches.push_back( cv::Point2f(keypointsA[ goodmatches[i].queryIdx ].pt.x/640.0f, keypointsA[ goodmatches[i].queryIdx ].pt.y/480.0f) ); } Mat _homography; Mat h = cv::findHomography(trainMatches,queryMatches,CV_RANSAC,0.005, status); for(size_t i = 0; i < queryMatches.size(); i++) { if(status.at<char>(i) != 0) { inliers.push_back(goodmatches[i]); } } 

Note that I normalized the points, so the homography score is more reliable.

+7
source

The cvFindFundamentalMat signature in C # will look like this:

 int cvFindFundamentalMat(CvMat points1, CvMat points2, CvMat fundamentalMatrix, CV_FM method, double param1, double param2, CvMat status); 

The default setting was introduced in C # 4.0. I assume that Emgu CV does not support .NET 4.0 yet (correct me if I am mistaken), so one could do an overload providing default values:

 int cvFindFundamentalMat(CvMat points1, CvMat points2, CvMat fundamentalMatrix) { return cvFindFundamentalMat(points1, points2, fundamentalMatrix, CV_FM.CV_FM_RANSAC, 1.0, 0.99, null); } 

Note: as commentators noted, it’s hard to be sure what you are asking. Here, I only guessed that some of your questions were about how the presented C ++ code would look in C #.

+1
source

Source: https://habr.com/ru/post/1334825/


All Articles