正确使用StereoRectify

2023-05-16

双目矫正的使用

cv::fisheye::StereoRectify()函数, 主要用于对双目图像做出矫正,计算出用于立体矫正的参数;具体的使用方法如下:


void cv::fisheye::stereoRectify	(InputArray K1,InputArray D1,
                                 InputArray K2, InputArray D2,
                                 const Size &imageSize, InputArray R, 
                                 InputArray tvec, 
                                 OutputArray 	R1,OutputArray 	R2,
                                 OutputArray P1, OutputArray P2, OutputArray Q, 
                                 int flags, const Size &newImageSize = Size(), 
                                 double balance = 0.0, double fov_scale = 1.0)	

其中参数的含义如下:

K1第一个相机的内参,Size为3x3, 数据类型为CV_32F 或者 CV_64F
D1第一个相机的畸变参数, Size必须为4x1, 数据类型为CV_32F 或者 CV_64F
K2第二个相机的内参,Size为3x3, 数据类型为CV_32F 或者 CV_64F
D2第二个相机的畸变参数, Size必须为4x1, 数据类型为CV_32F 或者 CV_64F
imageSize做双目标定StereoCalibration() 时用的图片的size, 如ImageSize = cv::Size(640,480)
R两个相机之间的旋转矩阵, Rrl, 如果内参采用Kalibr标定, 那么这里的R就是Kalibr标定出的T的前3x3
tvec两个相机之间的平移向量,trl, 即为左目相机在右目相机坐标系中的坐标, 所以,如果两个相机左右摆放, 该向量中x值一般为负数;
R1第一个相机的修正矩阵, 即从实际去畸变后的左目摆放位姿到经过极线矫正后的左目位姿之间, 有一个旋转量,为R1
R2第二个相机的修正矩阵, 即从实际去畸变后的右目摆放位姿到经过极线矫正后的右目位姿之间, 有一个旋转量,为R2
P1修正后第一个相机的投影矩阵; P1包含了R1和K1, 可直接将左目相机坐标系的三维点,投影到像素坐标系中; 要注意会投影到修正后的图像中
P2修正后第二个相机的投影矩阵; P2包含了R2和K2, 可直接将左目相机坐标系的三维点,投影到像素坐标系中; 要注意会投影到修正后的图像中
Q视差图转换成深度图的矩阵; 
flagsOperation flags that may be zero or fisheye::CALIB_ZERO_DISPARITY . If the flag is set, the function makes the principal points of each camera have the same pixel coordinates in the rectified views. And if the flag is not set, the function may still shift the images in the horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the useful image area.
newImageSize修正后图像的新Size.  该参数应该与下一步使用initUndistortRectifyMap()时所使用的iMAGE SIZE一致. 默认为 (0,0), 表示和 imageSize 一致. 当图像的径向畸变较严重时, 这个值设置的大一点,可以更好地保留一个细节;  (see the stereo_calib.cpp sample in OpenCV samples directory)
balance值在[0,1]之间, 设置这个值可以改变新图像的focal length, 从最小值到最大值之间变动;
fov_scale新的focal length = original focal length/ fov_scale

遇到的一些问题:

 Assertion failed (D.empty() || ((D.total() == 4) && (D.depth() == 5 || D.depth() == 6))) in estimateNewCameraMatrixForUndistortRectify, file Downloads/opencv-3.4.0/modules/calib3d/src/fisheye.cpp, line 545

问题的原因就是括号里的内容, 按照函数的要求D应该是4x1的Mat, 但是我实际输入的是5x1, 所以出错;

具体原因也可以到提示中的源码里查找, 找到出错的地方即为estimateNewCameraMatrixForUndistortRectify() 里面; 

void cv::fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,
    OutputArray P, double balance, const Size& new_size, double fov_scale)
{
    CV_INSTRUMENT_REGION();

    CV_Assert( K.size() == Size(3, 3)       && (K.depth() == CV_32F || K.depth() == CV_64F));
    CV_Assert(D.empty() || ((D.total() == 4) && (D.depth() == CV_32F || D.depth() == CV_64F)));
}

Mat相关的小细节

Mat::depth 返回一个矩阵元素的深度; 返回值只能是标识符, 具体类型对应的标识符如下:

// <interface.h>
#define CV_8U   0  //8位无符号整数 (0…..255)
#define CV_8S   1  //8位符号整数   (-128...127)
#define CV_16U  2  //16位无符号整数 (0...65535)
#define CV_16S  3  //16位符号整数 (-32768...32767)
#define CV_32S  4  //32为符号整数 (-2147483648...2147483648)
#define CV_32F  5  //32位浮点数  (-FLT_MAX...FLX_MAX)
#define CV_64F  6  //64位浮点数  (-DBL_MAX...DBL_MAX)
#define CV_16F  7  //16位浮点数

