OpenGL 编程指南(第八版)学习笔记——5 视口变换、剪切与反馈_opengl 视口变换-程序员宅基地

技术标签: 视图矩阵  蓝天日记  OpenGL  OpenGL 编程指南  OpenGL 编程指南笔记  投影矩阵  

OpenGL 编程指南学习资料以及我整理的代码下载地址https://pan.baidu.com/s/1bqrcspD

文中提到的代码为下载文件中的“OpenGL编程指南 VS2015代码.zip”文件

 

 

5 视口变换、剪切与反馈

视口变换

这一部分涉及到很多数学知识,书中有讲解。看这一部分之前最好先把书中5.1和5.2看完,需要理解齐次坐标,以及矩阵是如何对物体进行移动、旋转、缩放的。对于视图变换和投影变换,这里会有详细解答。

 

        理解模型变换:在3D系统中会大量使用矩阵对模型进行变换,如移动,缩放,旋转等等。理解矩阵是如何使模型移动缩放是3D编程的第一步。具体如何理解,我想最好的方法是通过实际数据比较。我们可以设计一个简单的2维正方形数据,不必是3D的,可以把四个点Z轴值设为0,然后将正方形数据通过矩阵相乘得到一个正方形数据。最后可以把前后两个数据手动绘制出来进行对比。

 

3D坐标系统原理

这里的原理并不是指数学原理,这里指的是为什么3D系统中需要进行模型变换,视口变换,投影变换,以及这些变换做了些什么,做这些有什么用。对于第一次接触3D编程时,面对这些问题总是很茫然,书中对这一部分的讲解非常少,完全没有讲清楚,看完后更加迷糊。

 

为了理解3D,我们从而2D开始讲起。我们绘制的窗口就是2D系统,这里就拿Win32 窗口上GDI绘图来讲。在Win32 窗口上GDI绘图时我们会以窗口左上角为原点,往右和往下分别说x轴和y轴的正方向。如果我们要在窗口上绘制一个矩形,首先我们需要知道窗口的长宽,然后我们需要确定绘制矩形的坐标x、y和矩形的宽高width、height,这样我们就可以确定绘制后的图。例如在400*400窗口上的(50,50)位置绘制一个200*200的矩形,绘制结果如下:

绘制图形独立设计

以上的例子中我们在表示要绘制的矩形,使用了一个坐标(x, y)和矩形的长宽(width, height)。这种表示方式限制很大,如果换了三角形、圆形、梯形等等,都不是一个长宽就可以确定的,而且这种方式也不适合我们OpenGL绘制,OpenGL绘制时都是将顶点数据传入顶点着色器进行绘制。为了更加灵活的方式并适合OpenGL绘制,我们使用四个点来表示矩形。使用四个点来表示矩形时,这四个点的数据为(50, 50)、(50, 250)、(250, 50)、(250, 250)。

 

用以上四个点表示矩形时,可以绘制出以上图形,但是如果要绘制的矩形位置发生了变换时,四个点的数据都需要改变,这使得这个设计的矩形无法复用。为了使得矩形能够复用,我们需要可已给矩形加上一个坐标(x, y),绘制时可以把顶点与坐标相加即可。

 

矩形数据(50, 50)、(50, 250)、(250, 50)、(250, 250),是以窗口坐标系统为参考系设计的。但我们在设计模型时,可能并不知道我们的图形要绘制到哪个窗口。那我们要如何设计呢,我们可以自己定义一个坐标系统,然后在这个坐标系统下设计一个矩形,如下:

四个点的数据变为(-100, -100)、(-100, 100)、(100, -100)、(100, 100)。绘制以上窗口中的图形时只需要把坐标(x, y),设为(150, 150)就可以了,绘制时的数据就会变成(50, 50)、(50, 250)、(250, 50)、(250, 250)。我们在设计矩形时用的坐标系被称为本地坐标系,四个点的坐标(-100,-100)、(-100, 100)、(100, -100)、(100, 100)为本地坐标

 

也许我们在绘制时发现矩形太大,需要矩形缩小一半,我们可以把矩形四个点都除以2,矩形数据变为(-50, -50)、(-50, 50)、(50, -50)、(50, 50),绘制后的矩形便会缩小一半。这个过程我们称为模型变换

 

无参考系绘图

在以上绘图时,我们都是以窗口左上角,即窗口坐标系原点为参考进行绘图的。当我们需要在坐标(x, y)处绘图时,只需要按照窗口左上角向左偏移x,向下偏移y就可以。在3D系统绘图时,我们并不能在窗口上找到一个参考点作为3D绘图的参考点,如果直接绘制将会感觉无从下手,不知在哪个位置绘制,如同“迷路”了。

 

想象一下这样的场景,给你一个平面,这个平面可以无限延伸,现在要在这个平面上绘图然后显示在窗口上。要完成绘制需要解决两个问题:1、我需要在给定的平面上自己定义一个坐标系,然后在这个坐标系绘图;2、需要一个绘图坐标系到窗口的映射,然后我们需要在绘图平面圈一块区域显示到窗口上。现在我们来逐一解决这两个问题。

 

1.  定义一个坐标系:这个很简单,我们可以随意定义一个坐标系,例如我们定义一个坐标系然后在(100, 100)处绘制我们之前设计好的矩形,如下图:

这里我们定义的坐标系称为世界坐标系,在世界坐标系下四个点被转换成(0, 0)、(200, 0)、(0, 200)、(200, 200),这个坐标称为世界坐标,这个过程称为世界坐标变换

 

2. 将图形显示到窗口:这个分两个步骤,第一转换绘制的图形,将绘制图形转换成一个与需要显示的坐标一致的坐标系;第二用一个矩形框选择一块区域显示到窗口上。

我依然显示一个最开始窗口上绘制矩形的截图。首先我们转换绘制后的图形,以上绘图需要转换成以下坐标,注意Y轴的方向发生了变换

这里用于转换的坐标系称为视图坐标系,也成为摄像机坐标系,在摄像机坐标系下四个点被转换成(-150, -150)、(-150,50)、(50, -150)、(50, 50),这个坐标称为摄像机坐标,这个过程称为视图变换

 

从上图的虚线矩形可以看到选择显示矩形框,这个矩形区域要就是我们要显示在窗口上的区域。很显然要将这个虚线框内的图形转换到窗口坐标下,只需要每个点加上(200, 200)就行。转换后的坐标为(50, 50)、(50, 250)、(250, 50)、(250, 250),这个转换我们称为投影变换,就如同把要显示的内容投影到窗口。

 

可能你这里会有一个问题,就是为什么要进行视图变换,似乎在定义世界坐标系的时候,直接定义一个与视图坐标系一样的坐标系就行。当然这中方法对于视口不变的情况下是完全可行的,但是对于视口变换的情况,如FPS游戏我们的视口总是在移动,而且还会旋转,这个时候就需要视图变换,这样可以保证我们的绘制物体的坐标不用变换,只需要进行视口变换就行。

 

小总结

3D绘图的也时按照以上过程进行绘制的,坐标转换的流程如下:

注意实际的3D绘图中,投影变换后的坐标并不是最终窗口上绘制的坐标,投影变换后的坐标是齐次空间的坐标,还需要将x、y、z除以第四个的w分量,才是最终的窗口坐标。

3D坐标变换时都是采用矩阵完成的,后面我会讨论OpenGL中两个重要的变换矩阵推导过程,即视图变换和投影变换使用的矩阵,这两个矩阵书中也没有提到推导过程。

 

视图矩阵推导

注:这里的推导过程是参考了书籍《DIRECTX9.3D游戏开发编程基础》中第12.2章。

视图矩阵的作用:可以将一个世界坐标的点转换成摄像机坐标。

要想世界坐标系变换到视图坐标系,首先我们需要将世界坐标系平移,然后旋转世界坐标系,让世界坐标系的x、y、z轴与视图坐标系重合。所以转换可以分为两个步骤:1移动,2旋转。

 

平移

假如世界坐标系中的P点为视图坐标系统的原点,设平移矩阵为T,则T * P=(0,0,0,1)T,平移矩阵T如下:

 

旋转

假设r、u、d为世界坐标系下单位向量(长度为1),且经过视图矩阵变换后会与视图坐标系的x、y、z轴重合。由于向量旋转跟矩阵的第四维无关系,所以我们设三位矩阵A3x3为旋转矩阵,则有如下关系:

把三个等式左右俩边的等式都合并:

首先A矩阵存在且唯一。因为r、u、d向量旋转后要在x、y、z轴上,且为单位向量,则它们之间两两互相垂直,且模为1,所以有以下等式:

r﹒u=0;r﹒d=0;u﹒d=0

r﹒r=1;u﹒u=1;z﹒z=1

最终可以推导出A矩阵如下:

最后再将A矩阵补全为4x4的矩阵,并与平移矩阵合并,就可以得到视图转换矩阵V了,如下:

 

我们的代码中有一个辅助向量库vmath.h,这里面的Lookat函数就是创建一视图矩阵的函数,代码如下:

template <typename T>
static inline Tmat4<T> lookat(vecN<T,3> eye, vecN<T,3> center, vecN<T,3> up)
{
    const Tvec3<T> f = normalize(center - eye);
    const Tvec3<T> upN = normalize(up);
    const Tvec3<T> s = cross(f, upN);
    const Tvec3<T> u = cross(s, f);
    const Tmat4<T> M = Tmat4<T>(Tvec4<T>(s[0], u[0], -f[0], T(0)),
                                Tvec4<T>(s[1], u[1], -f[1], T(0)),
                                Tvec4<T>(s[2], u[2], -f[2], T(0)),
                                Tvec4<T>(T(0), T(0), T(0), T(1)));
    return M * translate<T>(-eye);
}

 其中参数eye为视图坐标系的原点;center为所看物体中心的位置;up为物体向上的方向。

 

投影矩阵推导

投影矩阵的推导来自网上:http://www.songho.ca/opengl/gl_projectionmatrix.html这里只是对文章添加了一些说明。

 

首先我们要明确投影矩阵的作用:1.投影矩阵要在视图坐标系统中选择块要显示在窗口上的区域;2.投影矩阵需要将视图坐标系下的坐标转换成绘图坐标,即顶点着色器中gl_Position的输出值。投影变换后的坐标并不是最终窗口上绘制的坐标,投影变换后的坐标是齐次空间的坐标,还需要将x、y、z除以第四个的w分量,才是最终的窗口坐标。

选择区域:第一章中我们说过OpenGL使用的是规格化设备坐标(Normalized Device Coordinate, NDC),规格化设备坐标的范围为[-1.0,1.0]之间,即OpenGL中x, y, z的坐标必须在[-1.0, 1.0]之间,超出范围的片元会被剪切掉,不会显示。利用这一特性我们可以让要绘制的图形x, y, z坐标映都射到[-1.0, 1.0]之间,不要显示的则x, y, z坐标任一一个值小于-0.1或大于1.0。

转换坐标:视图坐标系下的坐标是三维坐标,我们需要把这个三维坐标转换成2维坐标。投影方式有两种:一种是远近物体都按同样的比例进行投影,这种投影称为正交投影;另一种是会根据物体的远近对物体进行一定的缩放,越远越小,这种投影称为透视投影。透视投影会更接近真实的显示效果,正常情况向同一物体我们在远处看也是更小的。这两种投影模型如下图:

 

投影矩阵推导中使用的变量

近平面:n (这是一个正数)

远平面:f (这是一个正数)

近平面上边界:t

近平面下边界:b

近平面左边界:l

近平面右边界:r

摄像机坐标(视图坐标,Eye Coordinates):(Xe, Ye, Ze, We)

近平面上的投影坐标(projection Coordinates):(Xp, Yp),二维平面坐标

窗口上绘制使用的NDC坐标(Normalized Device Coordinates):(Xn, Yn,Zn)

投影矩阵(Projection Matrix):Mproject

投影矩阵转换后的齐次空间坐标(Clip Coordinates):(Xc, Yc, Zc, Wc)

 投影矩阵最终的目标是将(Xe, Ye, Ze, We)转换成(Xc,Yc, Zc, Wc),推导就是找出两者的关系。最终的矩阵用:n,f, t, b, l, r表示,

 OpenGL投影的方向是视图坐标系Z轴的负方向,使用的是右手坐标。(左右手坐标主要会影响左边界和右边界在X轴上的方向,最终影响图形的左右方向。)

 

 

透视投影矩阵推导

投影矩阵会将在视图坐标系下一个点投影到近平面,近平面也就是我们的投影平面。投影的方式是将(Xe, Ye, Ze)点与视图坐标系原点直线连接,这条线会与近平面相交相交点也就是投影点。以下图片显示了一个点(Xe, Ye, Ze)如何投影到近平面上的 (Xp,Yp, Zp) 

从俯视图中根据相似三角形的比例关系,得到Xe和Xp的关系

从侧面视图中根据相似三角形的关系得到和Ye的Yp关系

从以上两个等式可以注意到Xp和Yp的值都需要除以-Ze。经过投影矩阵变换后的点(clip coordinates),在绘制之前还有一个齐次坐标转换的步骤,OpenGL会自动完成这个步骤,这个步骤会将x, y, z的值都除以最后一个w分量,如下图:

Mproject为投影矩阵,(Xc,Yc, Zc, Wc),(Xe, Ye, Ze, We)为摄像机坐标,(Xn, Yn, Zn)为窗口上绘制的坐标

因此我们可以把Wc的值设为-Ze,在投影矩阵中表示如下:

现在我们推导Xp映射到Xn和Yp映射到Yn的关系。这两者是线性关系,对于Xp和Xn的对应关系 [l, r] ⇒ [-1, 1],对于Yp和Yn对应关系[b, t] ⇒ [-1, 1]。所以有以下推导:

将得到的结果代入以下等式:

得到以下结果

我们可以看到最后两个等式都除了- Ze,之前的推导已经将Wc设为了- Ze,最终的Xn会等于Xc/Wc,同理Yn也是。所以以上等式圆括号内的值就是Xc和Yc。从Xc和Yc的等式我们可以得到投影矩阵的第一行和第二行的值

现在我们只需要推导第三行的值。对于Zn值的推导有些不一样,在投影的时候Ze总是投影到近平面-n上。Z值在绘制是的作用是用于深度比较,以及裁剪掉过远或者太近的物体。这里我们采用反向推导的方式推导第三行的值。首先我们可以确定Zc的值与Xc和Yc没有关系,所以第三行的一、二两列的值为0。我们设第三和第四列值分别为A、B,且Wc等于Ze,我们可以得到以下等式。

在视图空间中,We总是等于1,所以,可以得到以下等式:

因为OpenGL默认情况下是深度值小于更小的值绘制在前面,所以当Ze等于-n时Zn等于-1;当Ze等于-f时Zn等于1。所以可以得到以下等式:

将A、B的值带入矩阵,从而得到透视投影矩阵:

在继续推导正交投影前,我们先看一下Zn和Ze的关系,我们将A、B的值带入等式 中得到 最终我们可以得到Zn和Ze之间的函数关系,是一个反比例函数,这个函数中Ze很大时Zn变化的斜率很小,而Zn的值压缩在[-1.0, 1.0]之间,这可能会导致当Ze很大时,前后两个物体Zn的其变化值小于浮点数精度,导致深度比较失败。所以因尽量压缩n和f之间的距离。

 

在辅助向量库vmath.h里面的frustum函数就是创建一透视投影矩阵的函数,代码如下:

mat4 frustum(float left, float right, float bottom, float top, float n, float f)
{
    mat4 result(mat4::identity());

    if ((right == left) ||
        (top == bottom) ||
        (n == f) ||
        (n < 0.0) ||
        (f < 0.0))
       return result;

    result[0][0] = (2.0f * n) / (right - left);
    result[1][1] = (2.0f * n) / (top - bottom);

    result[2][0] = (right + left) / (right - left);
    result[2][1] = (top + bottom) / (top - bottom);
    result[2][2] = -(f + n) / (f - n);
    result[2][3]= -1.0f;

    result[3][2] = -(2.0f * f * n) / (f - n);
    result[3][3] =  0.0f;

    return result;
}

正交投影矩阵推导

正交投影矩阵相对简单很多,坐标(Xe, Ye, Ze),全部以线性关系映射到坐标(Xn,Yn, Zn)。如下推导:

 

因为Wc在正交投影中并没有使用所以把最终Wc的值始终设为1。当Wc=1时,(Xc, Yc, Zc)= (Xn, Yn,Zn),矩阵第四行设为(0, 0, 0, 1)。最终的到正交投影矩阵如下:

 

用户剪切

glScissor()剪切测试是在窗口上设置一个剪切矩形,使得绘图和glclear()限制在矩形内。

用户剪切则不一样,用户剪切在片元着色器中,用户剪切可以让我在3D空间内进行剪切。虽然用户剪切只使用了一个float值的gl_ClipDistance[],但我们可以设置平面函数,将平面函数的结果赋给gl_ClipDistance[]从而达到3D空间平面剪切的效果,而且我们可以同时开启多个用户剪切,我们完全可以在3D空间设置一个正方体剪切盒子。代码5.3.1ClipDistance是用户剪切的一个简单例子,运行效果如下:

Transform feedback

