opencv - OpenCV:基本矩阵精度

标签 opencv image-processing computer-vision camera-calibration reprojection-error

我正在尝试计算2张图像(同一相机拍摄的静态场景的不同照片)的基本矩阵。

我使用 findFundamentalMat 进行了计算,然后使用结果来计算其他矩阵(基本,旋转,...)。结果显然是错误的。因此,我试图确保所计算的基本矩阵的准确性。

使用对极约束方程式,我计算了基本矩阵误差。误差非常高(几百个)。我不知道我的代码有什么问题。我非常感谢您的帮助。特别是:基本矩阵计算中是否缺少任何内容?我计算错误的方式正确吗?

另外,我以完全不同的匹配数运行了代码。通常有很多离群值。例如,在超过80个匹配项的情况下,只有十个内线点。

Mat img_1 = imread( "imgl.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( "imgr.jpg", CV_LOAD_IMAGE_GRAYSCALE );
if( !img_1.data || !img_2.data )
{ return -1; }

//-- Step 1: Detect the keypoints using SURF Detector

int minHessian = 1000;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> keypoints_1, keypoints_2;

detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 );

//-- Step 2: Calculate descriptors (feature vectors)

SurfDescriptorExtractor extractor;
Mat descriptors_1, descriptors_2;
extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 );

//-- Step 3: Matching descriptor vectors with a brute force matcher

BFMatcher matcher(NORM_L1, true);
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches );

vector<Point2f>imgpts1,imgpts2;
for( unsigned int i = 0; i<matches.size(); i++ )
{
    // queryIdx is the "left" image
    imgpts1.push_back(keypoints_1[matches[i].queryIdx].pt);
    // trainIdx is the "right" image
    imgpts2.push_back(keypoints_2[matches[i].trainIdx].pt);
}

//-- Step 4: Calculate Fundamental matrix

Mat f_mask;
Mat F =  findFundamentalMat  (imgpts1, imgpts2, FM_RANSAC, 0.5, 0.99, f_mask);

//-- Step 5: Calculate Fundamental matrix error

//Camera intrinsics
double data[] = {1189.46 , 0.0, 805.49,
                0.0, 1191.78, 597.44,
                0.0, 0.0, 1.0};
Mat K(3, 3, CV_64F, data);
//Camera distortion parameters
double dist[] = { -0.03432, 0.05332, -0.00347, 0.00106, 0.00000};
Mat D(1, 5, CV_64F, dist);

//working with undistorted points
vector<Point2f> undistorted_1,undistorted_2;
vector<Point3f> line_1, line_2;
undistortPoints(imgpts1,undistorted_1,K,D);
undistortPoints(imgpts2,undistorted_2,K,D);
computeCorrespondEpilines(undistorted_1,1,F,line_1);
computeCorrespondEpilines(undistorted_2,2,F,line_2);

double f_err=0.0;
double fx,fy,cx,cy;
fx=K.at<double>(0,0);fy=K.at<double>(1,1);cx=K.at<double>(0,2);cy=K.at<double>(1,2);
Point2f pt1, pt2;
int inliers=0;
//calculation of fundamental matrix error for inliers
for (int i=0; i<f_mask.size().height; i++)
    if (f_mask.at<char>(i)==1)
    {
        inliers++;
        //calculate non-normalized values
        pt1.x = undistorted_1[i].x * fx + cx;
        pt1.y = undistorted_1[i].y * fy + cy;
        pt2.x = undistorted_2[i].x * fx + cx;
        pt2.y = undistorted_2[i].y * fy + cy;
        f_err += = fabs(pt1.x*line_2[i].x +
                pt1.y*line_2[i].y + line_2[i].z)
                + fabs(pt2.x*line_1[i].x +
                pt2.y*line_1[i].y + line_1[i].z);
    }

double AvrErr = f_err/inliers;

最佳答案

我相信问题是因为您仅基于蛮力匹配器计算了基本矩阵,因此您应该针对这些对应点进行更多优化,例如定量测试和对称测试。
我建议您从《 OpenCV2计算机视觉应用程序编程手册》第9章的第233页准备就绪。
它的解释很好!

关于opencv - OpenCV:基本矩阵精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20548353/

相关文章:

python - 如何使用 OpenCV 在 Python 中绘制灰度图像的 32-Bin 直方图

python - 如何停止在 Python 中打印 OpenCV 错误消息

python - 如何使用OPENCV从原始图像中减去图像的 “hue”

Perl 成像器 : how do I make the alpha channel become black insead of white?

python-3.x - Pytesseract 混淆了零 ('0' )和大写 O ('O' )

java - 如何使位图背景透明?

c - 将图像旋转 90 度的算法? (没有额外的内存)

image-processing - 自适应阈值二值化的不良影响

c++ - 使用 OpenCV 的目标检测项目

python - 与 Tensorflow 2.0 同一层的不同尺寸过滤器