OpenCV双目相机的标定C++

代码来和数据集来自于“小白公众号”
链接:https://pan.baidu.com/s/1bYrj57MEdhwWp45XXVbdpA 提取码:b3m6

双目相机标定的过程:
1.,调节两个相机的角度,给标定板拍10组左右的照片。
2,通过张正友的思想得到两个相机的内外参矩阵和畸变矩阵,为两个相机的畸变矫正做准备。
3,现实情况中,我们无法完全控制两个相机是完全平行的拍一个物体,所以只能通过矫正,来构造平行这一条件,然后通过两个相机的一些参数计算出深度z。
4,通过计算图片中物体的每一个点距离相机镜头的深度,从而构建出该物体的三维立体图。

总而言之,双目相机可以照到一个物体的更多细节,然后根据该细节在不同角度的照片中的位置,得到该细节的空间坐标信息,最终还原照片中的物体在三维空间中的图像。

缺点:双目相机只能对两个镜头都拍摄到的物体细节提取空间信息,也就是说对两个相机拍摄的物体细节无交集的那部分,会产生3D空间还原误差。

思考:如果是更加多维的相机,是不是还原的效果更好呢?
目前只知道,多目相机可以使还原的速度更快

双目相机的应用:
1,根据视差测距离
2,3d构建

代码:
以下是双目相机的标定代码,以及将两个相机的畸变矫正代码。
下一步计划:利用双目相机拍一个实际物体,利用双目参数进行三维立体的投影。

#include <opencv2\opencv.hpp>
#include <fstream> 
#include <iostream>
#include <vector>

using namespace std;
using namespace cv;

void getImgsPoints(vector<Mat> imgs, vector<vector<Point2f>>& imgsPoints, Size board_size)
{
   
	for (int i = 0; i < imgs.size(); i++)
	{
   
		Mat img1 = imgs[i];
		Mat gray1;
		cvtColor(img1, gray1, COLOR_BGR2GRAY);
		vector<Point2f> img1_points;
		findChessboardCorners(gray1, board_size, img1_points);  //计算方格标定板角点
		find4QuadCornerSubpix(gray1, img1_points, Size(5, 5));  //细化方格标定板角点坐标
		imgsPoints.push_back(img1_points);
	}
}

int 
  • 8
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
标定步骤实现方法 1 计算标靶平面与图像平面之间的映射矩阵 计算标靶平面与图像平面之间的映射矩阵,计算映射矩阵时不考虑摄像机的成像模型,只是根据平面标靶坐标点和对应的图像坐标点的数据,利用最小二乘方法计算得到[ [ix] ] .2 求解摄像机参数矩阵 由计算得到的标靶平面和图像平面的映射矩阵得到与摄像机内部参数相关的基本方程关系,求解方程得到摄像机内部参数,考虑镜头的畸变模型,将上述解方程获 得的内部参数作为初值,进行非线性优化搜索,从而计算出所有参数的准确值 [[x] ] .3 求解左右两摄像机之间的相对位置关系 设双目视觉系统左右摄像机的外部参数分别为Rl, Tl,与Rr, Tr,,即Rl, Tl表示左摄像机与世界坐标系的相对位置,Rr, Tr表示右摄像机与世界坐标系的相对位置 [[xi] ]。因此,对于空间任意一点,如果在世界坐标系、左摄像机坐标系和右摄像机坐标系中的坐标分别为Xw,, Xl , Xr,则有:Xl=RlXw+Tl ;Xr=RrXw+Tr .因此,两台摄像机之间的相对几何关系可以由下式表示R=RrRl-1 ;T=Tr- RrRl-1Tl 在实际标定过程中,由标定靶对两台摄像机同时进行摄像标定,以分别获得两台摄像机的内、外参数,从而不仅可以标定出摄像机的内部参数,还可以同时标定双目视觉系统的结构参数 [xii] 。由单摄像机标定过程可以知道,标定靶每变换一个位置就可以得到一组摄像机外参数:Rr,Tr,与Rl, Tl,因此,由公式R=RrRl-1 ;T=Tr- RrRl-1Tl,可以得到一组结构参数R和T
以下是基于OpenCV库实现的双目相机标定C++程序: ```c++ #include <iostream> #include <string> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { // 读取左右相机的图像 Mat img_left = imread("left.png", IMREAD_GRAYSCALE); Mat img_right = imread("right.png", IMREAD_GRAYSCALE); // 定义棋盘格的行列数以及每个方格的宽度 int board_width = 9; int board_height = 6; float square_size = 25.0; // 定义棋盘格的三维坐标 vector<Point3f> object_points; for (int i = 0; i < board_height; i++) { for (int j = 0; j < board_width; j++) { object_points.push_back(Point3f(j * square_size, i * square_size, 0)); } } // 检测每个图像中的角点 vector<Point2f> corners_left, corners_right; bool found_left = findChessboardCorners(img_left, Size(board_width, board_height), corners_left); bool found_right = findChessboardCorners(img_right, Size(board_width, board_height), corners_right); // 如果左右图像中都检测到了角点,则进行标定 if (found_left && found_right) { // 亚像素级别的精确角点检测 cornerSubPix(img_left, corners_left, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1)); cornerSubPix(img_right, corners_right, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1)); // 绘制角点 drawChessboardCorners(img_left, Size(board_width, board_height), corners_left, found_left); drawChessboardCorners(img_right, Size(board_width, board_height), corners_right, found_right); imshow("Left Image", img_left); imshow("Right Image", img_right); // 进行双目相机标定 Mat camera_matrix_left, camera_matrix_right, dist_coeffs_left, dist_coeffs_right; Mat R, T, E, F; stereoCalibrate({ object_points }, { corners_left }, { corners_right }, camera_matrix_left, dist_coeffs_left, camera_matrix_right, dist_coeffs_right, img_left.size(), R, T, E, F, CALIB_FIX_INTRINSIC); cout << "Camera Matrix Left: " << endl << camera_matrix_left << endl; cout << "Distortion Coefficients Left: " << endl << dist_coeffs_left << endl; cout << "Camera Matrix Right: " << endl << camera_matrix_right << endl; cout << "Distortion Coefficients Right: " << endl << dist_coeffs_right << endl; cout << "Rotation Matrix: " << endl << R << endl; cout << "Translation Vector: " << endl << T << endl; cout << "Essential Matrix: " << endl << E << endl; cout << "Fundamental Matrix: " << endl << F << endl; } else { cout << "Error: Cannot find chessboard corners in both images." << endl; } waitKey(0); return 0; } ``` 需要注意的是,该程序假设左右图像中的棋盘格都是完整的,并且每个棋盘格的角点可以被检测到。如果棋盘格不完整或者角点检测失败,需要进行额外的处理。另外,该程序只考虑了相机内参的标定,如果需要进行立体匹配,还需要进行外参的标定

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值