DFSファイル

DFS file format 1

DFSファイルから三角メッシュと頂点を読み込む関数Mファイル... 1

GIfTIファイル化... 1

 

DFS file format

DFSファイル形式は以下のようになっています。

ヘッダー

 

メッシュ数、頂点数、ポインタ

メタデータ

埋め込みXML

不使用

被検者メタデータ

埋め込みXML

不使用

三角データ

int32,int32,int32

メッシュ数×3×4バイト

頂点座標

single,single,single

0〜頂点数-1

頂点の法線

single,single,single

オプション ないときは0

頂点のUV座標

single,single

オプション テキストマップ座標

頂点のRGB

single,single,single

オプション 01

頂点のラベル

int16

オプション

頂点属性

single

オプション 曲率など

 

とりあえず、MATLABで読んでみます。

'D:\MATLAB\akira\BrainSuite\akira.brain.dfs'

fid=fopen(loadname,'rb');

B=fread(fid,'*uint8');

fclose(fid);

ヘッダーの大きさとかどうなってるかよくわかりません。

B(1:32)'

char(B(1:32)')

結果です。

ans =

 

  1×32 uint8 行ベクトル

 

  1 列から 16

 

    68    70    83    95    76    69    32   118    50    46    48     0   184     0     0     0

 

  17 列から 32

 

     0     0     0     0     0     0     0     0   244   181     2     0   252    90     1     0

 

 

ans =

 

    'DFS_LE v2.0 ¸           ôµ[1] üZ '

 

>> 

いろいろなdfsファイルみたんですが、どうも023番地は同じ数字のようです。読み飛ばすことにします。

BrainSuiteによると

akira.brain.dfs

D:/MATLAB/akira/BrainSuite

triangles: 177652

vertices: 88828

normals: 88828

uv map: 0

vertex color: 0

vertex labels: 0

です。

2455番地を見ていきます。

address=(1:32)+24;

B(address)'

結果です。

ans =

 

  1×32 uint8 行ベクトル

 

  1 列から 16

 

   244   181     2     0   252    90     1     0     0     0     0     0     0     0     0     0

 

  17 列から 32

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

>> 

三角メッシュ数、頂点数だけ表示されていて、ポインタ部分は全部ゼロになっています。

とりあえず、以下を実行します。

typecast(B(25:28),'int32')

typecast(B(29:32),'int32')

結果です。

ans =

 

  int32

 

   177652

 

 

ans =

 

  int32

 

   88828

 

>> 

メッシュ数と頂点数はBrainSuiteの情報と一致しています。

24番地がメッシュ数NT28番地が頂点数ということでいいようです。

32番地から223番地を見ていきます。

address=(1:192)+32;

B(address)'

結果です。

ans =

 

  1×192 uint8 行ベクトル

 

  1 列から 16

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  17 列から 32

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  33 列から 48

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  49 列から 64

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  65 列から 80

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  81 列から 96

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  97 列から 112

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  113 列から 128

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  129 列から 144

 

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

 

  145 列から 160

 

     0     0     0     0     0     0     0     0     0     0     0     0   236     1     0     0

 

  161 列から 176

 

   229     1     0     0     0     0     0     0   230     1     0     0     1     0     0     0

 

  177 列から 192

 

   229     1     0     0   230     1     0     0     0     0     0     0     1     0     0     0

 

>> 

189番地から数字が出てきました。

ヘッダー部分の「,」にみえた184というのはヘッダー部分の大きさ、三角メッシュ情報のポインタだと勝手に解釈します。

以後0番目の頂点からなる三角メッシュのリストとしてデータを見ていきます。

nt=typecast(B(25:28),'int32');

nv=typecast(B(29:32),'int32');

address=184+(1:(3*nt*4));

tri=typecast(B(address),'int32');

tri=reshape(tri,[3,nt]);

max(tri(:))

結果です。

ans =

 

  int32

 

   88827

 

>> 

頂点の番号は088827までですのでこれでOKです。

次は頂点座標です。MATLABでは頂点0番は認識しないので1ずつ値を増やし、頂点番号を1からとします。

address=184+3*nt*4+(1:(3*nv*4));

vertex=typecast(B(address),'single');

vertex=reshape(vertex,[3,nv]);

figure;

faces=tri+1;

hbrain=patch('faces',faces','vertices',vertex');

set(hbrain,'facecolor',[1,1,0],'edgecolor','none');

axis tight;

daspect([1,1,1]);

view([-120,20]);

light('position',[-1,0,0]);

rotate3d on;

結果です。

BrainSuiteの情報では法線ベクトルもあるそうです。最後の行はホントに法線なのか1になるかどうかの確認です。

address=184+3*nt*4+3*nv*4+(1:(3*nv*4));

vnorm=typecast(B(address),'single');

vnorm=reshape(vnorm,[3,nv]);

max(sum(vnorm.^2,1))

ん?エラーが出ました。

インデックスが配列要素数 (3197944) を超えています。

 

エラー: Untitled (line 37)

vnorm=typecast(B(address),'single');

 

>> 

今まで読み込んだファイル上のアドレスとファイルのデータサイズの長さとを比較してみます

184+3*nt*4+3*nv*4,length(B)

結果です。

ans =

 

  int32

 

   3197944

 

 

ans =

 

     3197944

 

>> 

頂点座標を読み込んだところで丁度ファイルの長さが終わっていました。

 

DFSファイルから三角メッシュと頂点を読み込む関数Mファイル

以下のような関数Mファイルを作成しました。

function R=hns_loaddfs(loadname)

R=[];

try

    fid=fopen(loadname,'rb');

    B=fread(fid,'*uint8');

    fclose(fid);

catch

    return

end

try

    ptrimesh=typecast(B(13:16),'int32');

    ntri=typecast(B(25:28),'int32');

    nvertex=typecast(B(29:32),'int32');

    pvertex=ptrimesh+3*ntri*4;

    pnormal=typecast(B(33:36),'int32');

    puv=typecast(B(37:40),'int32');

    prgb=typecast(B(41:44),'int32');

    plabel=typecast(B(45:48),'int32');

    pattr=typecast(B(49:52),'int32');

catch

    return

end

try

    address=ptrimesh+(1:(3*ntri*4));

    x=typecast(B(address),'int32');

    x=reshape(x,[3,ntri]);

    R.faces=x+1;

    address=pvertex+(1:(3*nvertex*4));

    x=typecast(B(address),'single');

    R.vertices=reshape(x,[3,nvertex]);

catch

    return

end

if pnormal>0

    try

        address=pnormal+(1:(3*nvertex*4));

        x=typecast(B(address),'single');

        R.normals=reshape(x,[3,nvertex]);

    catch

        return

    end

end

if puv>0

    try

        address=puv+(1:(2*nvertex*4));

        x=typecast(B(address),'single');

        R.uv=reshape(x,[2,nvertex]);

    catch

        return

    end

end

if prgb>0

    try

        address=prgb+(1:(3*nvertex*4));

        x=typecast(B(address),'single');

        R.rgb=reshape(x,[3,nvertex]);

    catch

        return

    end

end  

if plabel>0

    try

        address=plabel+(1:(nvertex*2));

        x=typecast(B(address),'int16');

        R.label=reshape(x,[3,nvertex]);

    catch

        return

    end

end      

if pattr>0

    try

        address=pattr+(1:(nvertex*4));

        R.attr=typecast(B(address),'single');

    catch

        return

    end

end       

以下を実行しました。left/right.pial.cortex.dfsは色情報RGBがありましたので、その情報を使っています。

DFSfiles={

    'D:\MATLAB\akira\BrainSuite\akira.left.pial.cortex.dfs'

    'D:\MATLAB\akira\BrainSuite\akira.right.pial.cortex.dfs'

    'D:\MATLAB\akira\BrainSuite\akira.scalp.dfs'

};

for n=1:length(DFSfiles)

    V=hns_loaddfs(DFSfiles{n});

    if n==1

        figure('color',[1,1,1]);

    end

    h=patch('faces',V.faces','vertices',V.vertices',...

        'FaceColor',[1,0.5,0],'FaceAlpha',0.5,'edgecolor','none');

    if isfield(V,'rgb')

        set(h,'FaceVertexCData',V.rgb','FaceColor','interp','FaceAlpha',1);

    end

    if n==1

        hold on;

        daspect([1,1,1]);

    end           

end

axis tight;

view([-120,20]);

rotate3d on;

結果です。

 

GIfTIファイル化

GIfTI toolbox for MATLABを使います。左半球を表示させ、BrainVISA風のLhemi.giiという名前で保存します。

close all;

addpath('D:\MATLAB\gifti-1.6');

loadname='D:\MATLAB\akira\BrainSuite\akira.left.pial.cortex.dfs';

v=hns_loaddfs(loadname);

v.faces=v.faces';

v.vertices=v.vertices';

g=gifti(v);

figure('color',[1,1,1]);

plot(g);

save(g,'D:\MATLAB\akira\BrainSuite\Lhemi.gii','Base64Binary');

 

結果です。

警告: cameramenu は将来のリリースで削除される予定です。代わりに cameratoolbar を使用してください。

>> 

このGIfTIファイルはFreeSurfermris_convertコマンドを使うことでFreeSurfersurfファイルに変換できます。

 

メッシュを膨らませる

パット見、BrainSuiteにはinflated brainの機能は見当たりません。

BrainVISAMorphologistsurfaceInflated Cortical Surface機能を使ってみます。

以下を実行しました。BrainVISAに合わせ、Lwhite.giiという名前で保存します。

close all;

addpath('D:\MATLAB\gifti-1.6');

loadname='D:\MATLAB\akira\BrainSuite\akira.left.inner.cortex.dfs';

v=hns_loaddfs(loadname);

v.faces=v.faces';

v.vertices=v.vertices';

g=gifti(v);

figure('color',[1,1,1]);

plot(g);

save(g,'D:\MATLAB\akira\BrainSuite\Lwhite.gii','Base64Binary');

Ubuntu 12.04/home/ns/brainsuiteにコピーします。

BrainVISA 4.6.1を起動し、MorphologistsurfacdInflate Cortical Surfaceを選択します。

inputファイルを選択します。

/home/ns/brainsuite/Lwhite.giiを選択します。

output_meshのファイル名をxx_inflated.giiとし、Runを押します。

curvature textureのところが空欄になっていると実行しないので手入力します。

結果です。

M

filename2='C:\akira\BrainSuite\akira_Lwhite_inflated.gii';

filename3='C:\akira\BrainSuite\akira_Lwhite_curv.gii';

f2=gifti(filename2);

f3=gifti(filename3);

figure;

h=trimesh(f2.faces,f2.vertices(:,1),f2.vertices(:,2),f2.vertices(:,3),f3.cdata);

set(h,'edgecolor','none','facecolor','interp');

map=-gray(2)*0.5+0.75;

colormap(map);

set(gca,'clim',[-1,1]);

daspect([1,1,1]);

view([-120,20]);

rotate3d on;