欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    暑期项目实训-基于webgl(threejs)的牙科数据可视化展示.docx

    • 资源ID:73269519       资源大小:23.25KB        全文页数:15页
    • 资源格式: DOCX        下载积分:14.8金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要14.8金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    暑期项目实训-基于webgl(threejs)的牙科数据可视化展示.docx

    暑期项目实训:基于webgl(three.js)的牙科数据可视化展示第一天:本组的选题是“牙科数据的分割与分类及可视化展示平台。工作主要划分成三块前端平台页面搭建、算法与数据可视化、后端及数据库。我以及另一个同学一起负责算法与数据可视化。根据学长给的demo视频。我们将组内任务分为如下一、牙科数据可视化1CBCT数据、口扫数据可视化三维数据其中细分由分为如下功能三维数据呈现、改变观测视角、光照效果、材质、颜色透明度变换形成渲染器中的GUI。2X光全景图可视化二维数据细分功能如下二维数据呈现、切换深度、根本的图像处理。二、牙科数据处理1牙齿分割任务2牙齿分类任务注模型已经由学长给出我们要导入数据和输出结果。、细分好工作后我们先决定实现数据可视化。考虑到以及Web端适配我们决定使用WebGL开发一开场使用原生的WebGL的开发是痛苦的。WebGL以及OpenGL是类似的而渲染管线又是流水线的工作必须按照流程。于是我们寻找到更高效的开发工具three.js简化开发的流程。我们建立了一个建立的html页面并成功载入三维CBCT数据并渲染出来。这是载入stl文件函数这是我们需要加载的外部文件我们需要创立场景、设置光源、设置相机、创立渲染器、执行渲染第二天我们开场给3D模型添加动画效果一是添加旋转让鼠标以及场景完成交互。在网上搜索资料有封装好的API可以调用类似于JQuery创立控件对象然后监听鼠标、键盘事件将render()函数做为参数。这样可以做出“相加跟随的效果。varcontrolsnewTHREE.OrbitControls(camera,renderer.domElement);/创立控件对象controls.addEventListener(change,render);/监听鼠标、键盘事件效果如下二是参加光照跟随的效果起初环境光与点光源都是固定的所以我们从不同的视角观测模型的亮暗局部都是固定的。所以有的角度直面的是暗的局部观测不清楚。我们定义好了render()函数用来专门渲染物体。在这个render()函数中我们先获取了相机的位置然后新建一个点光源把相机位置传入。这样无论我们在何处观测都有点光源会照在正对相机的外表上。极大地方便了用户观测三维模型。functionrender()varvectorcamera.position.clone();/console.log(vector.x);point.position.set(vector.x,vector.y,vector.z);/点光源位置renderer.render(scene,camera);/执行渲染操作/console.log(vector.x);问题我们在添加监控对象的时候遇到了一个费事即参加监听事件的对象后程序保持着监听状态但是刚点开网页的时候却无法渲染出物体。只有通过挪动鼠标运动相机后才能渲染出。我们判断是因为渲染的逻辑顺序的问题“监听的机制我们其实并不解析。但是我们可以在载入STL文件后立即执行渲染这样可以保证刚翻开时就能有模型显示。三为了进一步增加交互进步用户友好性。我们尝试增加一些按钮。首先增加“Reset按钮即复原相机位置让屏幕显示出从模型的正面观测。buttontypebuttononclickreset()重置方向/button我们按照html语法写了一个button添加了onclick一旦点击此按钮便会执行“reset()函数。functionreset()varvcamera.position.clone();camera.position.set(0,0,200);camera.lookAt(scene.position);scene.position.set(0,0,0);/varcontrolsnewTHREE.OrbitControls(camera,renderer.domElement);/创立控件对象/controls.addEventListener(change,render);/监听鼠标、键盘事件render();Reset()函数是先把相机的位置归回最初的(0,0,200)把保存模型的场景位置归回(0,0,0)再把相机的目的点放到“场景上最后渲染出。就能实现“reset。同样的添加了坐标轴的显示坐标轴显示/消失由于坐标轴显示与否是一个状态值所以添加了简单的逻辑判断。functionaxis()if(a0)/axesHelper.position.set(0,100,0);scene.add(axesHelper);a1;/console.log(a);elseif(a1)scene.remove(axesHelper);a0;/console.log(a);render();如下列图所示为了保证画面的美观看起来更灵敏。我们参加了“自动旋转即当阅读器开启时其实显示的模型就已经开场缓慢运动。这样看起来使得场景更具“高级感。代码如下;buttontypebuttononclickspin()自动旋转/buttonbuttontypebuttononclickspeedup()旋转加速/buttonbuttontypebuttononclickspeedown()旋转减速/buttonfunctionspeedup()speedspeed0.002;functionspeedown()if(speed-0.0020.001)speedspeed-0.002;elsespeed0.001;functionspinrender()mesh1.rotateY(speed);/每次绕y轴旋转0.01弧度mesh2.rotateY(speed);/camera.rotateY(speed);angleanglespeed;render();/renderer.render(scene,camera);/执行渲染操作functionspin()if(d0)myITVsetInterval(spinrender(),20);d1;elseif(d1)clearInterval(myITV);d0;mesh1.rotateY(-angle);/每次绕y轴旋转0.01弧度mesh2.rotateY(-angle);angle0;render();第四次实验经过我们考虑给模型增加不同的材质效果首先对它的颜色改变。并且我们需要一个成型的GUI在控件面板完成这些操作。我查阅资料发现three.js已经有封装好的GUI给我们使用我们可以轻松地调用这些方法实现颜色改变、模型大小等诸多功能。但问题是调用的变量终究是哪一个。Three.js的对象实在过多了由于之前的工作已经在主js文件里填充了过多。我详细且耐心地查阅了three.js的流程。大致如下将对象关系分析明确就可以判断出GUI的API中color是material的属性。gui.addColor(params,color).onChange(e/点击颜色面板e为返回的10进制颜色pointsMaterial.color.set(e);所以我们修改之前的代码把load函数里的材质提出到主js里。我们完成了对model的颜色修改(调色盘)。但有一个困境难住了我修改颜色后无法实现立即渲染。其实归根结底是代码逻辑的不通顺和three.js实现经过的不明晰。但是在修改颜色之后添加了render()函数立即渲染的问题却奇迹般的解决了。gui.addColor(params,color).onChange(function()material.color.set(params.color);render();完成的效果考虑如此得出的问题mesh早在加载模型时便已经绑定了material以及geometry。Gui.AddColor代码逻辑上在mesh载入scene之后。改变material却引起scene的变化。那么有如下两个可能1.onChange()的侦听重新运行整个程序渲染出新的frame2.Mesh即使在赋值后也是一直依赖于Material以及geometry的。第五次完成的任务1.实现基于GUI的mesh的透明度修改。2.上下颚的出现/隐藏3.坐标轴的隐现4.自动旋转5.旋转速度调控实现经过在添加完修改颜色模块后增加其它功能模块就变得容易起来。只需要在设定参数的时候增加“opacity并在gui中增加对material的opacity的修改。需要设置成滑块来改变。并设置步长为0.01。up.add(params,opacity,0.3,1.0).onChange(ematerial1.opacitye;render();).step(0.01);此外增加了隐藏/出现的按钮。up.add(params,visible).onChange(ematerial1.visiblee;render();坐标轴的出现/隐藏gui2.add(params2,axis).onChange(eif(e)scene.add(axesHelper);elsescene.remove(axesHelper);render();这里面需要注意的我们修改的对象是scene。旋转与速度设置。gui2.add(params2,spin).onChange(eif(e)mysetInterval(function()mesh1.rotateY(speed);/每次绕y轴旋转0.01弧度/mesh2.rotateY(speed);/camera.rotateY(speed);angleanglespeed;render();,20);elseclearInterval(my);gui2.add(params2,speed,slow:0.001,medium:0.005,fast:0.01).onChange(function(value)speedvalue;按时间间隔循环执行函数针对的对象是mesh。我们也参加下拉菜单改变速率。待解决GUI控件在窗口中的布局和隐藏、命名。第六次完成的任务CBCT图像的显示实验经过我查询了多种方法在代码中实现dicom类型数据的显示。首先由于我们根本javascript的three.js开发便搜索three.js的工具包。发现固然js有这种包但是加载起来很是复杂他将会涉及到XAMPP等一些解析不太清的工具。而且占内存达160M所以我尝试使用python来实现。接下来有两条路在我的面前一是直接尝试使用python开发web但是由于先前都使用js开发贸然切换成python很不利于工程衔接而且有一大局部知识待重新学习。所以我选择另一条路使用python的pydicom模块获取到图片的像素信息保存在list中然后把数据传给js文件再显示图像。幸运的如今使用pydicom成功显示CBCT图像。pix#用来获取文档中所有文件名Pathos.listdir(./lvsilinCBCT)#用来获取所有文件的像素值pix的类型是2维的foriinPath:filePath./lvsilinCBCT/iprint(filePath)dspydicom.read_file(filePath)pix.append(ds.pixel_array)另外我也成功导入了ply格式的文件它与stl文件几乎一样而且都是完好的牙。此处贴出导入的代码functionplyloader(path)varplyloadernewTHREE.PLYLoader();plyloader.load(path,function(geometry)/更新顶点的法向量geometryputeVertexNormals();mesh1newTHREE.Mesh(geometry,material1);mesh1.rotation.x-Math.PI*0.5;scene.add(mesh1);/render();第七次完成的任务CBCT图像(dicom格式)的序列解析并显示实现逐序列显示的效果。先前基于自己手写的代码已经完成了单帧dicom的显示但是有如下问题1.代码基于python实现的与js的通信受限。2.可以通过逐帧保存成png/jpg来完成序列显示的任务但是吃内存耗时久只能先保存转换到图片再直接提取。3.从dicom到jpg难以三维重构我为解析决如下的问题查找了很多文档。其核心问题就是在于python与js的通信问题其实再深一层是无法找到适宜解析dicom序列的api的问题。有不少开源的代码解决单帧、多帧的事实上使用js解决问题的大多是基于conerstone框架迭代成新的框架。我寻找到了适宜的框架sliceDrop研究里面的方法成功读出了多帧dicom并进展三维重构。三维重构讲起来内容不多但是这是我利用网络工具解决问题的重要一课利用工具简化开发的流程。有针对性地从工程提炼问题并检索。待解决的问题:2d图像的效果并不尽如人意3d的立方体noise以及透明度参数并不适宜gamma、比照度的功能还没有实现。第八次完成的任务三维口扫模型(含label)的点云形态可视化从机器学习跑出分类数据后out出来的是一个拥有N个点坐标的txt文件和对应的label每个点对应一个label。实际上txt里每行有6个数据所以一开场我花了不少时间解析txt点集并渲染最终渲染的效果却不如意比方渲染出一半牙齿另有一团点集中在worldspace的原点。于是耗时良久后最终答案是前三个点是坐标后三个点是法线。于是我们只需要解析前三个点就可以。此外我把不同顶点数据按照label已经存进了数组对象里。代码如下varfileresult0.txt;varrawFilenewXMLHttpRequest();rawFile.open(GET,file,false);rawFile.send(null);vartxtrawFile.responseText;varxDtxt.split(/n|/);xD.pop();varLabresult.txt;varrawFile2newXMLHttpRequest();rawFile2.open(GET,Lab,false);rawFile2.send(null);varlabelrawFile2.responseText;labellabel.split(n);label.pop();console.log(xD.length);/类别数varnum_label16;/建立一个长度为num_label的数组用来保存顶点数据vardocnewArray(num_label);/index是它的labelfor(vari0;inum_label;i)docinewArray();/数据导入for(vari0;ilabel.length;i)docNumber(labeli).push(Number(xD6*i);docNumber(labeli).push(Number(xD6*i1);docNumber(labeli).push(Number(xD6*i2);当然会碰到一些数据处理的问题使用的一些技巧就不在这里展开。颜色的处理一个label需要对应一个颜色。结合图形学与three.js的知识我在绑定material的时候改变顶点的颜色。给label做一个颜色映射是一个挺有趣的数学问题当然我这里简单地解决了。for(varj0;j3;j)tempjMath.round(Math.random()*8020)i;tempj128(255-128)/(116-20)*(tempj-20);tempjMath.floor(tempj);/console.log(tempj);还有一个值得一提的问题material里的颜色使用的是字符串/三个16进制数连起来的数字。我用之前得到的从label映射的数字再转成16进制练成字符串加上“#成功渲染出不同颜色的点。color:#(temp0).toString(16)(temp1).toString(16)(temp2).toString(16)效果如下待解决的问题从点云(pointscloud/pointsset)到面片(mesh/surface)的三维重建。第九次完成的任务从点云(points)数据到面片(mesh)数据进展这样的三维重构我们真实在做的工作其实是实现一个阅读器或是可执行程序读取以及解析model的经过。我们需要以下数据点在OpenGL称之为顶点(vertex)索引OpenGL里的IBO存放的数据按照pipline绘制的流程是需要这样的顶点顺序用以确定怎样绘制三角形的法线normal用来计算模型的材质承受的光照参数值。使用的文件是.off文件利用js内置的方法与函数便可以轻松把数据读取到自定义变量内。自己写的读取顶点函数以及读取label函数functionVloader(path)varfilepath;varrawFilenewXMLHttpRequest();rawFile.open(GET,file,false);rawFile.send(null);vartxtrawFile.responseText;varxDtxt.split(/n|/);/varxDtxt.split(/n|/);xD.pop();varvertexxD;/数据导入for(vari0;ivertex.length;i)vertexiNumber(vertexi);returnvertex;functionIloader(path)/标签读入varLabpath;/varLabLowerJaw_vClassLabels.txtvarrawFile2newXMLHttpRequest();rawFile2.open(GET,Lab,false);rawFile2.send(null);vartemp_1rawFile2.responseText;varlabeltemp_1.split(n);for(vari0;ilabel.length;i)labeliNumber(labeli);/label.splice(0,1);label.pop();returnlabel;在geometry读取顶点后需要读取索引信息一个装有顶点顺序的txt。geometry.indexnewTHREE.BufferAttribute(EBO,1);剩下的只需要更改材质为mesh材质geometry以及材质绑定的也是新的mesh即可。materialnewTHREE.MeshBasicMaterial()varmeshnewTHREE.Mesh(geometry,material);另外一个需要提到的我们同样需要给geometry顶点着色。我需要一个文件装载所有顶点颜色数据所以用了一些方法成功根据不同的label传入不同的颜色。颜色格式为(r,g,b)三个点为一组。之后只用在材质里开启vertexColors:THREE.VertexColors就能渲染出mesh了但由于label的问题没有与顶点对应所以最终渲染出的效果并不是成功分类的结果。关于模型的材质如今看起来极其乏味只有单纯的颜色填充并没有漫反射、镜面反射赋予的变化。在尝试了屡次更改材质为MeshLambertMaterial以及MeshPhongMaterial他们却都无法正常渲染出来。当然除了上面使用的off文件我们还拥有txt的数据文件。txt内包含了顶点数据与法线数据但却没有索引数据所以我不得不投入三维重构的工作。即不依靠索引尽可能渲染出好的面片。有一篇非常优秀的论文讨论了这个问题在搜索算法的时候大多数都是依靠C实现并没有适宜的js函数调用。所以实现这一算法还需要接下来进一步研究。图片下次补上来.

    注意事项

    本文(暑期项目实训-基于webgl(threejs)的牙科数据可视化展示.docx)为本站会员(安***)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开