在醫學影像領域中,將三維重建中的人體組織展開平鋪至二維,用來研判病灶和制定治療方案的重要手段之一,
它能夠將立體曲面所包含的資訊更為直觀的展示到二維平面上,常用的情景包括:
牙床全景圖、平鋪血管、骨骼二維化展開(肋骨平鋪)。
眾所周知,人體牙床正常情況下是有弧度的,無論是從俯視位還是冠狀位觀察都是不能直觀的瞭解牙齒狀況,
或多或少的都會被其他組織或牙齒遮擋,如下圖所示:
所以我們要將三維或二維的影像拉伸後平鋪到桌面上,目前主流曲面展開演算法有如下幾種:
①元素法
②旋轉正交矩陣法
③迭代應變能量釋放法
本文將根據網路查詢現有的演算法粗略介紹用能量法展開牙床:
基於彈簧質點系統建立能量模型:
彈性變形能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);
}
執行結果:
將此演算法應用到醫學影像中,開始定位展開錨點:
現在就可以在同一屏畫面中得到了各種視角的牙床圖:
同理,還可以應用到血管和骨骼的平鋪展開,更好的觀察血管阻塞和破裂、骨折骨裂等情況。