如何使用单应性或C#中的其他方法获取匹配的kyepoints的内部/异常值?
我正在研究http://www.emgu.com/wiki/index.php/SURF_feature_detector_in_CSharp上提供的SURF示例。
我得到了匹配功能。代码使用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#中看到类似的代码。
我再次需要异常值/内点分离。
答案 0 :(得分: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]);
}
}
请注意,我对点进行了标准化,因此Homography估计更加稳健。
答案 1 :(得分:6)
你的问题不是那么清楚,因为如果使用emgucv单应性计算,如果有超过10个匹配对,则使用RANSAC使用CameraCalibration.FindHomography()
函数进行估算。
我正在为我的论文研究这些主题,所以我会发布一些相关的代码,这些代码应该完全回复你并且还能为其他人服务。
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);
}
答案 2 :(得分:1)
C#中cvFindFundamentalMat
的签名如下所示:
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 ++代码是如何形成的。