20

双目立体视觉 II:块匹配视差图计算

 4 years ago
source link: https://mp.weixin.qq.com/s/ENXTkwKVz3x2ulqJoY6DqQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

双目立体视觉 II:块匹配视差图计算

ronghuaiyang 3D视觉工坊 2/25

点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达

640?wx_fmt=jpeg

作者:Ali Yasin Eser

编译:ronghuaiyang(AI 公园)

导读

双目立体视觉的第二部分,视差图计算算法。

大家好!欢迎来到立体视觉深度第二部分。我将简要解释块匹配算法。我假设您已经阅读了前一篇文章,如果你还没有读过,去读一下。我们将使用来自https://github.com/aliyasineser/stereoDepth的代码。在第一篇文章中,我们分别拍摄了左右两幅图像,并对相机进行了校准。校准过程之后,我们有了立体图像,两张图像中相同的点在同一条线上,这意味着如果这一对图片种有一支笔,笔上的对应的点应该分别是(X1, Y)和(X2, Y),Y是行号,X1和X2的图像的列号。
640?wx_fmt=jpeg
校正过的图像显示相同的P点。
在本例中,X1和x2之间的差异为我们提供了视差值。我们已经提到过,如果我们用左眼闭着看一个近距离的物体,反之亦然,位置根据睁眼的角度而变化。当物体距离越远,这种差别就越明显。这意味着如果视差值越小,物体越近。每个点都可以做这个操作,但是效率不高,因为:
  • 这是一个很慢的过程。时间是宝贵的。
  • 如果校正的不够好,每个点都不理想。
  • 我们需要减少误差,在这种情况下,逐点处理不会有帮助。
这就是我们使用块匹配的原因。其中一些是使用光流(图像流),或减少图像大小,以使用更少的处理能力。第二点我简单提一下,如果你想了解更详细的信息,请查阅相关论文。我们从左边的图像开始。使用左图不是强制的,我就是这么用的。太大的块会产生平滑的图像,太小的块会产生噪声。你都应该尝试一下,找到最佳值。在选择最左边的块之后,我们从左到右搜索,并尝试尽可能多地与右边的图像匹配。由于图像被校正过了,在一个轴上搜索就足够了。
640?wx_fmt=png
黑块是我们的待搜索块
640?wx_fmt=png
在一个轴上搜索,从左到右搜索
如何进行块匹配?有很多公式。大多数人用的是绝对差的和以及差的平方和。你可以研究一下相关的论文以及人们是如何使用它的。在这些方法中,较小的结果意味着非常相似。这将是我们选择的块的差异值。
640?wx_fmt=png
绝对差和的例子
640?wx_fmt=png
左校正后的图像,右校正后图像,块匹配后的视差图。
既然我们已经介绍了基础知识,让我们查看一下代码。在块匹配之后,我使用了WLS(加权最小二乘)滤波器来获得更平滑和更接近的视差值,可以更好地代表图像。函数为:
def depth_map(imgL, imgR):
    """ Depth map calculation. Works with SGBM and WLS. Need rectified images, returns depth map ( left to right disparity ) """
    # SGBM Parameters -----------------
    window_size = 3  # wsize default 3; 5; 7 for SGBM reduced size image; 15 for SGBM full size image (1300px and above); 5 Works nicely

left_matcher = cv2.StereoSGBM_create(
        minDisparity=-1,
        numDisparities=5*16,  # max_disp has to be dividable by 16 f. E. HH 192, 256
        blockSize=window_size,
        P1=8 * 3 * window_size,
        # wsize default 3; 5; 7 for SGBM reduced size image; 15 for SGBM full size image (1300px and above); 5 Works nicely
        P2=32 * 3 * window_size,
        disp12MaxDiff=12,
        uniquenessRatio=10,
        speckleWindowSize=50,
        speckleRange=32,
        preFilterCap=63,
        mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY
    )
    right_matcher = cv2.ximgproc.createRightMatcher(left_matcher)
    # FILTER Parameters
    lmbda = 80000
    sigma = 1.3
    visual_multiplier = 6

