Гомография, вкладыши / Эмгу CV / SURF в C # - PullRequest
4 голосов
/ 09 января 2011

Как я могу получить входящие / исходящие значения совпадающих kyepoints, используя гомографию или другой метод в C #?

Я работаю над примером SURF, предоставленным на http://www.emgu.com/wiki/index.php/SURF_feature_detector_in_CSharp.

Я получил matchedFeature.Код использует 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 #.

Опять же, мне просто нужно разделить выбросы / внутренние.

Ответы [ 3 ]

7 голосов
/ 20 декабря 2012

Если вы хотите разделить выбросы / выбросы и у вас уже есть совпадения, попробуйте это:

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

Обратите внимание, что я нормализовал баллы, чтобы гомографическая оценка была более надежной.

6 голосов
/ 10 января 2011

Ваш вопрос не так понятен, потому что, если вы используете 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 голос
/ 09 января 2011

Подпись 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 #.

...