Mat::total 返回数组元素的总数; 

如4x1的矩阵会返回4; 3x2的矩阵会返回6;

最后, 举个栗子:

//设定左目内参和畸变参数: 分别是3x3和4x1
Mat cameraMatrixL =(Mat_<double>(3, 3) << 216.0891385028069, 0., 319.19103592168216, 0.,286.915780332698, 237.28788884900933, 0., 0., 1.);

Mat distCoeffL =(Mat_<double>(4, 1) << 0.16031814840882294, 0.09948097914060017,
                                      -0.05647543763319335, 0.02313587059407878);
//设定右目内参和畸变参数: 分别是3x3和4x1
Mat cameraMatrixR =(Mat_<double>(3, 3) << 216.47145152004367, 0., 319.57751832884156, 0.,287.23866506549973, 240.30796467665027, 0., 0., 1.);

Mat distCoeffR = (Mat_<double>(4, 1) << 0.15400500709721424, 0.109194432654468,
                                      -0.06512886784397008, 0.025788980687450808);
//设定两个相机之间的旋转和平移, R为Rrl
Mat R = (Mat_<double>(3, 3) << 
        0.9998867545031103, -0.007295111520593036,0.013162808102250304, 
        0.007472043953567141, 0.9998817186236534,-0.01344311427322331, 
        -0.013063182169384159, 0.013539944981760093,0.9998229959155261);
//从平移的数值应该能看出来, t为 左目相机在右目相机的坐标系中的位置
Mat T = (Mat_<double>(3, 1) << 
        -0.10139343341319906, -0.0003237508769501881,0.0013986876758678593);

Mat Rl, Rr, Pl, Pr, Q;

cv::fisheye::stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize,R, T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY, imageSize);
//使用R1,P1输出两个映射矩阵
cv::fisheye::initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pl, 
                                     imageSize,CV_32FC1, mapLx, mapLy);
//使用R2,P2输出两个映射矩阵
cv::fisheye::initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, 
                                     imageSize,V_32FC1, mapRx, mapRy);
Mat ImageL, ImageR;
ImageL = cv::imread("left.png",-1);
ImageR = cv::imread("right.png", -1);
//将双目矫正后的图像放入rectifyImageL2和rectifyImageR2中
Mat rectifyImageL2, rectifyImageR2;
cv::remap(ImageL, rectifyImageL2, mapLx, mapLy, cv::INTER_LINEAR);
cv::remap(ImageR, rectifyImageR2, mapRx, mapRy, cv::INTER_LINEAR);

tips:

在使用的时候一定要注意自己使用的是cv::fisheye::StereoRectify()函数, 还是cv::StereoRectify(), 这点很重要, 因为函数不同,所使用的畸变模型是不一样的;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

正确使用StereoRectify 的相关文章

