在医学影像领域中,将三维重建中的人体组织展开平铺至二维,用来研判病灶和制定治疗方案的重要手段之一,
它能够将立体曲面所包含的信息更为直观的展示到二维平面上,常用的情景包括:
牙床全景图、平铺血管、骨骼二维化展开(肋骨平铺)。
众所周知,人体牙床正常情况下是有弧度的,无论是从俯视位还是冠状位观察都是不能直观的了解牙齿状况,
或多或少的都会被其他组织或牙齿遮挡,如下图所示:
所以我们要将三维或二维的影像拉伸后平铺到桌面上,目前主流曲面展开算法有如下几种:
①元素法
②旋转正交矩阵法
③迭代应变能量释放法
本文将根据网络查询现有的算法粗略介绍用能量法展开牙床:
基于弹簧质点系统建立能量模型:
弹性变形能E和弹性力f的计算式为:
判断展开标准:
曲面展开算法示例:
以VTK中圆柱体为例,将一根圆柱展开为一个矩形平面的部分代码:
void Cylinder_Expansion(vtkPolyData* srcData, vtkPolyData* destData, GEO_CYLINDER src_Cylinder) { vtkSmartPointer<vtkPoints>srcPoints = srcData->GetPoints(); vtkSmartPointer<vtkPoints>destPoints = vtkSmartPointer<vtkPoints>::New(); int num = srcPoints->GetNumberOfPoints(); double p[3],r[3],cross[3]; double v0[3] = { 0 }, v1[3] = {0}; v0[src_Cylinder.RdTran] = src_Cylinder.CenterTran; v0[src_Cylinder.RdLong] = src_Cylinder.CenterLong; v1[src_Cylinder.RdTran] = src_Cylinder.R; v1[src_Cylinder.RdLong] = 0; double arc_len; for (int i = 0; i < num; ++i) { srcPoints->GetPoint(i, p); v0[src_Cylinder.Axial]= p[src_Cylinder.Axial]; vtkMath::Subtract(p, v0, p); arc_len = vtkMath::AngleBetweenVectors(v1,p); vtkMath::Cross(v1, p, cross); if (cross[src_Cylinder.Axial]<0)
arc_len = vtkMath::Pi()*2-arc_len; r[src_Cylinder.RdTran]= src_Cylinder.CenterTran+ arc_len*src_Cylinder.R; r[src_Cylinder.Axial] = v0[src_Cylinder.Axial]; r[src_Cylinder.RdLong] =sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) - src_Cylinder.R; destPoints->InsertPoint(i,r); } destData->SetPoints(destPoints); }
运行结果:
将此算法应用到医学影像中,开始定位展开锚点:
现在就可以在同一屏画面中得到了各种视角的牙床图:
同理,还可以应用到血管和骨骼的平铺展开,更好的观察血管阻塞和破裂、骨折骨裂等情况。
标签:src,Cylinder,牙床,PACS,v0,Axial,医学影像,展开,三维重建 From: https://www.cnblogs.com/Uncle-Joker/p/17079269.html