2011-01-09 17 views
4

C#でホモグラフィや他の方法を使用して一致するキープポイントのinliers/outliersを取得するにはどうすればよいですか?ホモグラフィ、inliers/Emgu CV/SURF in C#

http://www.emgu.com/wiki/index.php/SURF_feature_detector_in_CSharpで提供されているSURFの例で作業しています。

私はマッチしたフィーチャーを得ました。コードはHomographyMatrix(ホモグラフィ)を使用します。私はinliersとoutliersを分離したいと思っています。 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#でもシンプルなコードを見ることはできますか?

もう一度、私は外れ値と内位値の分離が必要です。 C#で

+1

何ですか?この質問は混乱です。あなたのコードの一部でもないコメントがあります。そしてあなたが何を求めているかは非常に不明です。 –

+0

私はまだ断りません... – leppie

答えて

6

emgucvホモグラフィ計算を使用している場合は、一致するペアが10個以上ある場合はCameraCalibration.FindHomography()関数を使用してRANSACを使用して計算されるため、疑問がありません。 私は自分の論文のためにこれらの話題に取り組んでいますので、私はあなたに完全に返答し、他の人にも役立つ関連コードを投稿します。

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のシグネチャは次のようになります。

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

パラメータのデフォルト値は、C#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); 
} 

注:コメンターも述べたように、それは私がEmgu CVはまだ(私が間違っているなら、私を修正)、これはデフォルト値を提供し、過負荷を作ることができる.NET 4.0をサポートしていないと仮定しますあなたが求めていることを確かめるのは難しいです。ここでは、あなたの質問のいくつかは、提供されたC++コードがどのようにC#のように見えるかということだけを推測しました。

+0

Thanx、このヘルプ用です。なぜあなたがステータス(Null)を使用しているのか説明が必要です。 PointF形式のポイントがあります。私はそれらから行列を作らなければならないのですか?マトリックス円=新しいマトリックス(長さ、1,2);または行列円=新しい行列(長さ、2、1); – Shahgee

+0

status == nullは、C++シグネチャのデフォルト値がnullだったからです。 –

+0

しかし、もしあなたが 'PointF'データを持っていれば、それらを' CvMat'構造体に最初に変換する必要があります。 –

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

注意。