C#開發PACS醫學影像三維重建(十四):基於能量模型演算法將曲面牙床展開至二維平面

喬克灬叔叔發表於2023-01-31

在醫學影像領域中,將三維重建中的人體組織展開平鋪至二維,用來研判病灶和制定治療方案的重要手段之一,

它能夠將立體曲面所包含的資訊更為直觀的展示到二維平面上,常用的情景包括:

牙床全景圖、平鋪血管、骨骼二維化展開(肋骨平鋪)。

 

眾所周知,人體牙床正常情況下是有弧度的,無論是從俯視位還是冠狀位觀察都是不能直觀的瞭解牙齒狀況,

或多或少的都會被其他組織或牙齒遮擋,如下圖所示:

 

所以我們要將三維或二維的影像拉伸後平鋪到桌面上,目前主流曲面展開演算法有如下幾種:

①元素法

②旋轉正交矩陣法

③迭代應變能量釋放法 

 

本文將根據網路查詢現有的演算法粗略介紹用能量法展開牙床:

基於彈簧質點系統建立能量模型:

 

 

 

 

 

彈性變形能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); }

執行結果:

 

 

 

將此演算法應用到醫學影像中,開始定位展開錨點:

 

現在就可以在同一屏畫面中得到了各種視角的牙床圖:

 

同理,還可以應用到血管和骨骼的平鋪展開,更好的觀察血管阻塞和破裂、骨折骨裂等情況。

 

 

 

 

相關文章