Python-MNE-源空间和正模型07:修复BEM和头表面

news2024/11/15 15:56:51

有时在创建BEM模型时,由于可能出现的一系列问题(例如,表面之间的交叉),表面需要手动校正。在这里,我们将看到如何通过将表面导出到3D建模程序blender,编辑它们,并重新导入它们来实现这一点。我们还将给出一个简单的例子,说明如何使用pymeshfix来修复拓扑问题。
本教程的大部分内容都是基于Ezequiel Mikulan的ezemikulan/blender_freesurfer。

import os
import shutil

import mne

data_path = mne.datasets.sample.data_path()
subjects_dir = data_path / "subjects"
bem_dir = subjects_dir / "sample" / "bem" / "flash"
surf_dir = subjects_dir / "sample" / "surf"

导出表面到blender

在本教程中,我们使用MNE-Sample集,其表面没有问题。为了演示如何修复有问题的表面,我们将手动放置一个内颅骨顶点在外颅骨顶点的外部的网格。

然后我们将表面转换为.obj文件,并在FreeSurfer subject文件夹中创建一个名为conv的新文件夹来保存它们。

# Put the converted surfaces in a separate 'conv' folder
conv_dir = subjects_dir / "sample" / "conv"
os.makedirs(conv_dir, exist_ok=True)

# Load the inner skull surface and create a problem
# The metadata is empty in this example. In real study, we want to write the
# original metadata to the fixed surface file. Set read_metadata=True to do so.
coords, faces = mne.read_surface(bem_dir / "inner_skull.surf")
coords[0] *= 1.1  # Move the first vertex outside the skull

# Write the inner skull surface as an .obj file that can be imported by
# Blender.
mne.write_surface(conv_dir / "inner_skull.obj", coords, faces, overwrite=True)

# Also convert the outer skull surface.
coords, faces = mne.read_surface(bem_dir / "outer_skull.surf")
mne.write_surface(conv_dir / "outer_skull.obj", coords, faces, overwrite=True)

(以上代码中的文件连接在新版本中更改)

在blender中编辑

查看下面的视频教程,了解如何在Blender中导入,编辑和导出表面(一步一步的说明也在下面):
在blender中编辑
我们现在可以打开Blender并导入表面。进入文件>导入>Wavefront(.obj)。导航到conv文件夹并选择要导入的文件。确保选择“保持垂直顺序”(Keep Vert Order)选项。你还可以选择Y Forward选项以在正确的方向(RAS)加载坐标轴:
在这里插入图片描述
为方便起见,您可以通过按下Operator Presets旁边的+按钮来保存这些设置,对所有你想导入的表面重复这个过程。

你现在可以编辑任何你喜欢的表面。请参阅初学者blender系列教程来学习如何使用blender。可以看它的第2部分,教你如何使用基本的编辑工具来修复表面。
在这里插入图片描述

在MNE-Python中使用修复的表面

在Blender中,你可以通过选择它来导出一个表面作为.obj文件,然后进入file > export > Wavefront (.obj)。你需要再次选择Y Forwar选项,并选中Keep Vertex Order box。
在这里插入图片描述
每个surface都需要作为单独的文件导出。我们建议将它们保存在conv文件夹中,并以_fixed.obj为结尾,尽管不是严格必要的。
为了能够从上到下运行本教程脚本,我们在这里使用Python代码模拟您在Blender中手动进行的编辑:

coords, faces = mne.read_surface(conv_dir / "inner_skull.obj")
coords[0] /= 1.1  # Move the first vertex back inside the skull
mne.write_surface(conv_dir / "inner_skull_fixed.obj", coords, faces, overwrite=True)

现在回到Python,你可以读取修复后的.obj文件,并将它们保存为FreeSurfer的 .surf文件。为了mne.make_bem_model()函数找到它们,需要使用它们的原始名称保存在surf文件夹中,例如bem/inner_skull.surf一定要先备份原来的表面,以防出错!

# Read the fixed surface
coords, faces = mne.read_surface(conv_dir / "inner_skull_fixed.obj")

# Backup the original surface
shutil.copy(bem_dir / "inner_skull.surf", bem_dir / "inner_skull_orig.surf")

# Overwrite the original surface with the fixed version
# In real study you should provide the correct metadata using ``volume_info=``
# This could be accomplished for example with:
#
# _, _, vol_info = mne.read_surface(bem_dir / 'inner_skull.surf',
#                                   read_metadata=True)
# mne.write_surface(bem_dir / 'inner_skull.surf', coords, faces,
#                   volume_info=vol_info, overwrite=True)

