fangq / brain2mesh

Brain2Mesh - a one-liner for high-quality brain mesh generation
http://mcx.space/brain2mesh
Other
34 stars 14 forks source link

Reducing meshsize #12

Closed RebinaFrancis closed 4 years ago

RebinaFrancis commented 4 years ago

Dear Brain2mesh

As I understand it, openmeeg recommends the meshsize to be approximately 600 to 800 points per surface(https://openmeeg.github.io/tutorial.html). Without adjusting any parameters in cfg, I get a size between approx. 100000 and 900000. I have tried setting 'cfg.maxnode' to 1000. However, the number of nodes is still very high. Could you perhaps help me? I have included screenshots of the size of the elements per surface before and after this change .

Best wishes, Rebina

Before this change before

After this change After

fangq commented 4 years ago

@RebinaFrancis, I see several issues the way you counted the "node number" using brain2mesh outputs.

First, the tables you listed are not surface mesh, they are tetrahedral meshes. To get the surface meshes from tetrahedral meshes, you will have to call volface in iso2mesh, but you can't call this for each segment - because the brain layers are enclosing one another, calling volface per segment will produce both outer and inner surfaces, which can double count surfaces of the adjacent layers. You will have to run

scalpface=volface(elem(elem(:,5)>=1,1:4));
csfface=volface(elem(elem(:,5)>=2,1:4));

etc. Secondly, the number of elements/triangles is different from the number of nodes on a surface. To count the number of nodes, you will have to use

length(unique(scalpface))
length(unique(csfface))

Thirdly, users have full control to mesh density by adjusting the surface/tetrahedral mesh density parameters as described in Section 3.1 of our brain2mesh paper.

Specifically, to reduce the surface mesh density, you set the cfg.radbound (R_max), cfg.maxvol (V_max), and cfg.distbound values for each layer to a larger value, see help info

https://github.com/fangq/brain2mesh/blob/master/brain2mesh.m#L36

for example, if you want to run the provided demo script SPM_example_brain.m to produce a coarse mesh, for example, you may use

cfg.radbound=struct('scalp',20,'skull',20,'csf',20,'gm',5,'wm',5); % max triangle circumscribed circle radius
cfg.maxvol=5000; % max volume in cubic voxels
[node,elem] = brain2mesh(seg, cfg);
scalpface=volface(elem(:,1:4));
length(unique(scalpface))
plotmesh(node,scalpface);

to produce a much coarser mesh. the skin layer node number is around 4000 nodes. I am sure you can further coarsify this mesh, but if you drop skull/gm/wm mesh density too low, the surface may intersect each other and cause brain2mesh to fail.

fangq commented 4 years ago

Also, if you really just need the surface meshes, you don't have to go through the full meshing pipelines in brain2mesh to get tetrahedral meshes. Surface meshes are a lot easier to create.

For example, if you want to get the scalp surface, you can simply use the below 2 commands

img=seg.wm+seg.gm+seg.csf+seg.skull+seg.scalp;
[no,fc]=v2s(img*(1/256),0.8,10);
plotmesh(no,fc)

this is going to give you a surface mesh for the scalp layer. In other words, you don't need brain2mesh, you can simply use iso2mesh's v2s function to produce surfaces with fast speed and full control of mesh density. skinsurface