随机推荐

  • 「最全」电子元器件图片、名称、符号图形对照(精编请收藏)

    点击上方 大鱼机器人 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 xff01 一 电阻系列 电阻器 xff08 Resistor xff09 是一个限流元件 xff0c 用字母R来表示 xff0c 单位为欧姆 将
  • Karto_slam跑激光雷达(北阳ust-10lx下一篇介绍使用)

    0 当前配置 Ubuntu 16 04ROS KineticOpencv 3 4 1Ceres solvergcc version 5 4 0 20160609 g 43 43 Eigen3 G2O 1 前言 本人当下在学习slam kar
  • 串级PID控制四轴飞行状态-分析

    参考网页 xff1a http blog csdn net nemol1990 article details 45131603 一 概念 单极PID xff1a 当你知道系统当前状态和期望状态后 xff0c 如何将系统从当前状态调整到期望
  • Ubuntu18.04安装Nvidia显卡驱动,CUDA+CUDNN,完整Qt,编译安装OpenCV4.1.1 with CUDA and Qt

    目录 N卡无法开机问题一 安装Nvidia显卡驱动1 禁用安全引导2 禁用默认驱动程序3 添加Nvidia驱动源4 安装驱动 二 安装CUDA和CUDNN1 下载2 安装3 配置环境变量4 测试CUDA5 下载 xff0c 安装CUDNN
  • 纯C语言实现仿C++STL泛型链表

    声明 本代码完全开源 xff0c 可以用于任意用途 xff0c 但代码并未做完善的测试 xff0c 性能也不能保障 xff0c 主要用于初学者学习 源码链接 xff1a GitHub 一 原理 普通的单向链表的原理就是一个节点存储着数据和指
  • Ubuntu上使用CLion开发STM32,并使用JLink下载、调试

    目录 一 环境准备二 下载STM32CubeMX固件库三 使用STM32CubeMX创建工程四 CLion配置五 CMake简单操作和添加DSP库CMake简单操作添加DSP库 五 调试时查看外设寄存器 六 使用JLinkGDBServer
  • C++进阶——STL源码之迭代器(iterators)

    STL迭代器 在 STL 编程中 xff0c 容器和算法是独立设计的 xff0c 即数据结构和算法是独立设计的 xff0c 连接容器和算法的桥梁就是迭代器了 xff1a 迭代器是一种行为类似指针的对象 xff0c 而指针的各种行为中最常见也
  • C++基础——STL常见问题总结

    1 STL由哪些组件组成 容器 xff08 Containers xff09 xff1a 各种数据结构 xff0c 如 xff1a vector list deque set map 用来存放数据 从实现的角度来看 xff0c STL容器是
  • private static final long serialVersionUID = 1L 干什么的?

    private static final long serialVersionUID 61 1L xff1b 是定义以一个序列号 java源码里有大量的类都有这么一个序列号 目的就是把java对象序列化而后进行保存 java的序列化机制式通
  • 协议:PELCO-D

    PELCO D的功能是用于矩阵和其它设备之间的通信协议 基本信息 数据格式 xff1a 1位起始位 8位数据 1位停止位 xff0c 无校验位 波特率 xff1a 2400B S 命令格式 字节1 字节2 字节3 字节4 字节5 字节6 字
  • 9年FPGA工作经验,转行了,苦海无涯……

    整理 xff1a 付斌 xff0c 内容来自网络 01 9年峥嵘岁月 我很少说话 xff0c 因为怕被人鄙视 工作了9年的fpga xff0c 总要总结 其实说我的fpga经验 xff0c 也是一坨屎 三年的 xff0c 用altera的c
  • GPS-RTK

    一点一点的补充吧 背景 1 xff0e 各种控制测量传统的大地测量 工程控制测量采用三角网 导线网方法来施测 xff0c 不仅费工费时 xff0c 要求点间RTK 在工程测量的应用通视 xff0c 而且精度分布不均匀 xff0c 且在外业不
  • 浅谈栈帧

    一 什么是栈帧 xff1f 什么是栈帧 xff0c 首先引用百度百科的经典解释 xff1a 栈帧也叫过程活动记录 xff0c 是编译器用来实现过程 函数调用的一种数据结构 实际上 xff0c 可以简单理解为 xff1a 栈帧就是存储在用户栈
  • madVR+potplay 基本设置

    ctrl 43 j 调出 madvr 的OSD菜单 如下图 xff1a 如何设置 madVR 10bit 输出 xff1a 1 确保视频源是10bit 源 2 显示器设置 如下 xff1a 3 渲染设置如下 xff1a 设置完成 xff0c
  • 4.jetson更换python版本

    问题与背景 jetson自带的python版本是3 6 9 xff0c 太老旧了 xff0c 希望更换python版本 尝试替换成python3 7的版本 但是在未替换之前 xff0c 已经装了pip3了 xff0c 是否pip3会与pyt
  • char数组和指针的区别

    一个简单的字符分割函数引发的思考 char SegStr1 const char pSrc int n int nLen 61 strlen pSrc char ptrSrc 256 61 0 char pSeg 61 ptrSrc for
  • 舒尔补理论Schur Compliment

    在做slam的时候经常遇到的一个概念就是schur complement xff0c 了解这个概念 xff0c 对于理解slam的优化过程也会有很大的帮助 xff1b 首先给出的是舒尔补的定义 xff1a 舒尔补的由来其实就是将一个矩阵变成
  • 用CubeSLAM跑自己的数据集

    针对CubeSLAM本博客内容如下 xff0c 主要是阅读论文和代码的一些结果总结 xff0c 还有一部分总结未完成 xff0c 同样使用或者对语义slam感兴趣有经验的欢迎交流 xff0c 该博客后面也会不段更新cubeslam在自己的数
  • mipi接口的摄像头驱动并发布话题

    情况 需要跑ORBSLAM 之前一直使用USB接口的相机 打开摄像头一般使用的是ROS下的usb cam node进行驱动 采集图像并发布成topic的形式 或者使用opencv的videoCapture进行图像的捕捉 因为某些原因需要将u
  • 正确使用StereoRectify

    双目矫正的使用 cv fisheye StereoRectify 函数 主要用于对双目图像做出矫正 计算出用于立体矫正的参数 具体的使用方法如下 void cv fisheye stereoRectify InputArray K1 Inp