基于opencv(c++)和matlab的usb双目相机标定

本人由于实际需要入手了一款双目免驱usb摄像头,因为需要做深度估计,故需要标定内参,双目相机标定主要是为了获得摄像头的内参(f,1/dx,1/dy,cx,cy)、畸变参数(k1,k2,k3,p1,p1)和外参(R,t),用于接下来的双目校正和深度图生成。

具体标定步骤如下:

一、获得棋盘格图像

大多数双目标定都是用棋盘格进行标定,如下所示:

这里有一段c++代码,用于生成棋盘格图像:

//双目采集图像程序
#include<opencv2/opencv.hpp>
#include<stdlib.h>

using namespace cv;
using namespace std;

#define WIDTH 1280  //双目分辨率,根据自己摄像头型号选择数值
#define HEIGHT 480  //双目分辨率,根据自己摄像头型号选择数值
 
int main(int argc, char  *argv[])
{
    VideoCapture capture(0);
    if (!capture.isOpened())
    {
        cout<<"can not open the camera"<<endl; cin.get(); exit(1);
    }
    capture.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
    capture.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
    string left_road;
    string right_road;
    int num = 0;
    int count = 0;

    Rect leftRect(0, 0, WIDTH/2, HEIGHT);   //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
    Rect rightRect(WIDTH/2, 0, WIDTH/2, HEIGHT);
    while (1) {
        Mat frame; capture>>frame; //载入图像
        if (frame.empty())
        {
            //判断图像是否载入 cout<<"can not load the frame"<<endl;
        } else {
            count++;
            if (count == 1) {
                cout<<frame.cols<<" "<<frame.rows<<endl;
            }
            Mat leftImg,rightImg;
            frame(leftRect).copyTo(leftImg);     //将一幅图分割成单独的左目图像
            frame(rightRect).copyTo(rightImg);   //将一幅图分割成单独的右目图像
            imshow("left",leftImg);
            imshow("right",rightImg);
            char q=waitKey(30);
            if (q == 27) {    //按esc退出
                break;
            }
            if (q == 32)     //按空格保存,保存到项目的build文件夹下
            {
                num++;
                cout << num;
                left_road = "F:\\graph\\left\\" + to_string(num) + ".png";
                right_road = "F:\\graph\\right\\"+to_string(num) + ".png";
                imwrite(left_road, leftImg);
                imwrite(right_road, rightImg);
            }


        }
    }

}

dd对应的CMakeLists.txx文件为

cmake_minimum_required( VERSION 2.8)
project(biaoding)

# set( CMAKE_CXX_FLAGS "-std=c++11 -03")
find_package(OpenCV)
include_directories(${OpenCV})

add_executable(main src/main.cpp)
target_link_libraries(main ${OpenCV_LIBS})

代码执行后,点击空格即可保存图像,大概采集50张左右。

生成棋盘格后,拿双目相机对棋盘格进行不同位姿的多次拍照采样,一般在60张左右即可(因为后期标定时需要舍弃掉不合格的图像,因此越多素材越好)。分别将左目和右目的图像存在两个文件夹中。图像如下:

左目图:

右目图:

二、matlab标定工具箱

1、打开标定工具箱

在命令行输入stereoCameraCalibrator,出现如下界面:

将上面的“Skew”、“Tangential Distortion”以及“3 Coefficients”等选项选上,将“2 Coefficients”选项去掉,如下:

2、载入图像

点击添加图像

出现如下界面:

Camera1代表左摄像头,Camera2代表右摄像头,分别选择存放着左右图像的文件夹,需要特别注意的是棋盘格的边长应该根据打印的实际大小填写,单位可以选择,然后点击OK,程序会自动检测采集的图像到底有多少可以使用,可以说MATLAB2015的这个工具十分挑剔,如果角度不好的话,将使用不了,因此在采集图像时,最好多的采集一些。

3.标定

点击

按钮,开始标定:

左下方的直方图为左右图像的标定误差,点击误差较大的直方图,可以直接在左边的图像对中找到对应的图像,右键选择“Remove and Recalibrate”,可以重复上述步骤,直到认为误差满足标定需求为止。一般Overall Mean Error小于0.3就可以了。

4、导出参数

点击

在这里插入图片描述选择Export camera parameters,并点击“OK”。

在这里插入图片描述

三、读取参数

标定结束后,会得到如下标定参数:

TranslationOfCamera2:相机2相对于相机1的偏移矩阵,可以直接使用。

RotationOfCamera2:相机2相对于相机1的旋转矩阵,需要转置之后才能使用。

CameraParameters1与CameraParameters2为左右摄像头的单独标定参数。CameraParameters1与CameraParameters2中包含如下文件:

IntrinsicMatrix存放的是摄像头的内参,只与摄像机的内部结构有关,需要先转置再使用。

RadialDistortion:径向畸变,摄像头由于光学透镜的特性使得成像存在着径向畸变,可由K1,K2,K3确定。

TangentialDistortion:切向畸变,由于装配方面的误差,传感器与光学镜头之间并非完全平行,因此成像存在切向畸变,可由两个参数P1,P2确定。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值