简单来说Transform feedback就是可以让我们捕获绘制时使用的数据,捕获的数据是光栅化之前的数据。我们可以绘制的时候捕获数据,然后再将捕获的数据用于绘制,这样循环使用数据。这种模式对于粒子系统非常有用,因为我们可以在顶点着色器更新粒子的数据,并写入一个Transform feedback,然后用Transform feedback数据更新粒子信息并绘制,绘时又可以写入Transform feedback,这样循环。这个过程中无需要CPU中更新粒子信息,粒子的更新和绘制完全在GPU中完成。

 

Transformfeedback的使用

1.      系统会默认创建一个Transform feedback对象,Id=0,所以我们直接使用glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, …)是完全可以的。

 

2.      一个Transform feedback对象可以绑定多个缓存,绑定时缓存索引通过函数glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index,)的index函数控制。要数据多个缓存我们可以在glTransformFeedbackVaryings函数最后一个参数bufferMode设为GL_SEPARATE_ATTRIBS或者使用gl_NextBuffer参数。

3.      Transform feedback对象捕获数据是根据图元来的,不是根据点来的。例如代码glDrawArrays(GL_LINE_LOOP, 0, 4) 会输出八个顶点数据到Transformfeedback对象,而不是四个。因为会绘制四条线,每条线有两个顶点。

 

 

代码5.4TransformFeedback是使用默认Transform feedback对象,Id=0绘制的。

代码5.4TransformFeedback2测试了一个Transform Feedback对象中设置多个缓存输出,和使用多个TransformFeedback对象。

两个工程输出都是一个点向下运动,运动到矩形框内时矩形框和点的颜色都会改变。结果都如下图:

 

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wlk1229/article/details/79435250

智能推荐

YDOOK :Golang 各大操作系统 完全卸载删除 golang 的方法教程-程序员宅基地

文章浏览阅读1w次。1. 直接删除 Golang 安装包:如果是默认安装,Golang 的默认安装目录为:a. Linux、Mac OS X、和 FreeBSD 系统下通常为 /usr/local/go 。b. Windows 下为 c:\Go 。2. 删除环境变量:从 PATH 环境变量中移除 Golang 的 bin 目录:a. Linux 和 FreeBSD 下, 编辑 /etc/profil...

万源之源之drupal 之 drupal_flush_all_caches-程序员宅基地