编辑头表面

有时头部表面有缺陷,需要手动编辑。我们使用mne.write_head_bem()将修改的表面转换为.fif文件。

低分辨率的头

对于EEG正向建模,outer_skin.surf可能是手动编辑的。在这种情况下,记得保存从编辑表面文件或配准得到的-head.fif的原始和修改版本。

# Load the fixed surface
coords, faces = mne.read_surface(bem_dir / "outer_skin.surf")

# Make sure we are in the correct directory
head_dir = bem_dir.parent

# Remember to backup the original head file in advance!
# Overwrite the original head file
#
# mne.write_head_bem(head_dir / 'sample-head.fif', coords, faces,
#                    overwrite=True)

高分辨率的头

我们使用mne.read_bem_surfaces()来读取head surface文件。编辑完成后,我们再次使用mne.write_head_bem()输出头文件。这里我们用-head.fif提高速度。

# If ``-head-dense.fif`` does not exist, you need to run
# ``mne make_scalp_surfaces`` first.
# [0] because a list of surfaces is returned
surf = mne.read_bem_surfaces(head_dir / "sample-head.fif")[0]

# For consistency only
coords = surf["rr"]
faces = surf["tris"]

# Write the head as an .obj file for editing
mne.write_surface(conv_dir / "sample-head.obj", coords, faces, overwrite=True)

# Usually here you would go and edit your meshes.
#
# Here we just use the same surface as if it were fixed
# Read in the .obj file
coords, faces = mne.read_surface(conv_dir / "sample-head.obj")

# Remember to backup the original head file in advance!
# Overwrite the original head file
#
# mne.write_head_bem(head_dir / 'sample-head.fif', coords, faces,
#                    overwrite=True)
1 BEM surfaces found
Reading a surface...
[done]
1 BEM surfaces read

blender编辑技巧

一个特别有用的操作是Shrinkwrap功能,它将一个表面限制在另一个表面内。使用方法如下:

①选择表面:选择产生问题的表面。
②选择顶点:在Edit Mode下,按C使用圆选择工具选择外面的顶点。
③-⑤对顶点进行分组:在 Object Data Properties选项卡使用+按钮添加一个顶点组,并单击Assign将当前选择分配到组。
⑥-⑧Shrinkwrap:在Modifiers选项卡中,在Add Modifier下添加一个Shrinkwrap,并将其设置为snap内部,外部表面为Target,之前创建的Group为Vertex Group。然后可以使用Offset参数来调整距离。
⑨应用:在Object Mode下,点击Shrinkwrap修饰符的向下箭头,然后点击应用。
在这里插入图片描述
如果上述操作后没有任何变化,内颅骨表面的法线可能被反转了。要解决这个问题,请选择所有的顶点或内部颅骨的所有面,并在工具栏中进行Mesh>Normals>Flip。
然后!我们就已经准备好继续分析了,例如继续运行mne.make_bem_model()

还有错误怎么办?

blender操作

当在Blender中编辑BEM表面/网格时,请确保使用的工具不会改变顶点的数量或顺序,或三角形面的几何形状。例如,避免使用挤压工具(extrusion tool),因为它复制了被挤压的顶点。

用smoothing的方法清理坏的、密集的头部表面

如果你在使用mne make_scalp_surfaces时得到一个粗糙的头部表面,考虑使用FreeSurfer的高斯内核提前平滑T1,在受试者的mri目录中使用如下内容:

mri_convert --fwhm 3 T1.mgz T1_smoothed_3.mgz

这里的--fwhm参数决定了应用多少smoothing,单位为mm。然后删除SUBJECTS_DIR/SUBJECT/surf/lh.seghead重新运行mne make_scalp_surfaces并添加额外的参数--mri="T1_smoothed_3.mgz" --overwrite,你应该得到更clean的表面。

拓扑错误

MNE-Python要求网格满足一定的拓扑检查,以保证边界元求解、电极投影等后续处理能够正常工作。

下面是在MNE-Python中使用网格时可能遇到的一些错误示例,以及这些错误的可能原因。

  1. Cannot decimate to requested ico grade
    错误是由于顶点太少或太多造成的。完整的错误类似于:
RuntimeError: Cannot decimate to requested ico grade 4. The provided
BEM surface has 20516 triangles, which cannot be isomorphic with a
subdivided icosahedron. Consider manually decimating the surface to a
suitable density and then use ico=None in make_bem_model.
  1. Surface inner skull has topological defects
    在试图通过删除顶点来匹配原始三角形数量时,可能会发生此错误。完整的错误信息如下所示:
RuntimeError: Surface inner skull has topological defects: 12 / 20484
vertices have fewer than three neighboring triangles [733, 1014,
 2068, 7732, 8435, 8489, 10181, 11120, 11121, 11122, 11304, 11788]
  1. Surface inner skull is not complete
    这个错误,和前面的错误一样,反映了表面拓扑结构的一个问题,即预期的顶点/边/面模式被打乱了。
RuntimeError: Surface inner skull is not complete (sum of solid
angles yielded 0.999668, should be 1.)
  1. Triangle ordering is wrong
    这个错误反映了内存中表示曲面的方式(顶点/面定义的顺序)与MNE-Python所期望的不匹配。完整的错误是:
RuntimeError: The source surface has a matching number of triangles
but ordering is wrong
在blender中处理拓扑结构

对于任何这些错误,通常最简单的方法是从未编辑的BEM表面重新开始,并再次尝试,确保只移动顶点和面,而不添加或删除任何顶点和面。例如,选择一个圆的顶点,然后按G将它们拖动到想要的位置。在Blender中smoothing一组选中的顶点(右键单击并选择“smoothing”)也hen有用。

使用pymeshfix处理拓扑结构

pymeshfix是一个GPL许可的Python模块,用于生成满足上述拓扑检查的水密网格。例如,如果你的'SUBJECTS_DIR/SUBJECT/surf/lh.seghead'文件中有拓扑问题,通过上面的*“用smoothing的方法清理坏的、密集的头部表面”*行不通的,你可以尝试修复网格。在使用conda或pip从SUBJECTS_DIR/SUBJECT/surf目录安装pymeshfix后,你可以尝试:

import pymeshfix
rr, tris = mne.read_surface('lh.seghead')
rr, tris = pymeshfix.clean_from_arrays(rr, tris)
mne.write_surface('lh.seghead', rr, tris)

在某些情况下,这可以修复拓扑结构,以便后续对mne make_scalp_surfaces的调用可以成功,而不需要使用--force参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2090199.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

峟思大坝安全监测系统:科技筑牢工程稳定的基石

在全球工程建设的宏伟蓝图中,大坝安全始终占据着举足轻重的地位。随着科技的日新月异,大坝安全监测系统作为守护工程稳定的“哨兵”,正步入一个前所未有的创新与发展阶段。这一系统不仅是大坝健康管理的关键工具,更是确保民生安全…

使用pgdump、pgrestore迁移数据表到docker部署的postgis

将本地数据同步到内网服务器,使用的postgis,表含空间字段 备份 本地使用pgadmin 4进行备份,pgrestore的命令参数找起来麻烦,这个可以界面操作,比较方便 说明 说明的截图来自pgadmin,点击这个打开 …

搭建数据库启前后端环境

1、 安装postgre,修改pg_hba.conf文件 2、安装dbeaer 3、任务管理器-服务:查看是否启动postgresql-x64-11 4、连接测试:新建数据库连接 http://127.0.0.1:14269/browser/# pgAdmin等于dbeaver 5、创建数据库: 6、启动后端…

数博会 | 百度智能云千帆大模型数据安全解决方案获优秀科技成果

8月28日,由国家数据局主办、贵州省人民政府承办的2024中国国际大数据产业博览会在贵阳盛大开幕。期间,2024中国国际大数据产业博览会领先科技成果发布会在贵阳国际生态会议中心举行。百度智能云千帆大模型数据安全解决方案,凭借大模型全生命周…

可信捐赠系统的设计与开发论文

摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统可信捐赠系统信息管理难度大,容错率低&#x…

面试经典算法150题系列-找出字符串中第一个匹配项的下标

找出字符串中第一个匹配项的下标 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 示例 1&#xff1a…

前缀和差分【算法 13】

在算法领域中,前缀和与差分数组是两种高效处理区间问题的技术。它们能在特定问题场景下将时间复杂度从 (O(n)) 降到 (O(1)),适用于频繁的区间查询与修改操作。本文将简要介绍这两种技术及其应用。 1. 前缀和 (Prefix Sum) 前缀和是指一个数组的第 (i)…

【微信小程序】小程序的 MobX 绑定辅助库

小程序的 MobX 绑定辅助库 小程序的 MobX 绑定辅助库。 此 behavior 依赖开发者工具的 npm 构建。具体详情可查阅 官方 npm 文档 。 可配合 MobX 的小程序构建版 npm 模块 mobx-miniprogram 使用。 使用方法 需要小程序基础库版本 > 2.2.3 的环境。 也可以直接参考这个代码…

阿里云OSS迁移至华为云OBS,Java整合华为云OMS实现文件的自动批量迁移功能

华为云OBS 华为云对象存储服务(Object Storage Service,简称OBS)是华为云提供的一个高可靠、高安全、高可扩展的云存储服务。它允许用户在云上存储和管理海量数据,如图片、视频、文档、备份文件等。OBS 可以用作数据备份、文件共享、大数据存储、以及静态网站托管等多种用…

C++标准 alignas 与 windows 封装指令 (pack pragma) 的区别

C标准 alignas 与 windows 封装指令 (pack pragma) 的区别 结构体内存对齐受到二方面的影响【共同作用】: 一个方面是语言的对齐规则》语言的对齐规则 参考 https://blog.csdn.net/weixin_43698578/article/details/104801421 【主要影响因素是成员的对齐大小】【基本类型的对…

OpenCV小练习:人脸检测

OpenCV自带人脸检测模型,拿来就能用。所以“人脸检测”这个任务对于OpenCV而言真是太简单了——感叹一下:OpenCV太强大了!相关的介绍文章在网上可以搜到很多,原本我觉得没必要再写一篇了。结果我在写练习代码的时候,还…

【王树森】RNN模型与NLP应用(3/9):Simple RNN模型(个人向笔记)

前言 现在RNN已经没有以前那么流行了。在数据量大的情况下不如Transformer,但是在小数据的情况下仍然表现良好。 How to model sequential data? 1. one to one模型 像MLP和CNN,还有前面两节课讲到的二分类问题,都是基于one to one模型&a…

安装jmeter的梯度压测线程组(Custom Thread Groups)的插件

1、打开:Install :: JMeter-Plugins.org 2、进入主页后点击下面图片的链接进行安装 3、将安装包放入apache-jmeter-5.4.1 > lib > ext 里面 4、打开Jmeter 点击下面的【Plugins Manager】 5、进入 【Plugins Manager】后选择【Avaliable Plug…

Apache Flink 零基础入门(二):开发环境搭建和应用的配置、部署及运行

关联比赛: Apache Flink极客挑战赛——Flink TPC-DS性能优化 作者:沙晟阳 本文是根据 Apache Flink 系列直播课程整理而成,由阿里巴巴高级开发工程师沙晟阳分享,主要面向于初次接触 Flink、或者对 Flink 有了解但是没有实际操作过的同学。…

【分布式定时任务】XXL-JOB_2.4.1部署与实战

部署 分布式任务调度平台XXL-JOBXXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。https://www.xuxueli.com/xxl-job/ 一 数据库配置 执行初始化数据库…

flutter和原生Android以及IOS开发相比有什么优缺点?

Flutter 是 Google 开发的一个开源移动应用开发框架,它使用 Dart 语言编写。Flutter 的主要目标是使开发者能够从单一的代码库构建高性能、高保真的应用程序,这些应用程序可以在 iOS 和 Android 平台上运行,同时保持原生应用的感觉。 Flutte…

tomcat架构设计分析,核心组件详解

提示:tomcat整体架构分析,tomcat核心组件详解、tomcat请求全流程、tomcat设计模式分析。责任链模式设计、tomcat设计详解、tomcat调优的前置文档 文章目录 前言一、相关概念1、tomcat的概念2、web应用部署的3种方式 二、tomcat的整体架构1、tomcat架构图…

三星与海力士发力决战HBM4

在8月中旬,三星宣布正在加速推进下一代HBM(High Bandwidth Memory)的研发,目标是在今年年底前完成HBM4的设计定稿(tape-out)。而SK海力士则继续保持其竞争力,计划在10月份完成HBM4的设计定稿&am…

华为云征文|部署私有云和文档管理系统 Kodcloud

华为云征文|部署私有云和文档管理系统 Kodcloud 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 应用场景1.3 对比普通ECS 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Kodcloud3.1 Jellyfin 介绍3.2 Docker 环境搭建3.3 Jell…

Linux内核6.12新特性:panic之后扫码显示故障信息

Linux 内核 6.12 版本即将引入一项有趣的功能——在内核Panic时显示一个可选的二维码。这一功能将允许用户通过扫描二维码直接访问内核Panic信息的日志,从而更容易地诊断问题所在。 这不是 Linux 第一次尝试使用二维码。早在2014年,就有过关于在内核Pani…