双目匹配过程记录

此文章参考如下博客:
http://blog.csdn.net/wangchao7281/article/details/52506691
感谢子非鱼大大提供的宝贵的理论知识和代码。

双目匹配的过程无非是包括双目相机的标定、矫正以及最后得出视差图这么几个步骤。具体的理论知识可以参考上文的博客地址中的讲述或者自行搜索。

1. 双目相机的标定

双目相机的标定我使用的是Matlab的APP,Matlab自带Stereo Camera Calibration工具,位置如下截图

Matlab工具箱截图

点击下拉按钮,在图像处理和计算机视觉中找到Stereo Camera Calibration模块并打开它,点击Add images按钮,分别把左右相机拍摄的图片传入Matlab中,其中的Size of checkerboard square的大小是标定板的方格的长度,单位是mm。

标定截图

之后Matlab就会自动识别角点,点击上方菜单栏的Calibrate就会自动计算相关的参数,点击Export Camera Parameters之后就会把相关的参数Matlab的工作区,在这里就可以查看相关的参数了。

参数截图(1)

红色方框圈起来的是左右相机的各种参数,点进去之后可以看到相机的内参数以及畸变参数等等,红色箭头指向的是旋转矩阵,蓝色箭头指向的是平移矩阵。
至此标定部分全部完成,具体的参数可以直接在Matlab的工作区中查看即可。

2. 双目相机的矫正

在步骤1中,我们通过标定得到了相机的各种参数,现在把它传入OpenCV。代码如下

Mat cameraMatrixL = (Mat_<double>(3, 3) << 1.289608025726931e+03, 0, 6.437248258682027e+02,
    0, 1.290358173802592e+03, 5.321046969048958e+02,
    0, 0, 1);
Mat distCoeffL = (Mat_<double>(5, 1) << -0.447270756264546, 0.248847254828889, 0, 0, 0.00000);

Mat cameraMatrixR = (Mat_<double>(3, 3) << 1.289350232644886e+03, 0, 6.443163387389753e+02,
    0, 1.289962540201652e+03, 5.284409180695891e+02,
    0, 0, 1);
Mat distCoeffR = (Mat_<double>(5, 1) << -0.444499341518694, 0.234760627512454, 0, 0, 0.00000);

Mat T = (Mat_<double>(3, 1) << -2.383757790772444e+02, 2.938085768248284, -1.249386542211461);//T平移向量
                                                            
Mat R = (Mat_<double>(3, 3) << 0.999188845533377, 0.013112400390036, -0.038075135163100,
    -0.012563847364096, 0.999814319377252, 0.014610835281208,
    0.038259648470532, -0.014120613450352, 0.999168057723373);//R 旋转矩阵

这样,左右两个相机的内参数以及畸变参数已经传入到OpenCV,下面就可以进行矫正了。

//校正
    stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize, R, T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY,
        0, imageSize, &validROIL, &validROIR);
    initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pr, imageSize, CV_32FC1, mapLx, mapLy);
    initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);
        
//读取需要矫正的图片,矫正的图片只能是灰色图
    rgbImageL = imread("left24.png", CV_LOAD_IMAGE_COLOR);
    cvtColor(rgbImageL, grayImageL, CV_BGR2GRAY);
    rgbImageR = imread("right24.png", CV_LOAD_IMAGE_COLOR);
    cvtColor(rgbImageR, grayImageR, CV_BGR2GRAY);

    namedWindow("ImageL Before Rectify", 0);
    namedWindow("ImageR Before Rectify", 0);
    imshow("ImageL Before Rectify", grayImageL);
    imshow("ImageR Before Rectify", grayImageR);
//矫正
    remap(grayImageL, rectifyImageL, mapLx, mapLy, INTER_LINEAR);
    remap(grayImageR, rectifyImageR, mapRx, mapRy, INTER_LINEAR);

    Mat rgbRectifyImageL, rgbRectifyImageR;
    cvtColor(rectifyImageL, rgbRectifyImageL, CV_GRAY2BGR);  //伪彩色图
    cvtColor(rectifyImageR, rgbRectifyImageR, CV_GRAY2BGR);

    namedWindow("ImageL After Rectify", 0);
    namedWindow("ImageR After Rectify", 0);
    imshow("ImageL After Rectify", rgbRectifyImageL);
    imshow("ImageR After Rectify", rgbRectifyImageR);

3. 双目的匹配

经过步骤1和步骤2之后,双目匹配的实验也已经完成了大部分的工作,最后一步的匹配则就简单得多了,可以选择适合自己的匹配算法来完成立体匹配的结果,这里我选用的是OpenCV自带的SGBM算法。

int blockSize = 0, uniquenessRatio = 0, numDisparities = 0;
Ptr<StereoSGBM> sgbm = StereoSGBM::create(0, 16, 3);
void stereo_match(int, void*)
{
        int SADWindowSize = 5;
        sgbm->setPreFilterCap(63);
        int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
        sgbm->setBlockSize(sgbmWinSize);
    
        int cn = rgbImageL.channels();
        
        sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
        sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
        sgbm->setMinDisparity(0);
    
    
        numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : ((imageSize.width / 8) + 15) & -16;
    
        sgbm->setNumDisparities(numberOfDisparities);
        sgbm->setUniquenessRatio(10);
        sgbm->setSpeckleWindowSize(100);
        sgbm->setSpeckleRange(32);
        sgbm->setDisp12MaxDiff(1);
        sgbm->setMode(StereoSGBM::MODE_SGBM_3WAY);
        Mat disp, disp8;
        sgbm->compute(rectifyImageL, rectifyImageR, disp);
        disp.convertTo(disp8, CV_8U, 255 / (numberOfDisparities *16.));
        imwrite("disp.png", disp8);
        imshow("disp8", disp8);
}

匹配的算法有很多种,OpenCV自带的有BM,SGBM,GC,HH等等。

4. 结束语

对于双目匹配的相关的东西,我也是刚刚接触不到半个月,深感这个东西网上的资料很繁杂,且大多数资料不给出具体的步骤,理论的东西过多,亦或是版本过于陈旧。本篇文章如有问题,可以留言或者私信我,我很乐意探讨相关的问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容