https://www.cnblogs.com/wangguchangqing/p/8214032.html
OpenCV 计算基础矩阵
上面写了那么多基础矩阵的计算方法,在OpenCV中也就是一个函数的封装
Mat cv::findFundamentalMat(InputArray points1,
InputArray points2,
int method = FM_RANSAC,
double param1 = 3.,
double param2 = 0.99,
OutputArray mask = noArray()
)
其中,points1,points2是匹配点对的像素坐标,并且能够一一对应。method表是使用那种方法,默认的是FM_RANSAC也就是RANSAC的方法估算基础矩阵。param1表示RANSAC迭代过程中,判断点是内点还是外点的阈值(到对极线的像素距离);param2表示内点占的比例,以此来判断估计出的基础矩阵是否正确。
// RANSAC 计算基础矩阵F
Mat F;
F = findFundamentalMat(ps1, ps2, FM_RANSAC);//还有7点,8点法等等。
cout << "基础矩阵F:" << endl << F << endl;
这里的F是受ps1,ps2位置影响的,换位置会改变F,此时的F是第一幅图在左,第二幅图在右边的F。即为存在左右关系。
通过两视图的对极几何可知,所有的对极线相交于对极点,可以以此来验证估计的基础矩阵是否正确。在OpenCV中也封装了计算对极线的方法computeCorrespondEpilines,
vector<Vec3f> lines1;//line为(a,b,c) ax+by+c=0(图像坐标系)
computeCorrespondEpilines(ps1, 1, F, linesl);
for (auto it = linesl.begin(); it != linesl.end(); it++)
{
line(img1, Point(0, -(*it)[2] / (*it)[1]), Point(img1.cols, -((*it)[2] + (*it)[0] * img1.cols) / (*it)[1]), Scalar(255, 255, 255));
}
imshow("第一幅图像的对极线", img1);
computeCorrespondEpilines(ps1, 1, F, linesl);
这里的1表示第一幅图上的点对应的极线在第二幅图画线,改成2后会导致特征点不在极线上
vector<Vec3f> lines2;
computeCorrespondEpilines(ps2, 2, F, lines2);
for (auto it = lines2.begin(); it != lines2.end(); it++)
{
line(img2, Point(0, -(*it)[2] / (*it)[1]), Point(img2.cols, -((*it)[2] + (*it)[0] * img2.cols) / (*it)[1]), Scalar(255, 255, 255));
}
imshow("第二幅图像的对极线", img2);