【opencv】教程代码 —features2D(3)Homography—分解单应性矩阵

decompose_homography.cpp 分解单应性矩阵

1f3cf8759d2a1979c1054e4d24bfe9c1.jpeg

left01.jpg  boardSize:9x6  squareSize:0.025

b5dda4984f7911928b3769da8026b2c1.jpeg

left02.jpg

92de7d4b88c7756e55cb3eb041aa944e.png

c31a1fe2f8c8c527266998e13bb16387.png

相机内参

1eaf211b2dced8899b341b6ae026820c.png

#include <iostream> // 引入输入输出流库
#include <opencv2/core.hpp> // 引入OpenCV的核心功能头文件
#include <opencv2/highgui.hpp> // 引入OpenCV的GUI功能头文件
#include <opencv2/calib3d.hpp> // 引入OpenCV的相机标定和三维重建功能头文件


using namespace std; // 使用标准命名空间,例如std::vector可以省略std::
using namespace cv; // 使用opencv命名空间,例如cv::Mat可以省略cv::


namespace // 匿名命名空间
{
// 定义了几种标定板的模式的枚举类型
enum Pattern { CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID };


// 函数用于计算棋盘格的角点
void calcChessboardCorners(Size boardSize, float squareSize, vector<Point3f>& corners, Pattern patternType = CHESSBOARD)
{
    corners.resize(0); // 清空角点向量


    // 根据不同的标定板类型计算角点
    switch (patternType) {
    case CHESSBOARD:
    case CIRCLES_GRID:
        // 对于棋盘格和圆点网格,遍历每行每列生成角点
        for( int i = 0; i < boardSize.height; i++ )
            for( int j = 0; j < boardSize.width; j++ )
                corners.push_back(Point3f(float(j*squareSize),
                                          float(i*squareSize), 0));
        break;


    case ASYMMETRIC_CIRCLES_GRID:
        // 对于非对称圆点网格,遍历每行每列生成角点,同时考虑横向位置的偏移
        for( int i = 0; i < boardSize.height; i++ )
            for( int j = 0; j < boardSize.width; j++ )
                corners.push_back(Point3f(float((2*j + i % 2)*squareSize),
                                          float(i*squareSize), 0));
        break;


    // 如果模式类型未知则报错
    default:
        CV_Error(Error::StsBadArg, "Unknown pattern type\n");
    }
}


// 计算单应性矩阵的函数,基于旋转矩阵、平移向量、平面到相机的逆距离和平面的法向量
Mat computeHomography(const Mat &R_1to2, const Mat &tvec_1to2, const double d_inv, const Mat &normal)
{
    Mat homography = R_1to2 + d_inv * tvec_1to2*normal.t(); // 计算单应性矩阵
    return homography; // 返回计算出的单应性矩阵
}


// 根据两次相机位姿计算两个相机之间的位姿关系
void computeC2MC1(const Mat &R1, const Mat &tvec1, const Mat &R2, const Mat &tvec2,
                  Mat &R_1to2, Mat &tvec_1to2)
{
    //c2Mc1 = c2Mo * oMc1 = c2Mo * c1Mo.inv()
    R_1to2 = R2 * R1.t(); // 计算旋转矩阵
    tvec_1to2 = R2 * (-R1.t()*tvec1) + tvec2; // 计算平移向量
}


// 主函数,使用两个图像、棋盘格大小、方块大小和内参路径进行标定板的单应性分解
void decomposeHomography(const string &img1Path, const string &img2Path, const Size &patternSize,
                         const float squareSize, const string &intrinsicsPath)
{
    // 根据路径读取两张图像
    Mat img1 = imread( samples::findFile( img1Path) );
    Mat img2 = imread( samples::f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值