2024年5月


一、核心概念

    姿态(欧拉角、旋转矩阵(方向余弦矩阵)、四元数、旋转向量)表示的是一个相对量,即一定是一个坐标系相对另一个坐标系的姿态(角度或旋转)关系,如果只有一个坐标系或一个向量,则毫无意义!



二、位置的相对关系

      位置的相对关系<平移>对应的数学运算:+、-,加法、减法


三、姿态的相对关系

      姿态的相对关系<旋转>对应的数学运算:x、/,乘法、除法(矩阵的逆)


四、位置相等

      两个坐标系位置相等,则位置增量等于:0 ,即两个坐标系原点重合.


五:姿态相等

        两个坐标系姿态相等,即两个坐标系: X、Y、Z三个轴重合.

        1、四元数(单位四元数)

              Quaternion = [1 0 0 0]

              单位四元数对应着单位旋转矩阵!

        2、旋转矩阵(单位矩阵)

            R = [1 0 0 0 1 0 0 0 1]

            AxR=A, 相当于a*1=a














测试背景:

     利用一块棋盘格标定板,和一个装在车辆驾驶室上方的单目相机,然后求解该单目相机离地面的高度以及姿态(相对理想水平面相机坐标系),

采集一张图片,分别用OpenCV的算法与Matlab的算法进行求解,并比较其结果.


一、 棋盘格角点检测比较(使能亚像素角点检测)

      matlab函数:

                        detectCheckerboardPoints()

      opencv函数:

                        cv::findChessboardCorners()和cv::cornerSubPix()


通过绘制角点比较,opencv检测的角点在远处误差较大,检测结果比Matlab要差:







二、PnP问题求解的精度比较

        将Matlab检测的棋盘格角点作为Matlab和OpenCV求解的PnP问题的输入源。通过结果比较,在同样的角点输入的前提下,OpenCV和Matlab对PnP问题的结果精度基本相同,误差很小。













三、棋盘格角点检测比较(关闭亚像素角点检测)

        如果OpenCV不添加亚像素角点检测,其角点检测精度反而更优:

        cv::TermCriteria criteria = cv::TermCriteria( cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 40, 0.001 );

         cv::cornerSubPix(gray, image_points, cv::Size(11,11), cv::Size(-1,-1), criteria);






总结:

        (1): Matlab比OpenCV的求解精度更优,差异主要体现在棋盘格角点的检测更精准;

        (2): 但标定板离相机较远时,如果OpenCV开启亚像素角点检测优化(cv::cornerSubPix),其结果反而更差!!!

        (3): 当OpenCV关闭亚像素检测角点优化代码时,其最终的单目相机外参结果与Matlab的结果误差很小。




1、为了不用手动填写编译源文件,可以采用通配符,让CMake自己搜索


例如:

       file(GLOB  APP_SRCS  "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")


       file(GLOB  LIBPNP_SRCS  "${CMAKE_CURRENT_SOURCE_DIR}/libPnP/src/*.cpp")


       add_library(PnP_Solver  STATIC  ${LIBPNP_SRCS})