OpenCV RANSAC 和 LMeDS 都制作了一个大小为 0 的基本矩阵

Posted

技术标签:

【中文标题】OpenCV RANSAC 和 LMeDS 都制作了一个大小为 0 的基本矩阵【英文标题】:OpenCV Both RANSAC and LMeDS making an essential matrix of size 0 【发布时间】:2021-12-15 09:21:09 【问题描述】:

我试图使用findEssentialMat 函数生成一个基本矩阵并不断得到一个空矩阵,即使概率非常低且阈值很高。我制作了可重现的代码,试图从静止图像中计算基本矩阵,但我仍然没有得到基本矩阵。我不确定为什么会这样。

代码:

int main(int argc, char** argv) 

    Mat in = imread("test.jpg", IMREAD_GRAYSCALE);

    std::vector<KeyPoint> keypoints;
    std::vector<Point2f> points;
    std::vector<Point2f> prevPoints;
    std::vector<uchar> status;

    points = featureDetection(in, keypoints, 30);
    prevPoints = std::vector<Point2f>(points);

    double focal = 0;
    Point2d opticalCenter(in.rows / 2, in.cols / 2);
    
    // Track features
    featureTracking(in, in, points, prevPoints, status);

    // FIXME RANSAC algorithm not working. Try LMEDS?
    Mat E, mask;
    E = findEssentialMat(points, prevPoints, focal, opticalCenter, RANSAC, 0.001, 100.0, mask);
    Mat R, t;
    if(E.size().area() == 0) 
        std::cout << mask.size().area() << " points, essential matrix is empty\n";
     else 
        recoverPose(E, points, prevPoints, R, t, focal, opticalCenter, mask);
    

    // Draw tracked features (this frame)
    for(int i = 0; i < prevPoints.size(); i++) 
        // Tracking lines
        line(in, points[i], prevPoints[i], Scalar(0, 100, 0), 5, LineTypes::LINE_4);
      

    // Show output
    imshow("Data", in);
    char c = waitKey(0);

    imwrite("out.jpg", in);
std::vector<Point2f> featureDetection(const Mat& imgIn, std::vector<KeyPoint>& pointsOut, int threshold)     
    bool nonmaxSuppression = true;
    FAST(imgIn, pointsOut, threshold, nonmaxSuppression);
    std::vector<Point2f> points(0);
    for(KeyPoint p : pointsOut) 
        points.push_back(p.pt);
    
    return points;

void featureTracking(const Mat& img_1, const Mat& img_2, std::vector<Point2f>& points1, std::vector<Point2f>& points2, std::vector<uchar>& status)   

    //this function automatically gets rid of points for which tracking fails

    std::vector<float> err;                 
    Size winSize=Size(21,21);                                                                                               
    TermCriteria termcrit=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01);

    cv::calcOpticalFlowPyrLK(img_1, img_2, points1, points2, status, err, winSize, 3, termcrit, 0, 0.001);

    //getting rid of points for which the KLT tracking failed or those who have gone outside the frame
    int indexCorrection = 0;
    for( int i=0; i<status.size(); i++) 
        Point2f pt = points2.at(i- indexCorrection);
        if ((status.at(i) == 0)||(pt.x<0)||(pt.y<0)) 
            if((pt.x<0)||(pt.y<0))  
                status.at(i) = 0;
            
            points1.erase (points1.begin() + i - indexCorrection);
            points2.erase (points2.begin() + i - indexCorrection);
            indexCorrection++;
        
    

输入:

输出(用*表示的标记):

我正在使用为 MinGW 构建的 OpenCV 4.5.4

【问题讨论】:

【参考方案1】:

看起来 findEssentialMat 函数在焦距为 0 时不起作用,将其设置为 1 解决了问题!

【讨论】:

以上是关于OpenCV RANSAC 和 LMeDS 都制作了一个大小为 0 的基本矩阵的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV RANSAC 每次都返回相同的转换

(转载)利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较) 置顶

如何检索findHomography和RANSAC计算出的同分布点?

用RANSAC算法实现干扰严重的直线拟合~

视觉SLAM之RANSAC算法用于消除图像误匹配的原理

如何抑制 OpenCV 错误消息