精华内容
下载资源
问答
  • 最近搞摄像头项目,顺便扩展...该代码实现了双目摄像头的调用,代码运行稳定没有错误。 最近搞摄像头项目,顺便扩展学习python+opencv的图片处理和视频处理。该代码实现了双目摄像头的调用,代码运行稳定没有错误。
  • 双目摄像头测距算法

    千次阅读 2020-03-11 17:43:49
    双目摄像头测距算法 输入输出接口 Input: (1)左右两个摄像头采集的实时图像视频分辨率(整型int) (2)左右两个摄像头采集的实时图像视频格式 (RGB,YUV,MP4等) (3)摄像头标定参数(中心位置(x,y)和5个...

    双目摄像头测距算法

    输入输出接口

    Input:

    (1)左右两个摄像头采集的实时图像视频分辨率(整型int)

    (2)左右两个摄像头采集的实时图像视频格式 (RGB,YUV,MP4等)

    (3)摄像头标定参数(中心位置(x,y)和5个畸变

    系数(2径向,2切向,1棱向),浮点型float)

    (4)摄像头初始化参数(摄像头初始位置和三个坐标方向

    的旋转角度,车辆宽度高度车速等等,浮点型float)

    Output:

    (1)左右两帧图像匹配的图像视频分辨率(整型int)

    (2)左右两帧图像匹配的图像视频格式(RGB,YUV,MP4等)

    (3)左右两帧图像image/video
    匹配后的深度信息(浮点型float)

    (4)目标物与摄像头的距离 (浮点型float)

    1. 功能定义

    双目测距实际操作分4个步骤:相机标定——双目校正——双目匹配——计算深度信息。

    相机标定:摄像头由于光学透镜的特性使得成像存在着径向畸变,可由三个参数k1,k2,k3确定;由于装配方面的误差,传感器与光学镜头之间并非完全平行,因此成像存在切向畸变,可由两个参数p1,p2确定。单个摄像头的定标主要是计算出摄像头的内参(焦距f和成像原点cx,cy、五个畸变参数(一般只需要计算出k1,k2,p1,p2,对于鱼眼镜头等径向畸变特别大的才需要计算k3))以及外参(标定物的世界坐标)。而双目摄像头定标不仅要得出每个摄像头的内部参数,还需要通过标定来测量两个摄像头之间的相对位置(即右摄像头相对于左摄像头的旋转矩阵R、平移向量t)。

    双目校正:双目校正是根据摄像头定标后获得的单目内参数据(焦距、成像原点、畸变系数)和双目相对位置关系(旋转矩阵和平移向量),分别对左右视图进行消除畸变和行对准,使得左右视图的成像原点坐标一致(CV_CALIB_ZERO_DISPARITY标志位设置时发生作用)、两摄像头光轴平行、左右成像平面共面、对极线行对齐。这样一幅图像上任意一点与其在另一幅图像上的对应点就必然具有相同的行号,只需在该行进行一维搜索即可匹配到对应点。

    双目匹配:双目匹配的作用是把同一场景在左右视图上对应的像点匹配起来,这样做的目的是为了得到视差图。双目匹配被普遍认为是立体视觉中最困难也是最关键的问题。得到视差数据,通过上述原理中的公式就可以很容易的计算出深度信息。
    

    技术路线方案

    双目视觉广泛应用在机器人导航,精密工业测量、物体识别、虚拟现实、场景重建,勘测领域。

    双目视觉是模拟人类视觉原理,使用计算机被动感知距离的方法。从两个或者多个点观察一个物体,获取在不同视角下的图像,根据图像之间像素的匹配关系,通过三角测量原理计算出像素之间的偏移来获取物体的三维信息。

    它的物理原理是这样的,首先请看下图:

    在这里插入图片描述

    图1. 双目测距

    如图1,P是待测物体上的某一点,OR与OT分别是两个相机的光心,点P在两个相机感光器上的成像点分别为P和P’(相机的成像平面经过旋转后放在了镜头前方),f为相机焦距,B为两相机中心距,Z为我们想求得的深度信息,设点P到点P’的距离为dis,则:
    在这里插入图片描述
    根据相似三角形原理:
    在这里插入图片描述
    可得:
    在这里插入图片描述
    公式中,焦距f和摄像头中心距B可通过标定得到,因此,只要获得了在这里插入图片描述(即视差d)的值即可求得深度信息,即:
    在这里插入图片描述
    假设目标点在左视图中的坐标为(x,y),在左右视图上形成的视差为d,目标点在以左摄像头光心为原点的世界坐标系中的坐标为(X,Y,Z),则存在所示的变换矩阵Q,使得在这里插入图片描述
    在这里插入图片描述

    为了精确地求得某个点在三维空间里的距离Z,我们需要获得的参数有焦距f、视差d、摄像头中心距B。如果还需要获得X坐标和Y坐标的话,那么还需要额外知道左右像平面的坐标系与立体坐标系中原点的偏移cx和cy。其中f,d,cx和cy可以通过立体标定获得初始值,并通过立体校准优化,使得两个摄像头在数学上完全平行放置,并且左右摄像头的cx,cy和f相同。而立体匹配所做的工作,就是在之前的基础上,求取最后一个变量:视差d。从而最终完成求一个点三维坐标所需要的准备工作。在清楚了上述原理之后,我们也就知道了,所有的这几步:标定、校准和匹配,都是围绕着如何更精确地获得 f,d,B,cx 和cy 而设计的。

    标定:摄像头标定一般都需要一个放在摄像头前的特制的标定参照物(棋盘纸),摄像头获取该物体的图像,并由此计算摄像头的内外参数。标定参照物上的每一个特征点相对于世界坐标系的位置在制作时应精确测定,世界坐标系可选为参照物的物体坐标系。在得到这些已知点在图像上的投影位置后,可计算出摄像头的内外参数。

    校准与匹配:双目摄像头标定不仅要得出每个摄像头的内部参数,还需要通过标定来测量两个摄像头之间的相对位置。要计算目标点在左右两个视图上形成的视差,首先要把该点在左右视图上两个对应的像点匹配起来。然而,在二维空间上匹配对应点是非常耗时的,为了减少匹配搜索范围,我们可以利用极线约束使得对应点的匹配由二维搜索降为一维搜索。而双目校正的作用就是要把消除畸变后的两幅图像严格地行对应,使得两幅图像的对极线恰好在同一水平线上,这样一幅图像上任意一点与其在另一幅图像上的对应点就必然具有相同的行号,只需在该行进行一维搜索即可匹配到对应点。

    在这里插入图片描述

    图2. 双目校正与匹配

    1. 关键技术参数和性能指标

    利用双目摄像头的数据估计车辆和车辆距离。假设摄像头分辨率1280´720像素,焦距1458像素,角度误差小于0.5度。下表描述精度指标:

    在这里插入图片描述

    表1. 指标

    展开全文
  • 33、双目摄像头测距

    2021-06-12 12:12:17
    基本思想:因为最近用到了双目摄像头测距的代码逻辑,逐记录和转发一下大佬们的知识点 双目测距的整体原理是根据相似三角形原理进行计算和求距离 首先使用两个相机进行标注数据的采集 使用代码进行数据采集...

    基本思想:因为最近用到了双目摄像头测距的代码逻辑,逐记录和转发一下大佬们的知识点

    双目测距的整体原理是根据相似三角形原理进行计算和求距离

    本人打印出来的是一个表格1厘米=10mm

    首先使用两个相机进行标注数据的采集

    使用代码进行数据采集 https://blog.csdn.net/xiao__run/article/details/79618827

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import cv2
    import time
    
    AUTO = True  # 自动拍照,或手动按s键拍照
    INTERVAL = 2 # 自动拍照间隔
    
    cv2.namedWindow("left")
    cv2.namedWindow("right")
    cv2.moveWindow("left", 0, 0)
    cv2.moveWindow("right", 400, 0)
    left_camera = cv2.VideoCapture(0)
    #cv2.waitKey(50)
    #left_camera.set(cv2.CV_CAP_PROP_FRAME_WIDTH,320)
    #left_camera.set(cv2.CV_CAP_PROP_FRAME_HEIGHT,240)
    right_camera = cv2.VideoCapture(2)
    #right_camera.set(cv2.CV_CAP_PROP_FRAME_WIDTH,320)
    #right_camera.set(cv2.CV_CAP_PROP_FRAME_HEIGHT,240)
    
    counter = 0
    utc = time.time()
    pattern = (12, 8) # 棋盘格尺寸
    leftfolder = "F:\\snapshot\\left\\" # 拍照文件目录
    rightfolder = "F:\\snapshot\\right\\" # 拍照文件目录
    def shot(pos, frame):
        global counter
        if pos=="left":
            path = leftfolder + pos + "_" + str(counter) + ".jpg"
        else:
            path = rightfolder + pos + "_" + str(counter) + ".jpg"
        cv2.imwrite(path, frame)
        print("snapshot saved into: " + path)
    
    while True:
        ret, left_frame = left_camera.read()
        ret, right_frame = right_camera.read()
    
        cv2.imshow("left", left_frame)
        cv2.imshow("right", right_frame)
    
        now = time.time()
        if AUTO and now - utc >= INTERVAL:
            shot("left", left_frame)
            shot("right", right_frame)
            counter += 1
            utc = now
    
        key = cv2.waitKey(1)
        if key == ord("q"):
            break
        elif key == ord("s"):
            shot("left", left_frame)
            shot("right", right_frame)
            counter += 1
    
    left_camera.release()
    right_camera.release()
    cv2.destroyWindow("left")
    cv2.destroyWindow("right")
    

    然后采集的图片为

    然后下载Matlab,进行安装和标注图片

    链接:https://pan.baidu.com/s/1VZvsg4ItAAHt58TNqIHi0Q 
    提取码:3yds 
    复制这段内容后打开百度网盘手机App,操作更方便哦

     

    然后进行标注:https://blog.csdn.net/weixin_43322104/article/details/95968808

    得到内参数

    camera_1                                                                                            camera_2

    畸变参数

    camera_1

    camera_1内参数 (经过转置之后的数据)

    1815.16540425092	234.943222037557	218.483602583734
    0	2573.00608919612	0
    0	0	1
    RadialDistortion :1.28714906681218,110.305699549694  对应 K1,K2  ; K3默认为0
    
    TangentialDistortion :0 ,0   对应  P1,P2

    使用时,K1K2P1P2K3顺序 
     camera_2内参数(经过转置之后的数据)

    2034.30908846847	627.739373073135	252.878869230493
    0	2829.47741087495	0
    0	0	1
    RadialDistortion :-0.0633962707030803,4.69814885381521  对应 K1,K2  ; K3默认为0
    
    TangentialDistortion :0 ,0   对应  P1,P2

    R 矩阵

    0.999854279838965	0.00458676744034414	0.0164432555217484
    -0.00698007377963907	0.988874091283887	0.148591083707932
    -0.0155787566171407	-0.148684206128005	0.988762008367205

    测试代码 https://www.freesion.com/article/2052743865/

    # filename: camera_configs.py
    import cv2
    import numpy as np
    
    left_camera_matrix = np.array([[1815.16540425092,234.943222037557,218.483602583734],[0,2573.00608919612,0],[0,0,1]])
    left_distortion = np.array([[1.28714906681218,110.305699549694, 0.0, 0.0, 0.00000]])
    
    
    
    right_camera_matrix = np.array([[2034.30908846847,627.739373073135,252.878869230493],[0,2829.47741087495,0],[0,0,1]])
    right_distortion = np.array([[-0.0633962707030803,4.6981488538152, 0.0, 0.0, 0.00000]])
    
    R = np.matrix([
        [1.0000, 0.0014, 0.0033],
        [-0.0014, 1.0000, 0.0020],
        [-0.0033, -0.0020, 1.0000],
    ])
    
    # print(R)
    
    T = np.array([-18.1454, -0.3016, 0.4750])  # 平移关系向量
    
    size = (640, 480)  # 图像尺寸
    
    # 进行立体更正
    R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(left_camera_matrix, left_distortion,
                                                                      right_camera_matrix, right_distortion, size, R,
                                                                      T)
    # 计算更正map
    left_map1, left_map2 = cv2.initUndistortRectifyMap(left_camera_matrix, left_distortion, R1, P1, size, cv2.CV_16SC2)
    right_map1, right_map2 = cv2.initUndistortRectifyMap(right_camera_matrix, right_distortion, R2, P2, size, cv2.CV_16SC2)

    测试代码

    # 该脚本实现深度图以及点击深度图测量像素点的真实距离
    # 可以运行看到效果之后最好自己重新标定一次
    
    from cv2 import cv2
    import numpy as np
    import convert as camera_configs  # 摄像头的标定数据
    
    cam1 = cv2.VideoCapture(0)  # 摄像头的ID不同设备上可能不同
    cam2 = cv2.VideoCapture(2)  # 摄像头的ID不同设备上可能不同
    # cam1 = cv2.VideoCapture(1 + cv2.CAP_DSHOW)  # 摄像头的ID不同设备上可能不同
    # cam1.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)  # 设置双目的宽度
    # cam1.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)  # 设置双目的高度
    
    # 创建用于显示深度的窗口和调节参数的bar
    cv2.namedWindow("depth")
    cv2.moveWindow("left", 0, 0)
    cv2.moveWindow("right", 600, 0)
    
    # 创建用于显示深度的窗口和调节参数的bar
    # cv2.namedWindow("depth")
    cv2.namedWindow("config", cv2.WINDOW_NORMAL)
    cv2.moveWindow("left", 0, 0)
    cv2.moveWindow("right", 600, 0)
    
    cv2.createTrackbar("num", "config", 0, 60, lambda x: None)
    cv2.createTrackbar("blockSize", "config", 30, 255, lambda x: None)
    cv2.createTrackbar("SpeckleWindowSize", "config", 1, 10, lambda x: None)
    cv2.createTrackbar("SpeckleRange", "config", 1, 255, lambda x: None)
    cv2.createTrackbar("UniquenessRatio", "config", 1, 255, lambda x: None)
    cv2.createTrackbar("TextureThreshold", "config", 1, 255, lambda x: None)
    cv2.createTrackbar("UniquenessRatio", "config", 1, 255, lambda x: None)
    cv2.createTrackbar("MinDisparity", "config", 0, 255, lambda x: None)
    cv2.createTrackbar("PreFilterCap", "config", 1, 65, lambda x: None)  # 注意调节的时候这个值必须是奇数
    cv2.createTrackbar("MaxDiff", "config", 1, 400, lambda x: None)
    
    
    # 添加点击事件,打印当前点的距离
    def callbackFunc(e, x, y, f, p):
        if e == cv2.EVENT_LBUTTONDOWN:
            print(threeD[y][x])
            if abs(threeD[y][x][2]) < 3000:
                print("当前距离:" + str(abs(threeD[y][x][2])))
            else:
                print("当前距离过大或请点击色块的位置")
    
    
    cv2.setMouseCallback("depth", callbackFunc, None)
    
    # 初始化计算FPS需要用到参数 注意千万不要用opencv自带fps的函数,那个函数得到的是摄像头最大的FPS
    frame_rate_calc = 1
    freq = cv2.getTickFrequency()
    font = cv2.FONT_HERSHEY_SIMPLEX
    
    imageCount = 1
    
    while True:
        t1 = cv2.getTickCount()
        ret1, frame1 = cam1.read()
        ret1, frame2 = cam2.read()
    
        if not ret1:
            print("camera is not connected!")
            break
    
        # 这里的左右两个摄像头的图像是连在一起的,所以进行一下分割
        # frame1 = frame[0:480, 0:640]
        # frame2 = frame[0:480, 640:1280]
    
        ####### 深度图测量开始 #######
        # 立体匹配这里使用BM算法,
    
        # 根据标定数据对图片进行重构消除图片的畸变
        img1_rectified = cv2.remap(frame1, camera_configs.left_map1, camera_configs.left_map2, cv2.INTER_LINEAR,
                                   cv2.BORDER_CONSTANT)
        img2_rectified = cv2.remap(frame2, camera_configs.right_map1, camera_configs.right_map2, cv2.INTER_LINEAR,
                                   cv2.BORDER_CONSTANT)
    
        # 如有些版本 remap()的图是反的 这里对角翻转一下
        # img1_rectified = cv2.flip(img1_rectified, -1)
        # img2_rectified = cv2.flip(img2_rectified, -1)
    
        # 将图片置为灰度图,为StereoBM作准备,BM算法只能计算单通道的图片,即灰度图
        # 单通道就是黑白的,一个像素只有一个值如[123],opencv默认的是BGR(注意不是RGB), 如[123,4,134]分别代表这个像素点的蓝绿红的值
        imgL = cv2.cvtColor(img1_rectified, cv2.COLOR_BGR2GRAY)
        imgR = cv2.cvtColor(img2_rectified, cv2.COLOR_BGR2GRAY)
    
        out = np.hstack((img1_rectified, img2_rectified))
        for i in range(0, out.shape[0], 30):
            cv2.line(out, (0, i), (out.shape[1], i), (0, 255, 0), 1)
        cv2.imshow("epipolar lines", out)
    
        # 通过bar来获取到当前的参数
        # BM算法对参数非常敏感,一定要耐心调整适合自己摄像头的参数,前两个参数影响大 后面的参数也要调节
        num = cv2.getTrackbarPos("num", "config")
        SpeckleWindowSize = cv2.getTrackbarPos("SpeckleWindowSize", "config")
        SpeckleRange = cv2.getTrackbarPos("SpeckleRange", "config")
        blockSize = cv2.getTrackbarPos("blockSize", "config")
        UniquenessRatio = cv2.getTrackbarPos("UniquenessRatio", "config")
        TextureThreshold = cv2.getTrackbarPos("TextureThreshold", "config")
        MinDisparity = cv2.getTrackbarPos("MinDisparity", "config")
        PreFilterCap = cv2.getTrackbarPos("PreFilterCap", "config")
        MaxDiff = cv2.getTrackbarPos("MaxDiff", "config")
        if blockSize % 2 == 0:
            blockSize += 1
        if blockSize < 5:
            blockSize = 5
    
        # 根据BM算法生成深度图的矩阵,也可以使用SGBM,SGBM算法的速度比BM慢,但是比BM的精度高
        stereo = cv2.StereoBM_create(
            numDisparities=16 * num,
            blockSize=blockSize,
        )
        stereo.setROI1(camera_configs.validPixROI1)
        stereo.setROI2(camera_configs.validPixROI2)
        stereo.setPreFilterCap(PreFilterCap)
        stereo.setMinDisparity(MinDisparity)
        stereo.setTextureThreshold(TextureThreshold)
        stereo.setUniquenessRatio(UniquenessRatio)
        stereo.setSpeckleWindowSize(SpeckleWindowSize)
        stereo.setSpeckleRange(SpeckleRange)
        stereo.setDisp12MaxDiff(MaxDiff)
    
        # 对深度进行计算,获取深度矩阵
        disparity = stereo.compute(imgL, imgR)
        # 按照深度矩阵生产深度图
        disp = cv2.normalize(disparity, disparity, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    
        # 将深度图扩展至三维空间中,其z方向的值则为当前的距离
        threeD = cv2.reprojectImageTo3D(disparity.astype(np.float32) / 16., camera_configs.Q)
        # 将深度图转为伪色图,这一步对深度测量没有关系,只是好看而已
        fakeColorDepth = cv2.applyColorMap(disp, cv2.COLORMAP_JET)
    
        cv2.putText(frame1, "FPS: {0:.2f}".format(frame_rate_calc), (30, 50), font, 1, (255, 255, 0), 2, cv2.LINE_AA)
    
        # 按下S可以保存图片
        interrupt = cv2.waitKey(10)
        if interrupt & 0xFF == 27:  # 按下ESC退出程序
            break
        if interrupt & 0xFF == ord('s'):
            #cv2.imwrite('images/left' + '.jpg', frame1)
            #cv2.imwrite('images/right' + '.jpg', frame2)
            #cv2.imwrite('images/img1_rectified' + '.jpg', img1_rectified)  # 畸变,注意观察正反
            #cv2.imwrite('images/img2_rectified' + '.jpg', img2_rectified)
            cv2.imwrite('images/depth' + '.jpg', disp)
            #cv2.imwrite('images/fakeColor' + '.jpg', fakeColorDepth)
            #cv2.imwrite('mages/epipolar' + '.jpg', out)
    
        ####### 任务1:测距结束 #######
    
        # 显示
        # cv2.imshow("frame", frame) # 原始输出,用于检测左右
        cv2.imshow("frame1", frame1)  # 左边原始输出
        cv2.imshow("frame2", frame2)  # 右边原始输出
        #cv2.imshow("img1_rectified", img1_rectified)  # 左边矫正后输出
        #cv2.imshow("img2_rectified", img2_rectified)  # 右边边矫正后输出
        cv2.imshow("depth", disp)  # 输出深度图及调整的bar
        #cv2.imshow("fakeColor", fakeColorDepth)  # 输出深度图的伪色图,这个图没有用只是好看
    
        # 需要对深度图进行滤波将下面几行开启即可 开启后FPS会降低
        #img_medianBlur = cv2.medianBlur(disp, 25)
        #img_medianBlur_fakeColorDepth = cv2.applyColorMap(img_medianBlur, cv2.COLORMAP_JET)
        #img_GaussianBlur = cv2.GaussianBlur(disp, (7, 7), 0)
        #img_Blur = cv2.blur(disp, (5, 5))
        #cv2.imshow("img_GaussianBlur", img_GaussianBlur)  # 右边原始输出
        #cv2.imshow("img_medianBlur_fakeColorDepth", img_medianBlur_fakeColorDepth)  # 右边原始输出
        #cv2.imshow("img_Blur", img_Blur)  # 右边原始输出
        #cv2.imshow("img_medianBlur", img_medianBlur)  # 右边原始输出
    
        t2 = cv2.getTickCount()
        time1 = (t2 - t1) / freq
        frame_rate_calc = 1 / time1
    
    cam1.release()
    cv2.destroyAllWindows()

    展开全文
  • 双目摄像头测距-理论(转载)

    千次阅读 2018-08-14 15:39:45
    目前视觉方案做ADAS既有双目也有单目,两者在距离检测上用了不同的技术路线,产品...目前感知所采用的传感器包含各种形式的雷达、单目摄像头、双目摄像头等,或是由这些传感器进行不同组合形成的感知系统,而这些传...

    目前视觉方案做ADAS既有双目也有单目,两者在距离检测上用了不同的技术路线,产品化时也存在各自优缺点,对此作者谈了谈自己的看法。本文作者姜安,为中科慧眼CEO。

    ADAS功能的第一步是感知,也就是观察车辆周边负责的路况环境。在这个基础上才能做出相应的路径规划和驾驶行为决策。目前感知所采用的传感器包含各种形式的雷达、单目摄像头、双目摄像头等,或是由这些传感器进行不同组合形成的感知系统,而这些传感器件各有利弊,传感器融合是大势所趋。

    在这其中,摄像头不可或缺,可以通过采集前方道路图像,实现车道线障碍物以及行人检测ADAS功能。关于ADAS摄像头选用有哪些讲究?单双目方案存在哪些差异?在此谈一谈我的看法。

    ADAS摄像头成像哪些要求?

    根据ADAS检测需要,摄像头在选择时需要具备下面2个特点:

    一是要看得足够远。看的越远就能有更加充裕的时间做出判断和反应,从而避免或者降低事故发生造成的损失。这类摄像头关注的参数是焦距,焦距越长看的会越远。但是焦距越长,带来的问题是视角越窄,所以需要折衷考虑。

    二是要求高动态。选用具有高动态范围的黑白相机,可以有效抑制光晕现象,并增强暗处的细节,从而提高成像质量。另外,彩色图像在镜头表面进行了镀膜,虽然提升了人眼的感知体验,但实际上降低了信噪比或者说信息量。这对后续的图像处理不利。

    根据这些要求,很容易发现目前行业里的一种炒作现象。很多车上使用的智能硬件多是行车记录仪、云镜等产品,会在原来成像系统的基础上添加ADAS功能,其实只是厂家赚取噱头的方式。

    因为行车记录仪的目的是记录车辆周边的状况,看的越清晰越好、越全面越好,即“人友好”。这就需要成像系统具有超高的分辨率、超好的色彩还原性、超大的广角镜头,视角增大意味着焦距的缩小。这与ADAS对成像系统的要求截然相反,ADAS要求的图像质量是“机器友好”,因此在行车记录仪的成像系统基础上开发ADAS功能是不切实际的。目前很多号称有ADAS功能的行车记录仪,一般都只有车道线检测这一个功能。有的虽然有别的如碰撞预警的功能,但是用户体验极差。

    单/双目的测距原理区别

    目前摄像头ADAS有单目和双目两种方案,两者的共同特点,就是通过摄像头采集图像数据,然后从图像数据上得到距离信息。ADAS一个很重要的作用是碰撞预警。碰撞预警需要关注距离的变化,需要估计即将碰撞的时间。有了距离测量,才会有距离变化,有距离变化才会有碰撞时间的估计,最后才会有预警。

    单目摄像头的大致测距原理,是先通过图像匹配进行目标识别(各种车型、行人、物体等),再通过目标在图像中的大小去估算目标距离。这就要求在估算距离之前首先对目标进行准确识别,是汽车还是行人,是货车、SUV还是小轿车。准确识别是准确估算距离的第一步。

    要做到这一点,就需要建立并不断维护一个庞大的样本特征数据库,保证这个数据库包含待识别目标的全部特征数据。比如在一些特殊地区,为了专门检测大型动物,必须先行建立大型动物的数据库;而对于另外某些区域存在一些非常规车型,也要先将这些车型的特征数据加入到数据库中。

    如果缺乏待识别目标的特征数据,就会导致系统无法对这些车型、物体、障碍物进行识别,从而也就无法准确估算这些目标的距离。导致ADAS系统的漏报。

    而双目检测的方式就是通过对两幅图像视差的计算,直接对前方景物(图像所拍摄到的范围)进行距离测量,而无需判断前方出现的是什么类型的障碍物。所以对于任何类型的障碍物,都能根据距离信息的变化,进行必要的预警或制动。

    双目摄像头的原理与人眼相似。人眼能够感知物体的远近,是由于两只眼睛对同一个物体呈现的图像存在差异,也称“视差”。物体距离越远,视差越小;反之,视差越大。视差的大小对应着物体与眼睛之间距离的远近,这也是3D电影能够使人有立体层次感知的原因。

    图中的人和椰子树,人在前,椰子树在后,最下方是双目相机中的成像。可以看出右侧相机成像中人在树的左侧,左侧相机成像中人在树的右侧,这是因为双目的角度不一样。再通过对比两幅图像就可以知道人眼观察树的时候视差小。而观察人时视差大,因为树的距离远,人的距离近。这就是双目三角测距的原理。双目系统对目标物体距离感知是一种绝对的测量,而非估算。

    单/双目方案的优势与难点

    单目的优势在于成本较低,对计算资源的要求不高,系统结构相对简单。其缺点在于必须不断更新和维护一个庞大的样本数据库,才能保证系统达到较高的识别率;无法对非标准障碍物进行判断;距离并非真正意义上的测量,准确度较低。

    双目系统成本比单目系统要高,但尚处于可接受范围内,并且与激光雷达等方案相比成本较低;二是没有识别率的限制,因为从原理上无需先进行识别再进行测算,而是对所有障碍物直接进行测量;三是精度比单目高,直接利用视差计算距离;四是无需维护样本数据库,因为对于双目没有样本的概念。

    双目系统的一个难点在于计算量非常大,对计算单元的性能要求非常高,这使得双目系统的产品化、小型化的难度较大。所以在芯片或FPGA上解决双目的计算问题难度比较大。国际上使用双目的研究机构或厂商,绝大多数是使用服务器来进行图像处理与计算的;也有部分将算法进行简化后,使用FPGA进行处理。目前,中科慧眼在芯片上的计算效率已经达到15fps,在FPGA+ARM架构上的计算效率达到了40fps。

    另一个难点在于双目的配准效果。通过双目摄像头的图像配准可以计算生成表示距离的二维图像。下图是中科慧眼双目方案对实际场景信息采集与计算得到的距离的对应关系,不同饱和度颜色代表不同距离,从暖色调至冷色调为距离由近及远。在计算过程中,需要对噪点与空洞做很好的抑制。从右图可以看出,色调(距离)是平滑过渡,没有跳变。


    △中科慧眼距离计算获得的二维图像

    一些FPGA方案中有很多噪点与空洞,对后续计算不利,存在安全风险。对于小障碍物的识别,既要做到没有杂点和空洞,又要表现细节。否则比如一条横着的栏杆无法识别,会增加驾驶的风险。下面的图表现的是小物体和行人的探测上中科慧眼双目方案与国际上其他算法的对比。


    △Our为中科慧眼算法小障碍物的双目配准效果,其它为国际流行传统方法的处理效果

    小结

    因为检测原理上的差异,双目摄像头在距离测算上相比单目有自己的特点,其硬件成本和计算量级的加倍,是难关也是突破口。就像谷歌自动驾驶汽车不断积累大量的经验和使用数据,才可能一步步积累实现自动驾驶。中科慧眼的双目产品目前完成了样机,也正在进行大规模路测。从产品理论技术原型走到真正被用户接受的产品,还有很长的路要走。

    原出处:http://www.cheyun.com/content/10424

    展开全文
  • 1.双目匹配(双RGB摄像头+可选的照明系统) 三角测量原理即目标点在左右两幅视图中成像的横坐标之间存在的差异(视差Disparity),与目标点到成像平面的距离成反比例的关系:Z = ft/d;得到深度信息。 双目匹配采用三角测量...

    深度检测主要技术方法:
    1.双目匹配(双RGB摄像头+可选的照明系统)
    三角测量原理即目标点在左右两幅视图中成像的横坐标之间存在的差异(视差Disparity),与目标点到成像平面的距离成反比例的关系:Z = ft/d;得到深度信息。
    双目匹配采用三角测量原理完全基于图像处理技术,通过寻找两个图像中的相同的特征点得到匹配点,从而得到深度值。
    双目测距中光源是环境光或者白光这种没有经过编码的光源,图像识别完全取决于被拍摄的物体本身的特征点,因此匹配一直是双目的一个难点。
    匹配的精度和正确性很难保证,因此出现了结构光技术来解决匹配问题。
    技术点:立体匹配算法,一般步骤:匹配代价计算,匹配代价叠加,视差获取,视差细化(亚像素级)
    优点:
    给定的工作条件下,较好效果,硬件简单。
    缺点:
    双目使用的是物体本身的特征点,对表面颜色和纹理特征不明显的物体失效。
    因为结构光光源带有很多特征点或者编码,因此提供了很多的匹配角点或者直接的码字,可以很方便的进行特征点的匹配。
    换句话说,不需要使用被摄物体本身的特征点,因此能提供很好的匹配结果。

    2.一般结构光(一个RGB摄像头+结构光投射器(红外)+结构光深度感应器(CMOS))

    结构光测距的不同点在于对投射光源进行了编码或者说特征化。这样拍摄的是被编码的光源投影到物体上被物体表面的深度调制过的图像。
    结构光基本原理:
    通过投影一个预先设计好的图案作为参考图像(编码光源),将结构光投射至物体表面,再使用摄像机接收该物体表面反射的结构光图案,这样,同样获得了两幅图像,
    一幅是预先设计的参考图像,另外一幅是相机获取的物体表面反射的结构光图案,由于接收图案必会因物体的立体型状而发生变形,故可以通过该图案在摄像机上的位置和形变程度来计算物体表面的空间信息。普通的结构光方法仍然是部分采用了三角测距原理的深度计算。
    同样是进行图像匹配,这种方法比双目匹配好的地方在于,参考图像不是获取的,而是经过专门设计的图案,因此特征点是已知的,而且更容易从测试图像中提取。
    结构光采用三角视差测距,基线(光源与镜头光心的距离)越长精度越高。
    技术点:提供什么样的辅助信息来帮助快速而精确的对应点匹配是结构光编码方法的衡量标准。
    优点:
    成熟,经验证,可量产
    缺点:
    有限的供应商,技术和供应链门槛,阳光干扰敏感,多设备之间存在严重干扰

    3.Light coding(激光散斑光源)
    与结构光不同,Light coding的光源为“激光散斑”,是激光照射到粗糙物体或穿透毛玻璃后随机形成的衍射斑点。这些散斑具有高度的随机性,而且会随着距离的不同而变换图案。也就是说空间中任意两处的散斑图案都是不同的。只要在空间中打上这样的光,整个空间都被做了标记,把一个物体放进这个空间,只要看看物体上面的散斑图案,就可以知道这个物体在什么位置了。当然在这之前要把整个空间的散斑图案都记录下来,所以要先做一次光源标定。primesense公司的三维测量使用的就是激光散斑技术。primesense将该技术称为光源标定技术。光源标定技术在整个空间中每隔一段距离选取一个参考平面,把参考平面上的散斑图案保存下来。

    Light coding不是通过空间几何关系求解的,它的测量精度只和标定时取得参考面的密度有关,参考面越密测量越精确。不用为了提高精度而将基线拉宽。
    缺点:
    激光器发出的编码光斑容易被太阳光淹没掉

    转自:http://blog.csdn.net/jaylinzhou/article/details/70810300

    展开全文
  • 最详细的双目摄像头测距离(深度)的原理

    万次阅读 多人点赞 2019-05-23 21:30:31
    关于双目摄像头测距原理,最近在看关于双目摄像机成像的项目,找关于双目摄像头标定的c++代码,但是发现自己对双目摄像机的成像原理不清楚,所以看代码和看天书一样。这篇就写给零基础接触双目摄像机成像原理的小...
  • 双目视觉测距原理,数学推导及三维重建资源

    万次阅读 多人点赞 2018-01-09 21:15:20
    先说一下单/双目测距原理区别:单目测距原理:先通过图像匹配进行目标识别(各种车型、行人、物体等),再通过目标在图像中的大小去估算目标距离。这就要求在估算距离之前首先对目标进行准确识别,是汽车还是行人...
  • 双目测距原理

    万次阅读 多人点赞 2019-05-28 16:16:42
    双目测距基本原理双目测距实际操作分4个步骤:相机标定——双目校正——双目匹配——计算深度信息。 相机标定:摄像头由于光学透镜的特性使得成像存在着径向畸变,可由三个参数k1,k2,k3确定;由于装配方面...
  • 使用双目摄像头测距的方案基于Matlab2018,Python 2.7、Opencv 3.4实现,实现流程如下: 1. 首先,使用Matlab,进行双目摄像头的标定; 2. 其次,识别特定颜色点; 3. 最后,使用双目测距公式得到特征点的距离
  • 一、双目测距原理 通过对两幅图像视差的计算,直接对前方景物(图像所拍摄到的范围)进行距离测量。双目摄像头的原理与人眼相似。人眼能够感知物体的远近,是由于两只眼睛对同一个物体呈现的图像存在差异,也称...
  • 摄像头测距

    2020-04-21 08:19:57
    摄像头测距 深度检测主要技术方法: 1.双目匹配(双RGB摄像头+可选的照明系统) 三角测量原理即目标点在左右两幅视图中成像的横坐标之间存在的差异(视差Disparity),与目标点到成像平面的距离成反比例的关系:Z = ft/d;...
  • 双目相机测距原理图和生成深度图

    千次阅读 2020-05-27 18:01:10
    之前看了很多的示意图,但是感觉讲解和推导都不清楚,所以自己画了一个原理图,看不懂的话可以留言 根据上面的原理图可知,Z(深度)只和三个参数有关,即:B(两个相机中心间距), f(相机的焦距) , d(左右对应点的...
  • 双目视觉-双目测距原理剖析

    千次阅读 2020-04-08 14:45:29
    这是一篇好文章, 深入浅出,帮助我们更好地了解了双目相机的工作原理。 1.从相似三角形原理可知,我们仅仅需要分析出左眼图片和右眼图片中,相同物体的两个不同坐标,就可以算出深度值。 2. 计算 两个图片之间的...
  • 双目摄像头的标定及测距(Ubuntu16.04 + OpenCV)

    千次阅读 热门讨论 2019-08-10 23:02:01
    因为识别物体之后需要测距,然而带深度带RGB图的摄像头都好贵,所以入手了一个双目摄像头,长下面这个样子: 淘宝买的,只要35块钱…壳都没有,我是直接贴在电脑上的(请忽略杂乱的背景) 卖家把我拉进了个群,群里...
  • 谈到双目相机测距,我们首先要先了解测距原理:如下图所示,这是双目摄像头的俯视图。 上图解释了双摄像头测距原理,书中Z的公式如下:b代表基线,根据相似三角形关系, 这里d表示为左右图横坐标之差,称为视差...
  • 双目测距基本原理

    2017-11-02 16:06:13
    双目测距基本原理: 如图,P是待测物体上的某一点,OR与OT分别是两个相机的光心,点P在两个相机感光器上的成像点分别为P和P’(相机的成像平面经过旋转后放在了镜头前方),f为相机焦距,B为两相机中心距,Z为我们...
  • 文章目录ROS 生成深度图简介双目摄像头测距与 OpenCV 简介双目测距原理准备双目测距准备ROS 的摄像头仿真ROS 获取仿真摄像头的固定属性数据生成深度图设置相机属性参数生成深度图使用 python 获取话题的图像数据把...
  • 双目测距的原理个人理解 双目摄像机由两个摄像机组成,利用三角测量原理获得场景的深度信息,...双目测距原理: 其中,depth = (f * baseline)/disparity,disparity为视差即xr-xt,baseline为俩相机中心距,f为...
  • 学习OpenCV(2)双目测距原理

    千次阅读 2016-03-04 10:39:13
    图1解释了双摄像头测距原理,书中Z的公式如下: 在OpenCV中,f的量纲是像素点,T的量纲由定标棋盘格的实际尺寸和用户输入值确定,一般总是设成毫米,当然为了精度提高也可以设置为0.1毫米量级,d=xl-xr的量纲也...
  • 双目测距的基本原理

    万次阅读 2019-08-25 19:29:55
    单目测距原理: 先通过图像匹配进行目标识别(各种车型、行人、物体等),再通过目标在图像中的大小去估算目标距离。这就要求在估算距离之前首先对目标进行准确识别,是汽车还是行人,是货车、SUV还是小轿车。准确...
  • 双目摄像头的“中科慧眼”认为双目测距算法才是最精确的 时间 2016-01-05 18:53:01 36氪 原文 http://36kr.com/p/5041919.html 主题 算法 ADAS(Advanced Driving Assistant System),即高级...
  • 学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化. 图1. 双摄像头模型俯视图图1解释了双摄像头测距的原理,书中Z的公式如下:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 754
精华内容 301
关键字:

双目摄像头测距原理