wls_filter = cv2.ximgproc.createDisparityWLSFilter(matcher_left=left_matcher)
    wls_filter.setLambda(lmbda)

wls_filter.setSigmaColor(sigma)
    displ = left_matcher.compute(imgL, imgR)  # .astype(np.float32)/16
    dispr = right_matcher.compute(imgR, imgL)  # .astype(np.float32)/16
    displ = np.int16(displ)
    dispr = np.int16(dispr)
    filteredImg = wls_filter.filter(displ, imgL, None, dispr)  # important to put "imgL" here!!!

filteredImg = cv2.normalize(src=filteredImg, dst=filteredImg, beta=0, alpha=255, norm_type=cv2.NORM_MINMAX);
    filteredImg = np.uint8(filteredImg)

return filteredImg
你可以再这里:https://github.com/aliyasineser/stereoDepth检查项目。代码基本上就是在创建匹配器。OpenCV的文档很差(我添加了一些,但这只是冰山一角),但编码方面真的很容易。让我们来看看参数:
  • minDisparity: 最小视差值。通常我们期望这里是0,但当校正算法移动图像时,有时需要设置。
  • numDisparities: 最大视差值,必须大于0,定义视差边界。
  • blockSize: 匹配块的块大小。推荐使用[3-11],推荐使用奇数,因为奇数大小的块有一个中心。
  • P1 和 P2: 负责平滑图像,规则是P2>P1。
  • disp12MaxDiff: 视差计算的最大像素差。
  • preFilterCap:过滤前使用的值。在块匹配之前,计算图像x轴的一个导数,并用于检查边界[-prefiltercap, prefiltercap]。其余的值用Birchfield-Tomasi代价函数处理。
  • uniquenessRatio: 经过成本函数计算,此值用于比较。建议取值范围[5-15]。
  • speckleWindowSize: 过滤删除大的值,得到一个更平滑的图像。建议取值范围[50-200]。
  • speckleRange: 使用领域检查视差得到一个平滑的图像。如果你决定尝试,我建议1或2。小心,这个值会乘以16!OpenCV会这样做,所以你不需要自己去乘。
在代码中我们使用了SGBM。创建左右视差图,使用WLS滤波平滑优化图像。我还没有掌握这个,我用数值做了实验,所以我就不详细讲了。代码:https://github.com/aliyasineser/stereoDepth可用于单目和立体摄像机标定,以及视差图计算。之后,你可以对结果做任何你想做的事。在我的项目中,我用它来检测前方是否有物体或距离太近,都是关于无人机的。你可以用你的想象力创造很多东西。参考文献:
  • https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Lecture_1027_stereo_01.jpg/440px-Lecture_1027_stereo_01.jpg
  • http://mccormickml.com/2014/01/10/stereo-vision-tutorial-part-i/
  • http://www.diegm.uniud.it/fusiello/teaching/mvg/stereo.pdf
  • Learning OpenCV 3: Computer Vision with Python, page 79
英文原文:https://aliyasineser.medium.com/the-depth-ii-block-matching-d599e9372712本文仅做学术分享,如有侵权,请联系删文。下载1在「3D视觉工坊」公众号后台回复:3D视觉即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。下载2在「3D视觉工坊」公众号后台回复:3D视觉github资源汇总即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计源码汇总等。下载3在「3D视觉工坊」公众号后台回复:相机标定即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配即可下载独家立体匹配学习课件与视频网址。

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。

一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

640?wx_fmt=png▲长按加微信群或投稿

640?wx_fmt=jpeg

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近3000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款640?wx_fmt=jpeg 圈里有高质量教程资料、可答疑解惑、助你高效解决问题觉得有用,麻烦给个赞和在看~640?wx_fmt=gif


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK