精华内容
下载资源
问答
  • 视差图转换为深度图的实现

    千次阅读 热门讨论 2020-06-19 15:35:25
    双目视觉视差图转换为深度图 视差图转换为深度图 网上关于视差图转换为深度图的博客较多,但缺少具体实现。我根据原理和网上的一些参考自己实现了一个版本,做个记录,也希望能供大家参考 1 原理 根据视差图得到深度...

    视差图转换为深度图

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

    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]  );
                }
            }
    }
    

    结语

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

    展开全文
  • 双目相机视差图转换成深度图

    千次阅读 2021-03-16 20:24:24
    depth表示深度图;f表示归一化的焦距,也就是内参中的fx; baseline是两个相机光心之间的距离,称作基线距离;disp是视差值。 代码: void disp2Depth(cv::Mat dispMap, cv::Mat &depthMap, cv::Mat K) { int ...

    视差的单位是像素(pixel),深度的单位往往是毫米(mm)表示。而根据平行双目视觉的几何关系,可以得到下面的视差与深度的转换公式:

    depth = ( f * baseline) / disp

    depth表示深度图;f表示归一化的焦距,也就是内参中的fx; baseline是两个相机光心之间的距离,称作基线距离;disp是视差值。

    代码:

    #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("C:\\Users\\YP\\Desktop\\4.png",0);
        cout << img.type();
    
       // Mat img = imread("C:\\Users\\YP\\Desktop\\4.png");
        Mat depth(img.rows, img.cols, CV_16S);  //深度图
        cout<< depth.type()<<endl;
        //视差图转深度图
        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);
    }
    
    

    上面代码中设置深度图的精度为CV_16UC1,也就是ushort类型,将baseline设置为60mm,转换后保存为png格式即可。如果保存为jpg或者bmp等图像格式,会将数据截断为0-255。所以保存深度图,png格式是理想的选择。

    效果展示:
    在这里插入图片描述

    展开全文
  • 根据视差图和外方位元素生成物方点云或数字表面模型
  • 视差图转为深度图

    千次阅读 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);
    }
    

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

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

    展开全文
  • 用matlab实现由双目图恢复出场景视距图(深度图)的代码,亲测可用,提供大家参考参考。
  • 深度图转视差图 decompose3 (Image, Xm, Ym, Zm) 视差图合成深度图 compose3 (Xm, Ym, Zm , MultiChannelImage) 视差图合成点图模型 xyz_to_object_model_3d (Xm, Ym, Zm, ObjectModel3DModel) 把点云...

    在这里插入图片描述

    • 深度图转视差图

    在这里插入图片描述

    • 视差图合成深度图
    • 视差图合成点图模型
      在这里插入图片描述
    • 把点云模型差分成x,y,z的点坐标
      在这里插入图片描述
    • 通过x,y,z三维点云坐标点合成点云模型
    • 对比二维联合算子 ‘Union’
    gen_object_model_3d_from_points(x, y, z, ObjectModel3D1)
    
    展开全文
  • (转载不是目的,而是为了方便自己!) 双目立体视觉,在百度百科里的i解释是这样解a释的:双目立体视觉(Binocular Stereo Vision...一 、视差 Disparity与深度图 提到双目视觉就不得不提视差图:双目立体视觉...
  • 利用python实现SGBM算法,实现对视频的读取显示,计算左右视差图,将其播放出来
  • 使用的OpenCV自带方法sgbm计算求取视差图,配置好OpenCV环境,入口写好的,直接可用。opencv2和opencv3sgbm的写法略有不同。
  • 双目立体匹配程序中最后输出视差图,那怎么得到他的深度图,最好可以给出程序
  • 从双目视觉图片,左右双摄得到的图像,来获取图片的深度信息。从而用于构建3d图片。
  • 视差Disparity与深度图

    千次阅读 2021-02-03 19:57:14
    自:http://www.elecfans.com/d/863829.html ...一、视差Disparity与深度图 提到双目视觉就不得不提视差图:双目立体视觉融合两只眼睛获得的图像并观察它们之间的差别,使我们可以获得明显的深度感,建立特征间的对
  • import cv2 import os.path import glob import numpy as np from PIL import Image def convertPNG(pngfile,outdir): # READ THE DEPTH im_depth = cv2.imread(pngfile) #apply colormap on deoth image(image...
  • 视差图推出深度图

    千次阅读 2020-01-13 15:30:03
    视差图推出深度图 相机成像的模型如下图所示: P为空间中的点,P1和P2是点P在左右像平面上的成像点,f是焦距,OR和OT是左右相机的...
  • * @文档名称: 深度图显示点云。 * @作者: hugo * @版本: 1.1 * @日期: 2021-6-20 * @描述: 该方法支持显示3D彩色点云以及灰度点云。 ***********************************************/ read_image (imageReal, ...
  • 视差图和深度图有何关系I bet it’s more powerful than you think… 我敢打赌,它比您想像的还要强大…… Photo by Pereanu Sebastian on Unsplash Pereanu Sebastian在Unsplash上拍摄的照片 The question comes ...
  • 视差图转化得到深度图的一个c++
  • 视差图常为CV_16S或CV_32S等,如果直接使用cv::imwrite()保存视差图或深度图,则图像将被成CV_8U格式,损失很大的精度。 保存 在进行保存的时候,为保存无压缩图像,需要使用到cv::imwrite()的第三个参数。 显示...
  • 由两张视差图生成深度图

    千次阅读 2020-06-01 20:34:32
    由两张视差图生成深度图,SGBM方法输入的是未矫正的图片,BM输入的是校正后的图片 在这里插入代码片#include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <opencv2/...
  • 前提:你有一些disp(视差)图,例如我是在“”/home/lj/workspace/open-npy/img_d/”文件夹下有disp_1.bmp、disp_2.bmp、disp_3.bmp、disp_4.bmp四张视差图,来制作disp_re_1.npy、disp_...视差图转深度信息就不在...
  • 介绍深度图视差图之间的转换关系
  • Matlab生成视差图

    2018-03-03 20:39:21
    双目视觉,根据块匹配方法的视差图生成。依据Matlab生成视差图
  • 来源:博客园作者:一度逍遥双目立体匹配一直是双目视觉的研究热点,双目相机拍摄同一场景的左、右两幅视点图像,运用立体匹配匹配算法获取视差图,进而获取深度图。而深度图的应用范围非常广泛,由于其...
  • 双目矫正及视差图的计算 立体匹配主要是通过找出每对图像间的对应关系,根据三角测量原理,得到视差图;在获得了视差信息后,根据投影模型很容易地可以得到原始图像的深度信息和三维信息。
  • 该文件与提交至 STSIVA 2014 的文件一起提供,请在有空时阅读论文以了解其内容:标题 ---使用立体类分类法在光场中进行深度图估计-- -- 摘要-- 光场或 LF 是一个函数,它描述了通过场景中每个点(空间)在每个方向...
  • 我再操作的过程是这样做的:(1)下载好对应版本的软件(2)单独配置好每一个环境,(下面opencv的实现过程会教你如何以一次实现永久配置PCL配置好以后)用实例去实现一下;(3)再把他们创建的环境模块导入新建好的...
  • 深度图 原始深度图像(可选) 相机矩阵 如果您对深度图像感到困惑或没有深度图像,请参阅。 用法 我已经在getHHA.py中提供了一个接口。 该函数名为getHHA(C,D,RD) 。 具体而言,它需要相机矩阵C ,深度图像D和...
  • matlab图像视差图代码通过内容自适应多分辨率合并将单目深度估计模型提升到高分辨率 此存储库包含我们的 CVPR2021 出版物的实现: 通过内容自适应多分辨率合并将单目深度估计模型提升到高分辨率。 S. Mahdi H. ...

空空如也

空空如也

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

视差图转深度图