使用cv::findFundamentalMat要注意的几点
使用cv::findFundamentalMat要注意的几点
//! the algorithm for finding fundamental matrix
enum
{
};
//! finds fundamental matrix from a set of corresponding 2D points
CV_EXPORTS Mat findFundamentalMat( const Mat& points1, const Mat& points2,
//! finds fundamental matrix from a set of corresponding 2D points
CV_EXPORTS_W Mat findFundamentalMat( const Mat& points1, const Mat& points2,
直接用vector<Point2f>传递,在编译时可能不会报错,可是执行时会直接崩溃。
由于cv::Mat的构造函数并不会把Point2f转化为两个浮点数存于Mat的两个元素中,而是仍然以Point2f存于Mat的一个元素中。于是findFundamentalMat一读取这个Mat就会出错。
以下是从匹配好的特征点计算F的代码演示样例:
// vector<KeyPoint> m_LeftKey;
//
// vector<DMatch> m_Matches;
// 以上三个变量已经被计算出来,各自是提取的关键点及其匹配,以下直接计算F
// 分配空间
int ptCount = (int)m_Matches.size();
Mat p1(ptCount, 2, CV_32F);
Mat p2(ptCount, 2, CV_32F);
// 把Keypoint转换为Mat
Point2f pt;
for (int i=0; i<ptCount; i++)
{
}
// 用RANSAC方法计算F
// Mat m_Fundamental;
// 上面这个变量是基本矩阵
// vector<uchar> m_RANSACStatus;
// 上面这个变量已经定义过,用于存储RANSAC后每一个点的状态
m_Fundamental = findFundamentalMat(p1, p2, m_RANSACStatus, FM_RANSAC);
// 计算野点个数
int OutlinerCount = 0;
for (int i=0; i<ptCount; i++)
{
}
// 计算内点
// vector<Point2f> m_LeftInlier;
//
//
// 上面三个变量用于保存内点和匹配关系
int InlinerCount = ptCount - OutlinerCount;
m_InlierMatches.resize(InlinerCount);
m_LeftInlier.resize(InlinerCount);
m_RightInlier.resize(InlinerCount);
InlinerCount = 0;
for (int i=0; i<ptCount; i++)
{
}
// 把内点转换为drawMatches能够使用的格式
vector<KeyPoint> key1(InlinerCount);
vector<KeyPoint> key2(InlinerCount);
KeyPoint::convert(m_LeftInlier, key1);
KeyPoint::convert(m_RightInlier, key2);
// 显示计算F过后的内点匹配
// Mat m_matLeftImage;
// Mat m_matRightImage;
// 以上两个变量保存的是左右两幅图像
Mat OutImage;
drawMatches(m_matLeftImage, key1, m_matRightImage, key2, m_InlierMatches, OutImage);
cvNamedWindow( "Match features", 1);
cvShowImage("Match features", &(IplImage(OutImage)));
cvWaitKey( 0 );
cvDestroyWindow( "Match features" );
加载左右两幅图像后,先用http://blog.sina.com.cn/s/blog_4298002e01013w4z.html一文中所述方法提取特征点并匹配,然后用上面的程序计算基本矩阵。并显示内点匹配。
如图:
初始匹配:
RANSAC过后的内点匹配: