基于R语言的脑表面热图着色及相关技术问题咨询
脑3D模型相关技术问题解答
背景
以下代码可生成脑的3D模型:
library(rgl) library(brainR) template <- readNIfTI(system.file("MNI152_T1_2mm_brain.nii.gz", package = "brainR"), reorient = FALSE) misc3d::contour3d(template, level = 4500, alpha = .7, draw = T)
当设置参数draw = FALSE时,contour3d会返回一个三角形网格对象(类为Triangles3D)而非直接绘制,示例如下:
a <- misc3d::contour3d(template, level = 4500, alpha = .7, draw = F) str(a) # List of 10 # $ v1 : num [1:110433, 1:3] 45 45 46 46 47 47 43 43 44 44 ... # $ v2 : num [1:110433, 1:3] 44.1 46 46 47 47 ... # $ v3 : num [1:110433, 1:3] 45 45 45 46 46 ... # $ color : chr "white" # $ color2 : logi NA # $ fill : logi TRUE # $ material: chr "default" # $ col.mesh: logi NA # $ alpha : num 0.7 # $ smooth : num 0 # - attr(*, "class")= chr "Triangles3D"
问题解答
1. 外部表面热图投影(表面着色)
要给外部表面做热图投影,核心是给每个三角形面片或顶点分配对应颜色,具体步骤如下:
- 先准备好与表面面片/顶点匹配的数值数据(比如脑区激活值),确保数据数量和模型面片/顶点数对应。
- 用
colorRampPalette创建颜色映射,把数值转换成颜色向量。 - 直接修改
Triangles3D对象的color属性后重新绘制,或者转换为tmesh3d做顶点着色:# 示例:用随机数模拟激活数据(对应每个三角形面片) values <- runif(nrow(a$v1), min = 0, max = 1) # 创建蓝-白-红的颜色映射 col_map <- colorRampPalette(c("blue", "white", "red"))(100) # 将数值映射到对应的颜色索引 col_indices <- findInterval(values, seq(0, 1, length.out = 100)) # 给每个面片分配颜色 a$color <- col_map[col_indices] # 重新绘制带热图的表面 misc3d::drawScene.rgl(list(a))
如果要基于顶点着色,可先转换为tmesh3d格式:
# 把Triangles3D转成tmesh3d vertices <- rbind(a$v1, a$v2, a$v3) indices <- matrix(1:nrow(vertices), ncol = 3, byrow = TRUE) tmesh <- tmesh3d(vertices, indices) # 给每个顶点分配颜色 vertex_colors <- col_map[findInterval(runif(nrow(vertices)), seq(0,1,length.out=100))] shade3d(tmesh, color = vertex_colors, alpha = 0.7)
2. 定位特定位置(如EEG通道)
要在模型中标记EEG通道位置,关键是统一坐标系:
- 先获取EEG通道的MNI标准坐标(如果是头部坐标系,需要通过转换矩阵转成MNI空间)。
- 用
rgl的points3d在3D场景中标记这些点:# 示例:3个EEG通道的MNI坐标 eeg_coords <- matrix(c(-40, -20, 50, 40, -20, 50, 0, 0, 60), ncol = 3, byrow = TRUE) # 用红色圆点标记通道位置 points3d(eeg_coords, color = "red", size = 5)
如果要验证通道是否贴近脑表面,可计算点到表面的距离:
library(Rvcg) # 把tmesh转成vcgMesh格式 vcg_mesh <- vcgTmesh(tmesh) # 计算每个EEG点到脑表面的距离 distances <- vcgPointToMesh(eeg_coords, vcg_mesh) print(distances$distance)
3. 使用rgl::surface3d生成表面?
不行。rgl::surface3d要求输入是规则网格数据(x、y、z需为二维矩阵,对应网格的行列结构),但a$v1、a$v2、a$v3是不规则的三角形面片顶点,属于非结构化网格,无法适配surface3d的参数要求。
如果要基于这些数据生成表面,应该用支持非结构化网格的函数:
- 直接用
misc3d::drawScene.rgl绘制Triangles3D对象:drawScene.rgl(list(a)) - 转换为
tmesh3d后用shade3d绘制(参考问题1的示例) - 用
triangles3d直接绘制每个三角形:triangles3d(rbind(a$v1, a$v2, a$v3), color = a$color, alpha = a$alpha)
内容的提问来源于stack exchange,提问作者fina
相关产品推荐
相关产品推荐

