itk-js实现处理DICOM数据,并在VTKJS中渲染

itk-js实现处理DICOM数据,并在VTKJS中渲染

2023年7月7日发(作者:)

itk-js实现处理DICOM数据,并在VTKJS中渲染jourdain commented on 30 Marr 2018 2018To read a

vti file you need to use that reader like hereThe http reader use a different format which can be generated with that if you want to load DICOM, you should consider itk-js for loading your file natively and respect the orientation of thevolume. @thewtex can tell you more about you can see DICOM loading using itk-js and vtk-js here with ParaView x commented on 3 Apr 2018Yes, as @jourdain mentioned, we can load the DICOM images directly via load a multi-frame DICOM file (the entire volume is in one file), use itk/readImageFile. To load a DICOM file series, useitk/readImageDICOMFileSeries. Both of these are enabled in this reference application.简单来说依然拷贝它的源码进⾏简单的测试同样没有 ,⽤npm install 进⾏安装但是这个项⽬根本没有运⾏测试服务器的地⽅,所以装了也没啥⽤....只能进⼊example 来看看⽰例代码了itk的⽰例代码基本没有什么内容,但是他的⽂档⾄少把API给整理出来了。我们可以看到有2个重要的API对处理DICOM数据⼗分重要:1. 关键API : readImageFile(webWorker, file) -> { webWorker, image }Read an image from a File.这个API可以处理单个的DICOM数据2.关键API : readImageDICOMFileSeries(fileList,singleSortedSeries=false) -> { image, webWorkerPool }Read an image from a series of DICOM File‘s stored in an Array or the files are known to be from a single, sorted series, the last argument can be set to true for used webWorkerPool is returned to enable resource cleanup, if required.这个API可以处理⼀个series中的DICOM数据后来⼜参考了很多 thewtex 给出的⽰例代码,花了很长的时间...⼲脆就直接给出实现读取多个DICOM数据的流程:(0) 巨坑!!⾸先需要配置webpack的环境如果是使⽤了umi,请在config下加⼊新的copy配置参数:提⽰:umi⾥⾯集成了 CopyPlugin ,如果利⽤ chainWebpack 来配置 CopyPlugin 的话,可能会覆盖掉它⾃⼰⽣成的配置,导致Public⽬录失效,坑 copy: [ // 设置要复制到输出⽬录的⽂件或⽂件夹 { from: ('node_modules', 'itk', 'WebWorkers'), to: ('itk', 'WebWorkers'), }, { from: ('node_modules', 'itk', 'ImageIOs'), to: ('itk', 'ImageIOs'), }, { from: ('node_modules', 'itk', 'MeshIOs'), to: ('itk', 'MeshIOs'), }, { from: ('node_modules', 'itk', 'PolyDataIOs'), to: ('itk', 'PolyDataIOs'), }, ],如果是正常的webpack,请参考官⽅⽰例下的webpack plugins: [ new CopyPlugin([ { from: (__dirname, 'node_modules', 'itk', 'WebWorkers'), to: (__dirname, 'dist', 'itk', 'WebWorkers') }, { from: (__dirname, 'node_modules', 'itk', 'ImageIOs'), to: (__dirname, 'dist', 'itk', 'ImageIOs') }, { from: (__dirname, 'node_modules', 'itk', 'PolyDataIOs'), to: (__dirname, 'dist', 'itk', 'PolyDataIOs') }, { from: (__dirname, 'node_modules', 'itk', 'MeshIOs'), to: (__dirname, 'dist', 'itk', 'MeshIOs') } ]) ],(1) ⾸先需要发⽹络请求await axios .get( '{DICOM_IP}/series/bfd34afd-f97a9f7c-c0551428-93a0c48a-0285c8ce?_=17', ) .then((response) => { const { Instances } = ; for (const index in Instances) { files_(`{DICOM_IP}/instances/${Instances[index]}/file`); } }); const fetchFiles = files_((file_path, index) => { const path = file_path; return (path, { responseType: 'blob' }).then((response) => { const jsFile = new File([], `${index}.dcm`); // `${index}.dcm` ` file_('/').slice(-1)[0]` return jsFile; }); });这⾥处理⼀组DICOM,⾸先获取所以DICOM⽂件的地址,然后⽣产了⼀组读取DCOM⽂件的异步⽅法。这⾥从URL中获取,你也可以从本地来获取⽂件列表。反正,需要获取到⼀个 ⽂件的列表(2) 转换图⽚数据(fetchFiles).then((files) => { readImageDICOMFileSeries(files).then(({ webWorker, image }) => { // ate(); // printImage(image); const imageData = tItkToVtkImage(image); }); }); };这⼀步⽐较简单,直接调⽤⽅法对⽣成的图⽚列表执⾏ITK的⽅法注意:ITK的⽅法进⾏了更新,只需要传⼊⼀个参数,如果参考⽼的代码会发⽣错误(坑!!然后将itk image 格式再转换成 vtk 的image data,这⾥是VTK ⾥⾯⼀个⽅法做的事情,叫 ITKHelper(3) 坑中坑!利⽤VTK渲染 ima(3) 坑中坑!利⽤VTK渲染 imageData const view3d = mentById('view3d'); const fullScreenRenderer = tance({ rootContainer: view3d, containerStyle: { height: '100%', overflow: 'hidden', }, background: [0, 0, 0], }); const renderer = derer(); const renderWindow = derWindow(); eractor().setDesiredUpdateRate(15); const source = imageData; // Pipeline handling per(mapper); utData(source); // pleDistance(0.7); const sampleDistance = 0.7 * ( source .getSpacing() .map((v) => v * v) .reduce((a, b) => a + b, 0), ); pleDistance(sampleDistance); or(actor); const lookupTable = tance(); const piecewiseFunction = tance(); // create color and opacity transfer functions // 加了UI之后 这⾥的设置其实可以删除 Point(200.0, 0.4, 0.2, 0.0); Point(2000.0, 1.0, 1.0, 1.0); nt(200.0, 0.0); nt(1200.0, 0.5); nt(3000.0, 0.8); perty().setRGBTransferFunction(0, lookupTable); perty().setScalarOpacity(0, piecewiseFunction); perty().setScalarOpacityUnitDistance(0, 4.5); perty().setInterpolationTypeToLinear(); perty().setUseGradientOpacity(0, 1); perty().setGradientOpacityMinimumValue(0, 15); perty().setGradientOpacityMinimumOpacity(0, 0.0); perty().setGradientOpacityMaximumValue(0, 100); perty().setGradientOpacityMaximumOpacity(0, 1.0); perty().setShade(1); perty().setAmbient(0.2); perty().setDiffuse(0.7); perty().setSpecular(0.3); perty().setSpecularPower(8.0); // Control UI const controllerWidget = tance({ size: [400, 150], rescaleColorMap: true, }); tainer(view3d); ontent(renderWindow, actor, true); izeCallback(({ width, height }) => { // 2px padding + 2x1px boder + 5px edge = 14 if (width > 414) { e(400, 150); } else { e(width - 14, 150); } (); (); }); // First render amera(); ();⽹上⼤多数代码就给出了如何实现从DICOM数据 =》vtk image data 的转换,后续如何进⾏渲染很难找到例⼦。官⽅的例⼦都惦记着他那个.vti格式⽂件的渲染,所以他直接就写⼀个 Reader 来进⾏⽂件读取了,没有直接拿image data进⾏渲染的。我⼀开始尝试⽤ React-vtk-js 这个库进⾏渲染,但是估计是不⾏,它也需要⼀个Reader进⾏配合,可能才能进⾏渲染。⽆赖之下,还是只能参考 itk-vtk-viewer 这个实现,但是这个代码迭代的版本的太多,最新的代码结构太复杂,我只好从头来看,于是我尝试了很多旧版本的代码,但是始终都是⿊屏的,也没报错,就是渲染不出3D的体素数据,我真的哭死。我发现这个 itk-vtk-viewer 这个库⼀开始⽤了⼀些vtk⽐较原始的实现⽅法,似乎从 4.0开始,后⾯就⽤了 vtk ⾥⾯代理的⽅法进⾏实现,我也把代码抄了⼀下,但是始终就是⿊屏,真的哭死...第⼆天,我发现vtk的⽰例⾥⾯有⼀个 volume的app⽰例代码,我也抄了⼀下,但是依旧是渲染不出来,要吐了。关键它也不报错,我不知道问题是出在什么地⽅,我不知道是我数据出问题了,还是渲染出问题了。最后我⼜偷了⼀个volume 的代码,我发现终于渲染出来了!问题就是好像是出在 lookupTable 和 piecewiseFunction 的设置上⾯,如果没有设置它们可能就是渲染不出来影像。于是⼀个很坑的地⽅出现了,我之前调试代码的时候,⼀直没有把UI这个东西加上,我以为不会对结果造成影像,于是lookupTable 和 piecewiseFunction 的参数,我也学⽰例代码⾥⾯写,把它们留⽩。但是实际上如果加了 UI,就会⾃动设置它们的参数,坑最后渲染结果:结果最后由于loader可能还是有问题,所以UI界⾯不能正常展⽰,但是基础的功能有了。这次被这个问题坑了很久,感觉还是对VTKJS的渲染不太熟悉后续还是得熟悉⼀下 VTKJS 的代码,把现在的代码结构改成 VTKJS代理的那个实现⽅式

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688684966a162444.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信