如何用掩模(mask)提取MRI图像的原理与技术

前言:

  在磁共振影像处理中,mask是一个非常常用的工具,它的作用笔者使用过的包括但不限于:

  • 预处理:去除头骨、颈部、颅外等区域(脑提取(Brain extraction)&头骨剥离(Skull stripping))。
  • 分割:将大脑分离成特定成分,如白质、灰质、脑脊液等。
  • 标准化和配准:mask可以确保只有相关脑区参与到配准计算,这在某些序列(eg:QSM)中是必不可少的一步。
  • 统计分析:在组间比较前进行mask,不仅可以增加同一体素的可比性,还能减少计算量。

  mask也有不同的类型,常见的两种原理分别是:

  1.二值化掩模:只包含0和1的MRI图像,1表示感兴趣区域,0表示不感兴趣的区域。

  2.先验概率掩模:每个体素里包含从0到1的连续变量,指该体素在概率上属于某种成分的可能性。(例如0.5&csf,指该体素在之前的群体模版里有50%可能性属于脑脊液成分。)

图1 二值化MRI掩模示意图

   原理

    mask提取的过程本质上是通过元素级的乘法,将原始MRI图像中的不感兴趣区域定义为0,感兴趣区保留原始强度。

  拿灰质mask为例,其中灰质区域的体素值为1,非灰质区域为0,将这个mask矩阵与原始MRI图像矩阵相乘,非灰质区域就进行了置零。

  而脑图谱中的ROI(感兴趣区)提取方法本质上也是通过label的索引,再转化成二值mask来提取。

  数学描述

MRI图像是三维矩阵:

  • x方向:n个体素;
  • y方向:m个体素;
  • z方向:k个体素。

定义变量:

  •   I:原始MRI图像。
  • M:灰质mask。
  • G:提取出的MRI里的灰质图像。

I,M,G都是三维矩阵,且其三者的维度相等并等于I,M,G \in \mathbb{R}^{m\cdot n\cdot k}

对于图像中的每个体素,我们都可以用(m,n,k)来表示其位置。

那么提取灰质的过程也就是:
G(m,n,k)=I((m,n,k))\times M(m,n,k)

概率mask原理相同:

  M(m,n,k)\in \left [ 0,1 \right ]

  某些情况下每个体素单位内不是严格的0或1,而是每个体素属于某种成分的概率。

G(m,n,k)=I((m,n,k))\bigodot M(m,n,k)

技术

  上文介绍了mask提取MRI图像原理,本质上非常简单,但3D图像还涉及到中心坐标点,朝向,体素点大小,尺寸等许多问题,为了让mask可以完美的覆盖到我们的MRI图像,在技术层面还是要细心做许多工作的。

  在这里覆上笔者亲踩的坑,如果图省事直接用matlab的imresize函数简单粗暴解决问题,效果有多差。

图2 缩放VS裁剪的提取方法的比较

1.准备mask

  准备好二值化掩模,将其中感兴趣区设置为1,非感兴趣区设置为0。

  

图3 灰质二值化MASK示意图

2.Reslice:确保mask和MRI采样率(Voxel Size)一致

读取:

  在matlab上用spm读取MRI和mask的图像信息。

V = spm_vol('MRIimg.nii');
disp('Image dimensions:');
disp(V.dim);
voxel_size = sqrt(sum(V.mat(1:3,1:3).^2));
disp('Voxel size (mm):');
disp(voxel_size);
图4 图像信息输出结果

重采样:

  使用cat的toolbox进行自动化Resize,或者自己在matlab上编写代码,示例如下,一般使用常见的邻近法插值即可:

​
% 将voxel size为3mm的MASK重新采样为1.5mm
filename = 'mask.nii';
V = spm_vol(filename);
[img, XYZ] = spm_read_vols(V);
old_dim = V.dim;
new_dim = round(old_dim .* (3/1.5));
[x, y, z] = ndgrid(1:new_dim(1), 1:new_dim(2), 1:new_dim(3));
new_coords = [x(:)'; y(:)'; z(:)'];
M = V.mat * [diag(3./1.5), zeros(3,1); zeros(1,3), 1];
old_coords = V.mat \ (M * [new_coords; ones(1, size(new_coords, 2))]);
interp_img = interpn(img, old_coords(1,:), old_coords(2,:), old_coords(3,:), 'nearest');
new_img = reshape(interp_img, new_dim);
new_V = V;
new_V.dim = new_dim;
new_V.mat = M;
new_V.fname = 'F:\XIUJUEmaterial\resampled_1.5mm_mask.nii';
spm_write_vol(new_V, new_img);
disp('重采样完成!');

​

3.确保mask和MRI图像配准

通过将MRI和mask重叠的方式,它们对齐在同一空间。

如果没有重叠,需配准到标准空间(spm配置教程)。

图5 mask与MRI配准示意图

4.【可选】进行mask填充

因为我们从网站上下载的脑图谱mask和自己处理的T1img维度可能不一样,如果T1大于mask的范围,我们需要将mask的边缘用零值填充,使其和T1一致,再进行运算。

mri = spm_read_vols(spm_vol('T1.nii'));
mask = spm_read_vols(spm_vol('Mask.nii'));

[x1, y1, z1] = size(mri);
[x2, y2, z2] = size(mask);

pad_x = max(0, x1 - x2);
pad_y = max(0, y1 - y2);
pad_z = max(0, z1 - z2);

% 填充
mask_padded = padarray(mask, [pad_x, pad_y, pad_z], 0, 'post');

% 裁剪
mask_final = mask_padded(1:x1, 1:y1, 1:z1);

% 写入MASK原文件
V = spm_vol('Mask.nii');
V.dim = size(mask_final);
spm_write_vol(V, mask_final);

4.进行提取

可以用spm-imgCacluater进行图像相乘。

图6 spm的mask提取步骤

5.【可选】裁剪

  如果进行了第四步,用填充后的mask进行抓取,那在进行组间比较前需要再裁剪,否则会有很多体素值为0,影响多重比较校正的计算。下文的代码介绍将图像裁剪为113*137*113维度。

% 读取MRI图像
mri_file = 'MRI.nii';
V = spm_vol(mri_file);
img = spm_read_vols(V);

% 找到非零值的索引
[x, y, z] = ind2sub(size(img), find(img ~= 0));

% 计算非零值的中心
center_x = round(mean(x));
center_y = round(mean(y));
center_z = round(mean(z));

% 计算裁剪的起始和结束索引
start_x = center_x - 56; end_x = center_x + 56;
start_y = center_y - 68; end_y = center_y + 68;
start_z = center_z - 56; end_z = center_z + 56;

% 确保裁剪索引在图像范围内
start_x = max(1, start_x); end_x = min(size(img, 1), end_x);
start_y = max(1, start_y); end_y = min(size(img, 2), end_y);
start_z = max(1, start_z); end_z = min(size(img, 3), end_z);

% 裁剪图像
img_cropped = img(start_x:end_x, start_y:end_y, start_z:end_z);

% 确保裁剪后的尺寸正确
[crop_x, crop_y, crop_z] = size(img_cropped);
if crop_x ~= 113 || crop_y ~= 137 || crop_z ~= 113
    warning('裁剪后的尺寸不是113x137x113,可能需要额外的处理');
    % 如果尺寸不匹配,可以考虑在这里添加额外的裁剪或填充步骤
end

% 创建新的头文件
V_new = V;
V_new.fname = 'path_to_save_cropped_image.nii';
V_new.dim = size(img_cropped);

% 更新变换矩阵以反映新的图像位置
% 这确保了裁剪后的图像在原始空间中的正确定位
orig_to_world = V.mat;
crop_to_orig = eye(4);
crop_to_orig(1:3, 4) = [start_x; start_y; start_z] - 1;
V_new.mat = orig_to_world * crop_to_orig;

% 保存新图像
spm_write_vol(V_new, img_cropped);

总结:

  笔者进行VBM(体素形态学)组间比较时发现不同组因T1图像不同,分割后的灰质图像维度并不一致,为了让每个体素单位的统计检验更可靠,学习将三组在同一空间再次应用灰质掩模后比较。

图7 按本文步骤提取的灰质图像
  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值