文章浏览阅读1.7k次。(注:学习笔记,仅学习交流用,如果有错误的地方,在您方便的情况下指正一下,万分感激!)<?phpfunction drupal_flush_all_caches(){ // Change query-strings on css/js files to enforce reload for all users. _drupal_flush_css_js(); /** |->varia_flush_all_cache

Qt opencv 程序异常结束,crashed_qt opencv 环境 程序异常结束。-程序员宅基地

文章浏览阅读9.2k次,点赞3次,收藏18次。1.问题描述在配置VS2015+Qt+OpenCv3.2时,想在Qt中配置OpenCv3.2,配置完毕后,编译运行可以通过,但是运行的时候会出现报错:Starting D:\demo\build-test-Desktop_Qt_5_8_0_MSVC2015_64bit-Release\release\test.exe...程序异常结束。D:\demo\build-test-Desktop_Qt_5..._qt opencv 环境 程序异常结束。

哇哦!《Java核心技术》都更到12版了,牛逼!-程序员宅基地

文章浏览阅读7.6k次。Java 已经诞生 27 年,在全球范围内拥有超过 1200 万的开发者群体,有超过 450 亿物理设备使用着 Java 技术,云端数据中心的虚拟化环境里,还运行着超过 250 亿个 Java 虚拟机的进程实例……这些数据都是 Java 过去取得巨大成就的佐证。进入云原生时代以后,传统的 Java 技术正遭受诸多挑战,“一次编写,到处运行”等植根于 Java 基因里的前提..._java核心技术第十二版和十一版区别

【Android SDK30版本】代码明显是正确的为何升级了sdk版本号就报错或是警告呢(已解决)_iscasting false because ihwdistributedwindowmanage-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏4次。Android每次升级sdk都会有惊喜,功能报错,各种警告,无法使用等问题!_iscasting false because ihwdistributedwindowmanager is invalid.

读取风云4号卫星FullMask_Grid.raw文件_python读取fy-4a,4b数据行列号和经纬度查找表raw文件-程序员宅基地

文章浏览阅读3.2k次,点赞2次,收藏23次。读取风云4号卫星FullMask_Grid.raw文件1、下载FullMask_Grid.raw文件下载网址:国家卫星气象中心(http://satellite.nsmc.org.cn/PortalSite/StaticContent/DocumentDownload.aspx?TypeID=3)2、读取FullMask_Grid.raw文件import numpy as npimport h5pydef fy4disk(rawfile,dim): """ FY-4A数据行列_python读取fy-4a,4b数据行列号和经纬度查找表raw文件

随便推点

安立Anritsu MS2663C频谱分析仪_信号分析频带宽度:120s-120hz,频谱分析、功率谱分析、实时波形分析和展示-程序员宅基地

文章浏览阅读377次,点赞9次,收藏7次。MS2663C具有“Measure”功能用以评估无线设备(频率计数器、C/N、邻道功率、占有频带宽度、突发平均电平和模板判定功能),并且能够进行双屏显示和FM解调波形显示。Anritsu MS2663C 具有评估无线电设备的功能(频率计数器、C/N、相邻信道功率、占用频率带宽、突发平均功率和模板决策功能)。它的"测试" 功能用以评估无线电设备( 频率计数器,C/N比率,相邻通道功率,占用频率带宽 , 脉冲平均功率和模版策判定功能)。它可测量三倍于频率范围的寄生频率,因此可用在全世界的移动通信测量中。_信号分析频带宽度:120s-120hz,频谱分析、功率谱分析、实时波形分析和展示

泛微e-cology OA 系统远程代码执行漏洞_cn_windows_server_2012_x64_dvd_915588-程序员宅基地

文章浏览阅读3.6k次。声明好好学习,天天向上漏洞描述2019年9月19日,泛微e-cology OA系统自带BeanShell组件被爆出存在远程代码执行漏洞。攻击者通过调用BeanShell组件中未授权访问的问题接口可直接在目标服务器上执行任意命令,目前该漏洞安全补丁已发布,请使用泛微e-cology OA系统的用户尽快采取防护措施。泛微e-cology OA系统存在java Beanshell接口,攻击者调用该Beanshell可以被未授权访问接口,构造特定的数据请求绕过OA自带的一些安全限制进行远程命令执行。影响范_cn_windows_server_2012_x64_dvd_915588

最新优惠:无限次视频回放及1v1老师指导--计算机辅助药物设计分子动力学系列专题-程序员宅基地

文章浏览阅读291次。系列课程:CADD药物分子相互作用、分子对接、靶点预测专题 课程名称 课程内容 生物分子互作基础 1.生物分子互作用研究方法 1.1蛋白-小分子、蛋白-蛋白相互作用原理 1.2 分子对接研究生物分子相互作用 1.3 蛋白蛋白对接研究分子相互作用 蛋白数据库 1. PDB 数据库介绍 1.1 PDB蛋白数据库功能 1.2 PDB蛋白数据可获取资源

layui_layui {{}}-程序员宅基地

文章浏览阅读708次。文章的主要简介核心方法各内置模块核心方法 layui.define([mods], callback)通过该方法可定义一个 Layui模块。参数mods是可选的,用于声明该模块所依赖的模块。callback即为模块加载完毕的回调函数,它返回一个exports参数,用于输出该模块的接口。 config layui.use([mods], callback)Layui的内置模块并..._layui {{}}

百度Apollo发布海量自动驾驶数据集,还有两项重磅挑战赛-程序员宅基地

文章浏览阅读4.9k次。作者 | 费棋近日, ApolloScape 宣布开放了大规模自动驾驶数据集。它是 Apollo 自动驾驶项目的一个研究型项目,旨在促进自动驾驶的各方面创新,号称是世界上最大自主驾驶技术开源数据集。根据 ApolloScape 官方介绍,它开放了对像素级标注的场景解析数据集和仿真工具的访问,并将定期添加新的数据集和新功能。▌场景解析数据集场景解析是自动驾驶的核心能力,他们通过高精度车载传感器采集并_apollo车道线数据集

python批量处理excel文本改为数字_Python批量修改Excel中的文件内容-程序员宅基地

文章浏览阅读572次。import osimport xlrdfrom xlutils.copy import copydef base_dir(filename=None):return os.path.join(os.path.dirname(__file__),filename)"""对excel进行操作"""work = xlrd.open_workbook(base_dir("excel.xls"))# 索引..._python将excel文档内批量转换为数字

推荐文章

热门文章

相关标签