2011-01-09 55 views
4

如何在C#中使用單應性或其他某種方法獲得匹配接點的內點/異常值?C中的inlier/Emgu CV/SURF中的單反相機#

我在SURF示例上提供http://www.emgu.com/wiki/index.php/SURF_feature_detector_in_CSharp

我matchedFeature。 Code使用HomographyMatrix(單應性)。我想分離內點和外點。

在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) 

返回正常值。我可以在C#中看到類似的代碼嗎?

再次我只是需要異常值/正常值分離。

+1

什麼?這個問題很混亂。有一個評論甚至不是你的代碼的一部分。而且你不清楚你在問什麼。 – 2011-01-09 16:30:00

+0

我仍然無能爲力... – leppie 2011-01-09 17:59:47

回答

6

你的問題並不那麼清楚,因爲如果你使用emgucv單應性計算,估計使用CameraCalibration.FindHomography()函數使用RANSAC,如果有超過10個匹配對。 我正在研究我的論文的這些主題,所以我會發布一些相關的代碼,應該完全回覆你,併爲其他人服務。

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); 
} 
1

cvFindFundamentalMat C#中的簽名是這樣的:在

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

參數默認引入C#4.0。我認爲Emgu CV不支持.NET 4.0,但(糾正我,如果我錯了),從而提供了默認值的過載可以作出:

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

注:作爲評論者也都表示,這是很難確定你要求什麼。在這裏,我剛剛猜到,你的一些問題是如何在C#中提供C++代碼。

7

如果你想正常值/離羣分離,你已經有你的比賽試試這個:

//**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]); 
     } 
    } 

注意,我歸點所以單應估計更強勁。