精华内容
下载资源
问答
  • 双目矫正及视差图的计算 立体匹配主要是通过找出每对图像间的对应关系,根据三角测量原理,得到视差图;在获得了视差信息后,根据投影模型很容易地可以得到原始图像的深度信息和三维信息。
  • 视差图转为深度

    千次阅读 2020-06-16 11:09:46
    有人容易把视差图跟深度搞混,一切还是要从这个公式说起:Z=f*B/d Z是深度,B是双目相机的光心间距(基线长度),f是相机焦距,d就是视差(左右相机对应特征像素坐标差值)。 而我们说的视差图就是灰度的灰度值...

    有人容易把视差图跟深度图搞混,一切还是要从这个公式说起:Z=f*B/d
    Z是深度,B是双目相机的光心间距(基线长度),f是相机焦距,d就是视差(左右相机对应特征像素坐标差值)。
    而我们说的视差图就是灰度图的灰度值为d的时候,想转化为Z就变成了深度图,所以这是个并不复杂的问题。
    代码里fx是内参的值,x方向的焦距,baseline是基线长。
    这里要注意深度图的类型,不同图像类型的尺度范围是不一样的,那么如果直接用于距离测量得到的只是一个相对深度,而不是精确的距离。如果图像的类型是CV_8UC1,那么对应的标识符要变成uchar ,CV_8S对应的是char, CV_16U对应的标识符应该是ushort.也就是说标识符要和图像数据类型相对应。short d = img.ptr<uchar>(row)[col];
    下面三个图就是在不同数据类型下产生的效果,坑也挺多的,这里生成的深度图的数值还不是真实的距离,因为在进行数据类型变换的时候数值尺度变了,OpenCV里面reprojectImageTo3D(disp, xyz, Q, true)这个函数得到的才是真实的三坐标值它计算出来的结果CV_16S或者CV_32S类型的, sgbm立体匹配算法出来的结果是CV_16S 类型的,在转换的过程中要确保前后尺度一致,可以简单的思考一下,d是视差值,大小不可能超过图像的分辨率,如果视差图的像素值超过了说明在类型变换的时候尺度变了。

    关于这些细节我懂的也不多,欢迎补充。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    根据Mat.type()输出的值判断图像的类型

    #include <iostream>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    using namespace std;
    using namespace cv;
    
    const double fx = 4152.073;
    const double baseline = 176.252;
    
    
    int main(int argc, char** argv)
    {
            Mat img = imread("E:\\intern\\depth\\disp0.png",0);
        cout << img.type();
    
       // Mat img = imread("E:\\intern\\depth\\disp0.png");
        Mat depth(img.rows, img.cols, CV_16S);  //深度图
        cout<< depth.type()<<endl;//https://blog.csdn.net/sysleo/article/details/96445786   查看图像类型,输出的数值去网站查表
        //视差图转深度图
        for (int row = 0; row < depth.rows; row++)
        {
            for (int col = 0; col < depth.cols; col++)
            {
                short d = img.ptr<uchar>(row)[col];
    
    
                if (d == 0)
                    continue;
    
                depth.ptr<short>(row)[col] = fx * baseline / d;
            }
        }
        namedWindow("img", 0);
        namedWindow("depth", 0);
        imshow("img", img);
        imshow("depth", depth);
        waitKey(0);
    }
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    毕竟是灰度图看起来不舒服,可以参考我的另外一篇文章转为伪彩色深度图
    在这里插入图片描述

    展开全文
  • 计算视差图

    千次阅读 2020-04-26 17:20:04
    一、计算视差原理1.1立体图像1.2计算视图差1.3双目立体匹配二、代码实现2.1图片集2.2结果展示2.3代码三、实验结果分析 一、计算视差原理 1.1立体图像 一个多视图成像的特殊例子是立体视觉(或者立体成像),即使用两台...

    一、计算视差原理

    1.1立体图像

    一个多视图成像的特殊例子是立体视觉(或者立体成像),即使用两台只有水平(向一侧)偏移的照相机观测同-.场景。当照相机的位置如上设置,两幅图像具有相同的图像平面,图像的行是垂直对齐的,那么称图像对是经过矫正的。该设置在机器人学中很常见,常被称为立体平台。通过将图像扭曲到公共的平面,上,使外极线位于图像行上,任何立体照相机设置都能得到矫正(我们通常构建立体平台来产生经过矫正的图像对)。假设两幅图像经过了矫正,那么对应点的寻找限制在图像的同一行.上。一旦找到对应点,由于深度是和偏移成正比的,那么深度(Z坐标)可以直接由水平偏移来计算,
    在这里插入图片描述
    其中,f是经过矫正图像的焦距,b是两个照相机中心之间的距离,x和x,是左右两.幅图像中对应点的x坐标。分开照相机中心的距离称为基线。矫正后的立体照相机设置如图所示。
    在这里插入图片描述
    立体重建(有时称为致密深度重建)就是恢复深度图(或者相反,视差图),图像中.每个像素的深度(或者视差)都需要计算出来。

    1.2计算视图差

    当密集地应用在图像中时,归一化的互相关值可以很快地计算出来。我们使用每个像素周围的图像块(根本上说,是局部周边图像)来计算归一化的互相关。对于这里的情形,我们可以在像素周围写出公式中的NCC,如下所示
    在这里插入图片描述

    1.3双目立体匹配

    1、采集图像:通过标定好的双目相机采集图像,可以用两个单目相机来组合成双目相机。
    2、极线校正:校正的目的是使两帧图像极线处于水平方向,或者说是使两帧图像的光心处于同一水平线上。通过校正极线可以方便后续的NCC操作。
    3、特征匹配:匹配方法如上所述,右视图中与左视图待测像素同一水平线上相关性最高的即为最优匹配。完成匹配后,我们需要记录其视差d,即待测像素水平方向xl与匹配像素水平方向xr之间的差值d = xr - xl,最终我们可以得到一个与原始图像尺寸相同的视差图D。
    4、深度恢复:通过上述匹配结果得到的视差图D,我们可以很简单的利用相似三角形反推出以左视图为参考系的深度图。

    二、代码实现

    2.1图片集

    左相机在这里插入图片描述

    右相机
    在这里插入图片描述

    2.2结果展示

    窗口值wid=4时

    在这里插入图片描述
    窗口值wid=6时在这里插入图片描述

    窗口值wid=9时
    在这里插入图片描述
    窗口值wid=12时
    在这里插入图片描述

    2.3代码

    # -*- coding: utf-8 -*-
    from PIL import Image
    from pylab import *
    import cv2
    from numpy import *
    from numpy.ma import array
    from scipy.ndimage import filters
    def plane_sweep_ncc(im_l,im_r,start,steps,wid):
        """ 使用归一化的互相关计算视差图像 """
        m,n = im_l.shape
        # 保存不同求和值的数组
        mean_l = zeros((m,n))
        mean_r = zeros((m,n))
        s = zeros((m,n))
        s_l = zeros((m,n))
        s_r = zeros((m,n))
        # 保存深度平面的数组
        dmaps = zeros((m,n,steps))
        # 计算图像块的平均值
        filters.uniform_filter(im_l,wid,mean_l)
        filters.uniform_filter(im_r,wid,mean_r)
        # 归一化图像
        norm_l = im_l - mean_l
        norm_r = im_r - mean_r
        # 尝试不同的视差
        for displ in range(steps):
            # 将左边图像移动到右边,计算加和
            filters.uniform_filter(np.roll(norm_l, -displ - start) * norm_r, wid, s) # 和归一化
            filters.uniform_filter(np.roll(norm_l, -displ - start) * np.roll(norm_l, -displ - start), wid, s_l)
            filters.uniform_filter(norm_r*norm_r,wid,s_r) # 和反归一化
            # 保存 ncc 的分数
            dmaps[:,:,displ] = s / sqrt(s_l * s_r)
            # 为每个像素选取最佳深度
        return np.argmax(dmaps, axis=2)
    
    def plane_sweep_gauss(im_l,im_r,start,steps,wid):
     """ 使用带有高斯加权周边的归一化互相关计算视差图像 """
     m,n = im_l.shape
     # 保存不同加和的数组
     mean_l = zeros((m,n))
     mean_r = zeros((m,n))
     s = zeros((m,n))
     s_l = zeros((m,n))
     s_r = zeros((m,n))
     # 保存深度平面的数组
     dmaps = zeros((m,n,steps))
     # 计算平均值
     filters.gaussian_filter(im_l,wid,0,mean_l)
     filters.gaussian_filter(im_r,wid,0,mean_r)
     # 归一化图像
     norm_l = im_l - mean_l
     norm_r = im_r - mean_r
     # 尝试不同的视差
     for displ in range(steps):
         # 将左边图像移动到右边,计算加和
         filters.gaussian_filter(np.roll(norm_l, -displ - start) * norm_r, wid, 0, s) # 和归一化
         filters.gaussian_filter(np.roll(norm_l, -displ - start) * np.roll(norm_l, -displ - start), wid, 0, s_l)
         filters.gaussian_filter(norm_r*norm_r,wid,0,s_r) # 和反归一化
         # 保存 ncc 的分数
         dmaps[:,:,displ] = s / np.sqrt(s_l * s_r)
     # 为每个像素选取最佳深度
     return np.argmax(dmaps, axis=2)
    
    im_l = array(Image.open('1.png').convert('L'), 'f')
    im_r = array(Image.open('2.png').convert('L'),'f')
    # 开始偏移,并设置步长
    steps = 12
    start = 4
    # ncc 的宽度
    wid = 9
    res = plane_sweep_ncc(im_l,im_r,start,steps,wid)
    import scipy.misc
    scipy.misc.imsave('depth.png',res)
    show()
    
    

    三、实验结果分析

    当窗口值改变时,结果也跟着改变。窗口值越大,匹配结果区分度越高,但也不能太大,窗口值太大时,匹配结果容易变得很黑。窗口值小时,容易出现颗粒状,图片辨认度低。

    展开全文
  • 视差图转换为深度的实现

    千次阅读 热门讨论 2020-06-19 15:35:25
    中b为双目相机的基线,一般需要自己测量(如果只需要相对深度的话可以自己取值)。f表示相机焦距(通常相机焦距有fx,fy,但由于视差只在x方向,因此直接取fx为f即可)。可以得到深度Z与视差d的关系为: 具体推导...

    视差图转换为深度图

    网上关于视差图转换为深度图的博客较多,但缺少具体实现。我根据原理和网上的一些参考自己实现了一个版本,做个记录,也希望能供大家参考

    1 原理

    根据视差图得到深度的原理很简单,示意如下:在这里插入图片描述
    图中b为双目相机的基线,一般需要自己测量(如果只需要相对深度的话可以自己取值)。f表示相机焦距(通常相机焦距有fx,fy,但由于视差只在x方向,因此直接取fx为f即可)。可以得到深度Z与视差d的关系为:
    式1
    式1
    具体推导可以参考推导过程。需要注意的是,d的单位是像素pixel,而其他几个变量的单位是mm,这看似单位不匹配(也是我一开始的困惑所在),但实际上是没有问题的。可以参考《视觉slam十四讲》的相机模型构建,相机成像过程如下:
    在这里插入图片描述
    主要分为:
    (1)实际空间点到物理成像平面上的投影;
    (2)物理成像平面转换到像素平面
    这两个过程。(1)中物理成像平面上对应实际空间点(X,Y,Z)的点(X’,Y’)是具有物理尺度的,只不过进行了缩放:

    X ′ = f ∗ X / Z X' = f*X/Z X=fX/Z
    Y ′ = f ∗ Y / Z Y' = f*Y/Z Y=fY/Z

    在此之后,(2)将物理成像平面上的坐标进一步转换到像素平面得到坐标(u,v),也就是我们使用的图像像素坐标,这个过程为:

    u = α X ′ + c x u = \alpha X' +cx u=αX+cx
    v = β Y ′ + c y v = \beta Y' +cy v=βY+cy

    f x = α f fx = \alpha f fx=αf, f y = β f fy = \beta f fy=βf, 这样就将像素坐标与三维空间点建立了联系。需要注意的是,焦距 f f f的单位确实是mm,但 α , β \alpha,\beta α,β的单位是pixel/mm。那么式1中的 f f f,也就是 f x fx fx的单位实际上是pixel,这样就和视差单位是pixel一致了。

    搞清楚原理后,下面就可以进行实现了。

    2 代码实现

    假定大家已经有了视差图,这里只进行深度图的求解。话不多说,直接上代码。main函数如下:

    int main(int argc, char* argv[])
    {
    	//视差图 D1, 深度图 depth1
    	cv::Mat D1,depth1, draw ,draw1;
    	//
    	//对视差图的计算,此处省略
    	//
    	sgm.disp2Depth(D1,depth1);//由视差图计算深度图
    	std::cout << "depth map is ok " << std::endl;
    	//转换成彩色图便于观察
    	depth1.convertTo(draw1, CV_8U, 1./256);
    	cv::applyColorMap(draw1, draw1, cv::COLORMAP_JET);
    	
    	//视差图也转换成彩色图
    	D1.convertTo(draw, CV_8U, 255. / (SemiGlobalMatching::DISP_SCALE * param.numDisparities));
    	cv::applyColorMap(draw, draw, cv::COLORMAP_JET);
    	
    	cv::imshow("image", I1);
    	cv::imshow("disparity1", draw);
    	cv::imshow("depth1", draw1);
    	cv::waitKey(0);
    }
    

    下面是disp2Depth()函数的实现,

    void SemiGlobalMatching::disp2Depth(cv::Mat dispMap, cv::Mat &depthMap)
    {
        	float fx = 4.9250945790423793e+02;//取fx为f,fx由标定内参得到
        	float baseline = 600; //基线距离b,根据标定的相机外参计算。如果只需要相对深度取1即可
    
            int height = dispMap.rows;
            int width = dispMap.cols;
    		depthMap.create(height, width, CV_16U);
    		
    		//这里深度图的数据类型可能会不一样,大家根据自己的情况进行修改
            short* dispData = (short*)dispMap.data;
            ushort* depthData = (ushort*)depthMap.data;
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
    				int id = i*width + j;
                    if (!dispData[id])  continue;  //防止0除
                    depthData[id] = ushort( fx*baseline / dispData[id]  );
                }
            }
    }
    

    结语

    相比于视差图的计算,深度计算只能算是饭后甜点了,不过还是需要把原理和思路理清。

    展开全文
  • 计算机视觉——计算视差图

    千次阅读 2020-04-26 17:19:34
    计算视差图1. 立体视差2. 极线矫正3. 归一化互相关(NCC)4 . 计算视差图的步骤5. 实验过程5.1 实验代码5.2 实验结果及分析5.2.1 视差图...立体视差测量包括三个步骤: (1)必须从一幅图像中选出位于场景中一个表面上...

    1. 立体视差

    立体视差 ,亦称立体视像、立体知觉。基于双眼视差所 获得的深度知觉。

    立体视差的测量包括三个步骤:
    (1)必须从一幅图像中选出位于场景中一个表面上的某一特定位置;
    (2)必须在另一幅图像中鉴别出同一个位置;
    (3)测出这两个对应像点之间的视差。

    在一组重复摄影的两张照片上(立体模式),同一地物的影象,沿着摄影基线(摄影地点和下一个摄影地点之间的飞行方向线)方向位置变换,这个变化量叫“立体视差”。

    立体视差在每张照片上,从那点到照片基线(临接摄影地点与照片的摄影地点的像连结的直线),下垂线的足和主点(相片中心)之间叫距离之和。这是把相对两个照片的基线方向,使其成为一直线,按摄影顺序排列时,和相应的同一地物影象间的两个照片主点之间的间隔差。

    2. 极线矫正

    一个多视图成像的特殊例子是立体视觉(或者立体成像),即使用两台只有水平(向一侧)偏移的照相机观测同一场景。当照相机的位置只有水平偏移观测同一场景时,两幅图像具有相同的图像平面,图像的行是垂直对齐的,那么称图像对是经过矫正的。该设置在机器人学中很常见,常被称为立体平台

    极线矫正:通过将图像扭曲到公共的平面上,使外极线位于图像行上,任何立体照相机设置都能得到矫正(我们通常构建立体平台来产生经过矫正的图像对)。

    假设两幅图像经过了矫正,那么对应点的寻找限制在图像的同一行上。一旦找到对应点,由于深度是和偏移成正比的,那么深度(Z 坐标)可以直接由水平偏移来计算,如下图所示:
    在这里插入图片描述
    其中, f f f 是经过矫正图像的焦距, T T T是两个照相机中心之间的距离, x l x_l xl x r x_r xr 是左右两幅图像中对应点的 x x x坐标。分开照相机中心的距离称为基线。

    根据上图可以得到相似三角形:
    Δ ( p l , p , p r ) ∼ Δ ( O l , p , O r ) \Delta (p_l,p,p_r)\sim \Delta (O_l,p,O_r) Δ(pl,p,pr)Δ(Ol,p,Or)
    根据相似三角形的性质可以得出如下公式:
    T + x l − x r T = Z − f Z \frac{T+x_l-x_r}{T} = \frac{Z-f}{Z} TT+xlxr=ZZf
    所以深度(Z 坐标)的计算如下:
    Z = f T x r − x l Z=f\frac{T}{x_r-x_l} Z=fxrxlT

    立体重建(有时称为致密深度重建)就是恢复深度图(或者相反,视差图),图像中每个像素的深度(或者视差)都需要计算出来。

    3. 归一化互相关(NCC)

    在立体重建算法中,我们将对于每个像素尝试不同的偏移,并按照局部图像周围归一化的互相关值,选择具有最好分数的偏移,然后记录下该最佳偏移。因为每个偏移在某种程度上对应于一个平面,所以该过程有时称为扫平面法。

    归一化互相关(NCC)算法的原理如下:如有校正过的两帧图像 I 1 I_1 I1,、 I 2 I_2 I2,NCC算法对图像 I 1 I_1 I1一个待匹配像素构建n*n匹配窗口,在图像 I 2 I_2 I2极线上对每一个像素构建匹配窗口与待匹配像素匹配窗口计算相关性,相关性最高的视为最优匹配。由于NCC匹配流程是通过在同一行中查找最优匹配,因此它可以并行处理,对于运行效率有一定的提升。

    我们使用每个像素周围的图像块(根本上说,是局部周边图像)来计算归一化的互相关。针对图像,像素周围重新写出公式中的NCC,如下所示:
    n c c ( I 1 , I 2 ) = ∑ x ( I 1 ( x ) − u 1 ) ( I 2 ( x ) − u 2 ) ( ∑ x ( I 1 ( x ) − u 1 ) 2 ∑ x ( I 2 ( x ) − u 2 ) 2 ) ncc(I_1,I_2)=\frac{\sum_{x}(I_1(x)-u_1)(I_2(x)-u_2)}{\sqrt(\sum_{x}(I_1(x)-u_1)^2\sum_{x}(I_2(x)-u_2)^2)} ncc(I1,I2)=( x(I1(x)u1)2x(I2(x)u2)2)x(I1(x)u1)(I2(x)u2)

    4 . 计算视差图的步骤

    经过上述分析,可以得到计算视差图的基本步骤如下:

    1. 极线校正:校正的目的是使两帧图像极线处于水平方向,或者说是使两帧图像的光心处于同一水平线上。通过校正极线可以方便后续的NCC操作。
    2. 特征匹配:这里便利用NCC做匹配的步骤,匹配方法如上所述,右视图中与左视图待测像素同一水平线上相关性最高的即为最优匹配。完成匹配后,我们需要记录其视差 d d d,即待测像素水平方向 x l x_l xl与匹配像素水平方向 x r x_r xr之间的差值 x r − x l x_r - x_l xrxl,由极线矫正部分中推导出的公式 Z = f T x r − x l Z=f\frac{T}{x_r-x_l} Z=fxrxlT f 、 T f、T fT已知,即可算出深度Z。最终我们可以得到一个与原始图像尺寸相同的视差图D。
    3. 深度恢复:通过上述匹配结果得到的视差图D,可以很简单的利用相似三角形反推出以左视图为参考系的深度图。

    5. 实验过程

    在本次实验中,首先实现视差图的计算,其次改变窗口值(wid)观察实验结果并分析窗口值(wid)对视差图的影响。

    5.1 实验代码

    from PIL import Image
    from pylab import *
    import numpy as np
    import scipy.ndimage.filters as filters
    import scipy.misc
    
    # 使用归一化的互相关计算视差图像
    def plane_sweep_ncc(im_l,im_r,start,steps,wid):
        m, n = im_l.shape
        # 保存不同求和值的数组
        mean_l = np.zeros((m, n))
        mean_r = np.zeros((m, n))
        s = np.zeros((m, n))
        s_l = np.zeros((m, n))
        s_r = np.zeros((m, n))
        # 保存深度平面的数组
        dmaps = np.zeros((m, n, steps))
        # 计算图像块的平均值
        filters.uniform_filter(im_l, wid, mean_l)
        filters.uniform_filter(im_r, wid, mean_r)
        # 归一化图像
        norm_l = im_l - mean_l
        norm_r = im_r - mean_r
        # 尝试不同的视差
        for displ in range(steps):
            #将左边图像移动到右边,计算加和
            filters.uniform_filter(roll(norm_l, -displ - start) * norm_r, wid, s)  # 和归一化
            filters.uniform_filter(roll(norm_l, -displ - start) * roll(norm_l, -displ - start), wid, s_l)
            filters.uniform_filter(norm_r * norm_r, wid, s_r)  # 和反归一化
            # 保存ncc 的分数
            dmaps[:, :, displ] = s / np.sqrt((s_l * s_r)+1e-5)
        # 为每个像素选取最佳深度
        return argmax(dmaps, axis=2)
    
    def plane_sweep_gauss(im_l,im_r,start,steps,wid):
        """ 使用带有高斯加权周边的归一化互相关计算视差图像"""
        m,n = im_l.shape
        # 保存不同加和的数组
        mean_l = zeros((m,n))
        mean_r = zeros((m,n))
        s = zeros((m,n))
        s_l = zeros((m,n))
        s_r = zeros((m,n))
        # 保存深度平面的数组
        dmaps = zeros((m,n,steps))
        # 计算平均值
        filters.gaussian_filter(im_l,wid,0,mean_l)
        filters.gaussian_filter(im_r,wid,0,mean_r)
        # 归一化图像
        norm_l = im_l - mean_l
        norm_r = im_r - mean_r
        # 尝试不同的视差
        for displ in range(steps):
            # 将左边图像移动到右边,计算加和
            filters.gaussian_filter(roll(norm_l,-displ-start)*norm_r,wid,0,s) # 和归一化
            filters.gaussian_filter(roll(norm_l,-displ-start)*roll(norm_l,-displ-start),wid,
            0,s_l)
            filters.gaussian_filter(norm_r*norm_r,wid,0,s_r) # 和反归一化
            # 保存ncc 的分数
            dmaps[:,:,displ] = s/np.sqrt(s_l*s_r)
        # 为每个像素选取最佳深度
        return argmax(dmaps,axis=2)
    
    if __name__ == '__main__':
        im_l = array(Image.open('data/3.jpg').convert('L'), 'f')
        im_r = array(Image.open('data/4.jpg').convert('L'), 'f')
        # 开始偏移,并设置步长
        steps = 12
        start = 4
        # ncc 的宽度
        wid = 9
        res1 = plane_sweep_ncc(im_l, im_r, start, steps, wid)
        scipy.misc.imsave('depth1.png', res1)
        # scipy.misc.imsave('depth2wid'+str(wid)+'.png', res1)
        res2 = plane_sweep_gauss(im_l, im_r, start, steps, wid)
        scipy.misc.imsave('depth2.png', res2)
    

    5.2 实验结果及分析

    5.2.1 视差图计算结果

    ① 第一组图像的NCC均匀滤波器视差图和NCC高斯滤波器视差图结果
    NCC均匀滤波器视差图:wid=9
    NCC高斯滤波器视差图:wid=3
    在这里插入图片描述

    ② 第一组图像的NCC均匀滤波器视差图和NCC高斯滤波器视差图结果
    NCC均匀滤波器视差图:wid=27
    NCC高斯滤波器视差图:wid=9
    在这里插入图片描述
    以上实验结果是两组图像分别实现均匀滤波器计算视差和高斯滤波器计算视差的方法,可以看出:
    与均值滤波版本相比,高斯滤波版本具有较少的噪声,但缺少很多细节信息。 对于第一组图像来说均匀滤波器计算出的视差图较为容易观察一些,而对于第二组图像来说其均匀滤波器计算出的视差图太过杂乱,使用高斯滤波器计算的视差图较为平滑,减少了均匀滤波器的杂乱感更容易观察一些。
    分析原因如下:
    均匀滤波器给定正方形图像块中所有像素相同的权值,所以可以观察到使用均匀滤波器得到的视差图没有那么平滑。而高斯滤波器高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到,所以而后使用高斯滤波器替换均匀滤波器,可以看到产生了更加平滑视差图。

    均匀滤波器和高斯滤波器的区别:
    其窗口模板的系数和均值滤波器不同,均值滤波器的模板系数都是相同的为1;而高斯滤波器的模板系数,则随着距离模板中心的增大而系数减小。所以,高斯滤波器相比于均值滤波器对图像个模糊程度较小。

    对于接下来考虑wid值对于视差图计算的影响进行实验,所以选用较为容易观察的数据进行实验,即第一组图像中的NCC均匀滤波器的方法。

    5.2.2 不同窗口值(wid)的视差图

    观察代码可知:wid值在主函数中进行赋值,从而作为参数传给计算视差图的函数,在计算视差图的函数中再次将wid值作为参数传给均匀滤波器的方法。即wid值的影响应该为:先影响滤波结果,再接着滤波结果影响视差图的计算,所以在进行分析的时候应首先考虑wid值对滤波的影响,再考虑滤波对是视差图的影响。

    随着wid值的改变,即改变了滤波器的模板大小,对于均值滤波器来说,经过滤波后图像的每一个像素的灰度值都是原图像中窗口值大小内的所有灰度值的均值,可以得到结论:当wid值越小,得到的像素值越不能参考周围像素点的灰度值;当wid值越大,得到的像素值越能参考周围像素点的灰度值。

    实验结果分为两部分:第一部分为不同wid值整合在一起进行对比的图像,如下六张图分别是wid不同值的图像整合在一张图中,用来观察轮廓及大致影响。第二部分为六张不同wid值的细节图,用于观察细节。

    在观察实验结果的时候需注意:灰度值越小的地方视差越小,即距离照相机越近。

    (一) 第一部分
    在这里插入图片描述
    由上图观察可得:随着wid值的增大,图像深度信息的图像的轮廓逐渐明显,可以大致看出距离照相机最近的物体即为台灯,但较远处的物体就无法分辨。
    可以得出结论:
    wid值越大,产生的深度图噪声小,然而计算代价高。模板太大会丢失物体边缘上的细节。

    进而思考:wid值影响了滤波结果,滤波结果影响了NCC的匹配度的计算。当wid值较小,滤波结果就较为局限,进而NCC的匹配度就会不准确,然后在计算视差的时候可能造成匹配到的不是同一特征点,最后计算出的视差会有误差,视差图就较为杂乱不易观察;在wid值较大的时候,滤波结果就较为开放,可以考虑到周围像素的影响,进而降低NCC匹配度的误差,得到的视差图轮廓明显,易观察。

    (二) 第二部分

    ① wid=3
    在这里插入图片描述
    ② wid=5
    在这里插入图片描述
    ③ wid=7
    在这里插入图片描述
    ④ wid=9
    在这里插入图片描述
    ⑤ wid=11
    在这里插入图片描述
    ⑥ wid=13
    在这里插入图片描述
    在这六幅图像中,选取台灯为观察点截取局部图像如下:

    3/95/117/13

    可以看到当wid值较小的时候台灯的两根支架的细节信息是很丰富的,虽然当wid=3时整张图像很杂乱,无法抓住重点,担当截取出台灯的部分可以看到其细节是很丰富的,随着wid值的增大台灯两根支架的细节信息逐渐消失。

    由于wid值影响了滤波结果,滤波结果影响了NCC的匹配度的计算。可以分析:当wid值较小,滤波结果仅仅只受自身和周围较少像素的影响,所以就会保留更多自身的特征性在,进行NCC的匹配计算视差的时候细节信息就会更丰富一些,但也可以看到当wid值较小的时候视差图是很杂乱的,无法直接观察出视差的区别。;在wid值较大的时候,可以考虑到周围像素的影响,可以使自身和周围像素更好地融合,得到的视差图的轮廓信息较为明显,易观察。

    总结以上所有分析过程可以得到如下实验结论:

    1. wid值越大,细节更丰富,但噪声点更多。
    2. wid值越小,稳健性更好,但细节信息更少。

    6. 实验中遇到的问题及解决

    1.在进行实验的过程中遇到如下报错:

    RuntimeError: output shape not correct
    

    经过排查发现同一组的两幅图像尺寸不一致如下:

    使用python库中图像处理的函数更改图像尺寸大小即可。

    2.在进行实验的过程中遇到如下警告:

    RuntimeWarning: divide by zero encountered in true_divide
      dmaps[:, :, displ] = s / np.sqrt((s_l * s_r))
    

    其原因大致时因为根号下的数不能为0,所以将改行代码更改为:

    dmaps[:, :, displ] = s / np.sqrt((s_l * s_r)+1e-5)
    

    为根号下的数字加上1e-5,其数值不大,对原本数据也不会造成影响,所以造成的影响不大,同时也解决了根号下不能为0的问题。

    展开全文
  • 双目立体视觉,在百度百科里的i解释是这样解a释的:双目立体视觉(Binocular Stereo Vision)是机器视觉的一种重要形式,它是基于视差原理并利用成像设备从不同的位置获取被物体的两幅图像,通过计算图像对应点间...
  • OpenCV视差图计算

    千次阅读 2018-05-14 21:43:52
    OpenCV视差图计算 如今立体视觉越来越多的被应用到工业检测、机器人、自动驾驶、AR/VR领域,因为目前自己也在一个产品研发期,自己倒腾了几天做了一些通过双目进行避障的小实验,把一些比较流程化的代码以及相应...
  • 学习笔记:经过一段时间双目视觉的学习,做到stereo_match,达到较好双目极线矫正的效果,其中RMS=0.21,得到视差图与pointcloud.txt文件,但不知道txt文件的含义,用matlab处理后得到锥形三维图像。明显不是物体...
  • 在之前的教程中,我向您展示了如何使用CSS 3D变换创建等轴网格布局 。 这是非常具有挑战性的,因为诸如Firefox之类的一些浏览器在如何在三维平面上呈现元素方面具有略有不同的方法。 在本教程中,我们将通过受...
  • NCC视差匹配计算视差图(python)

    千次阅读 2020-04-26 17:21:36
    一、视差计算原理 1.1NCC视差匹配方法 归一化相关性(normalization cross-correlation),简称NCC。其是对图像内的像素点来构建一个nn的邻域作为匹配窗口,然后对目标像素位置同样的构建一个nn大小的匹配窗口,...
  • 计算视差图一、立体图像1.1概念1.2关于图像配准算法二、立体重建之计算视差图2.1归一化及算法概念2.2匹配流程三、实验测试3.1实验要求3.2实验代码3.3实验结果分析3.4实验总结和遇到的问题 此次实验的内容主要有关于...
  • 以下程序使用同一物体的两幅图像来计算视差图距离摄像头近的点在视差图中会有更明亮的颜色。黑色区域代表两幅图像的差异部分。 import numpy as np import cv2 def update(val = 0): stereo.setBlo
  • 本期话题:深度内容要点1. 深度基础知识2. 不同的技术路径传统方法早期...顾名思义,深度是用来反映深度信息的图像,而其中的深度信息指的就是距离信息。它用来描述相机拍摄到的场景图像中每个像素点到相机的...
  • 文章目录一、什么是立体图像二、以窗口代价计算视差的原理三、归一化互相关(NCC)算法匹配原理 一、什么是立体图像 一个多视图成像的特殊例子是立体视觉(或者立体成像),即使用两台只有水平(向一侧)偏移的...
  • LearnOpenGL学习笔记—高级光照 05:视差贴图1 引入1.1 偏移方法一1.2 偏移方法二2 视差贴图3 陡峭视差映射4 视差遮蔽映射5 代码 本节对应官网学习内容:视差贴图 结合英文原站,中文站,以及个人实践进行描述(这...
  • 计算机视觉python--计算视差图

    千次阅读 2020-04-26 18:07:52
    立体视差测量包括三个步骤: (1)必须从一幅图像中选出位于场景中一个表面上的某一特定位置; (2)必须在另一幅图像中鉴别出同一个位置; (3)出这两个对应像点之间的视差。 在一组重复摄影的两张照片上(立体模式)...
  • 实现NCC 视差匹配方法,即给定左右两张视图,根据NCC计算视差图 分析不同窗口值对匹配结果的影响,重点考查那些点(或者哪些类型的点)在不同窗口大小下的匹配精度影响 文章目录1. 实验原理1.1 立体图像1.2 计算...
  • 相机成像的模型如下所示: ...XR和XT是两个成像点在左右两个像面上距离图像左边缘的距离。    若两个相机已经校正完成即达到极线平行,两条光轴方向也平行。则视差和物体深度的关系式如下:    ...
  • 视差图转换为深度公司 Last week we talked about ZorroSVG, a tool for converting your chunky transparent PNG-32s into slim and flexible SVGs. 上周,我们讨论了ZorroSVG ,该工具可将您的透明透明PNG-32...
  • 计算机视觉——立体视觉NCC法计算视差图原理归一化互相关NCC深度立体视觉立体视觉目标计算视差图步骤测试图像左图像右图像运行结果及分析窗口值为3窗口值为6窗口值为9窗口值为11窗口值为100分析遇到的问题NameError:...
  • 点击上方“3D视觉工坊”,选择“星标”干货第一时间送达作者:Ali Yasin Eser编译:ronghuaiyang(AI 公园)导读双目立体视觉的第二部分,视差图计算算法。大家好!欢迎...
  • 视差Disparity与深度

    2021-02-03 19:57:14
    双目立体视觉,在百度百科里的解释是这样解释的:双目立体视觉(BinocularStereoVision)是机器视觉的一种重要形式,它是基于视差原理并利用成像设备从不同的位置获取被物体的两幅图像,通过计算图像对应点间的...
  • 第五讲stereoVision.cpp主要介绍双目图像如何生成视差图和点云图。
  • 【python计算机视觉】计算视差图

    千次阅读 2020-04-26 14:26:37
    计算视差原理 1.1 立体图像 一个多视图成像的特殊例子是立体视觉(或者立体成像),即使用两台只有水平(向 一侧)偏移的照相机观测同一场景。当照相机的位置如上设置,两幅图像具有相同 的图像平面,图像的行是...
  • 视差图和深度有何关系I bet it’s more powerful than you think… 我敢打赌,它比您想像的还要强大…… Photo by Pereanu Sebastian on Unsplash Pereanu Sebastian在Unsplash上拍摄的照片 The question comes ...
  • 实现NCC 视差匹配方法,即给定左右两张视图,根据NCC计算视差图 分析不同窗口值对匹配结果的影响,重点考查那些点(或者哪些类型的点)在不同窗口大小下的匹配精度影响 2、语言和平台 语言:python2.7.13 ...
  • 而深度的应用范围非常广泛,由于其能够记录场景中物体距离摄像机的距离,可以用以测量、三维重建、以及虚拟视点的合成等。 为了模拟人眼对立体场景的捕捉和对不同景物远近的识别能力,立体匹配算法要求采用两...
  • 使用 Matlab 生成双目视差及点云图像

    千次阅读 多人点赞 2020-06-05 21:22:20
    最近需要验证一下双相机的成像效果,一开始使用了opencv + python/cpp 代码采集、标定并生成视差图,效果不是很理想,所以决定先用 matlab 标定相机,生成图像点云,查看效果,如果不错的话,以此为基准优化 open.
  • 图像的视差匹配(Stereo Matching)

    万次阅读 2016-04-16 10:30:26
    视差图返回的值是计算得到的视差乘以3之后的,所以在计算时我不是两个值相差大于1,而是大于3,因为两个图像都乘3了,所以要大于3,我传入的参数是两个图像的矩阵,因为我是写了一个脚本咯跑所有例的,在脚本...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,396
精华内容 1,758
关键字:

视差图测量距离