蒙特卡洛(Monte Carlo, MC)方法是模拟光子在生物组织中传播的"黄金标准"。由于生物组织具有高度散射的特性,光子的传播路径本质上是一个随机游走(Random Walk)过程。蒙特卡洛模拟通过追踪成千上万个光子的微观轨迹,利用统计力学的方法宏观地反映出光在组织中的能量沉积、吸收和热效应。
基于 MATLAB 的3D 蒙特卡洛光子传输模拟。这个框架涵盖了组织光学特性设定、自由程抽样、Henyey-Greenstein 相位函数散射以及边界折射/全反射处理等核心机制。
1. 核心算法原理概述
在模拟中,每个光子都有一个权重 WWW(初始为 1)。当它进入组织后:
- 步长抽样 :光子在遇到下一次相互作用前传播的距离 sss 服从指数分布:s=−ln(ξ)/μts = -\ln(\xi) / \mu_ts=−ln(ξ)/μt,其中 μt=μa+μs\mu_t = \mu_a + \mu_sμt=μa+μs 是总衰减系数,ξ\xiξ 是 (0,1)(0,1)(0,1) 间的均匀随机数。
- 散射方向 :偏转角度 θ\thetaθ 由 Henyey-Greenstein 函数抽样得到,方位角 ϕ\phiϕ 在 [0,2π][0, 2\pi][0,2π] 均匀抽样。
- 边界处理:在空气-组织界面,根据菲涅尔公式和斯涅尔定律计算反射和折射概率。若发生全反射,则光子留在组织内继续传播。
2. 仿真代码实现
您可以直接复制以下代码到一个新的 MATLAB 脚本文件(例如 monte_carlo_tissue.m)中运行。
matlab
% =========================================================
% 蒙特卡洛模拟:光子在生物组织(皮肤)中的传播
% 描述:本代码模拟光子束垂直入射到多层组织中的传播轨迹,
% 并记录其在组织内部的能量沉积分布。
% =========================================================
clear; clc; close all;
%% --- 1. 模拟与组织参数设定 ---
num_photons = 10000; % 发射的光子数量 (越多越精确,但耗时越长)
grid_size = [100, 100, 200]; % 仿真空间网格 (X, Y, Z),单位:个体素
voxel_size = 0.01; % 体素实际大小 1cm / grid_size = 0.1 mm
% 组织光学参数 (以皮肤/真皮为例)
mu_a = 0.1; % 吸收系数 (1/cm) - 光传播1cm被吸收的概率
mu_s = 10.0; % 散射系数 (1/cm) - 光传播1cm被散射的概率
g = 0.8; % 各向异性因子 (-1 到 1),0.8表示强烈前向散射
n_tissue = 1.4; % 组织折射率
n_air = 1.0; % 空气折射率
% 初始化能量沉积网格 (记录光子能量在空间中的分布情况)
energy_deposition = zeros(grid_size);
% 菲涅尔反射系数 (垂直入射时的近似)
Rs = ((n_air - n_tissue) / (n_air + n_tissue))^2;
%% --- 2. 主循环:发射并追踪每一个光子 ---
fprintf('正在使用蒙特卡洛方法模拟 %d 个光子的传播...\n', num_photons);
for p_idx = 1:num_photons
% --- 2.1 光子初始化 ---
% 初始位置 (网格中心,表面处)
pos = [grid_size(1)/2, grid_size(2)/2, 1];
% 初始方向 (垂直向下,即 +Z 方向)
dir = [0, 0, 1];
% 光子初始权重
weight = 1.0;
% 考虑光束在空气-组织界面的初次反射损失
if rand() < Rs
continue; % 光子被反射,停止追踪
end
% --- 2.2 光子在组织内的随机游走 ---
while true
% 1. 抽样自由程 (Step Length)
% 公式: s = -ln(xi) / (mu_a + mu_s)
s = -log(rand()) / (mu_a + mu_s);
% 2. 更新光子位置
% 新位置 = 旧位置 + 步长 * 单位方向向量
new_pos = pos + s * dir;
% 3. 检查边界碰撞 (假设组织是一个长方体网格)
% 如果光子试图逃离底面 (Z方向超出网格)
if new_pos(3) > grid_size(3) || new_pos(3) < 1
break; % 光子逃逸出组织,结束追踪
end
% 如果光子试图逃离侧面 (X或Y方向超出网格)
if new_pos(1) < 1 || new_pos(1) > grid_size(1) || ...
new_pos(2) < 1 || new_pos(2) > grid_size(2)
break; % 光子逃逸
end
% 4. 记录能量沉积 (光与物质相互作用)
% 按比例分配吸收和散射的能量
absorb_prob = mu_a / (mu_a + mu_s);
if rand() < absorb_prob
% 光子被吸收,将其权重加到当前体素中
% 使用线性索引加速
idx = sub2ind(grid_size, round(pos(1)), round(pos(2)), round(pos(3)));
energy_deposition(idx) = energy_deposition(idx) + weight;
% 采用俄罗斯轮盘赌法 (Russian Roulette) 决定光子存亡以节省计算
if rand() > 0.1 % 90%概率光子死亡
weight = 0;
break;
else
weight = weight / 0.1; % 10%概率存活,权重增加
end
end
% 5. 更新位置 (如果未被吸收)
pos = new_pos;
% 6. 抽样新的散射方向 (Henyey-Greenstein 相位函数)
% 抽样偏转极角 theta
xi = rand();
if g == 0
cos_theta = 2*xi - 1;
else
cos_theta = (1/(2*g)) * (1 + g^2 - ((1-g^2)/(1-g+2*g*xi))^2);
end
sin_theta = sqrt(1 - cos_theta^2);
% 抽样方位角 phi
phi = 2 * pi * rand();
% 构建新的方向向量 (局部坐标系旋转到全局坐标系)
u = dir(1); v = dir(2); w = dir(3);
% 防止数值误差导致 w 超出 [-1, 1]
w = max(min(w, 1.0), -1.0);
if abs(w) > 0.99999
% 接近平行于 Z 轴的情况
new_dir = [sin_theta*cos(phi), sin_theta*sin(phi), cos_theta*w/abs(w)];
else
sqrt_term = sqrt(1 - w^2);
new_dir = [
sin_theta*(u*w*cos(phi) - v*sin(phi))/sqrt_term + u*cos_theta;
sin_theta*(v*w*cos(phi) + u*sin(phi))/sqrt_term + v*cos_theta;
-sin_theta*cos(phi)*sqrt_term + w*cos_theta
];
end
% 归一化新方向向量 (防止浮点数误差累积)
dir = new_dir / norm(new_dir);
end
end
fprintf('模拟完成!\n');
%% --- 3. 结果可视化 ---
% 计算沿深度方向 (Z轴) 的能量沉积剖面
depth_profile = squeeze(sum(sum(energy_deposition, 1), 2));
% 绘制 3D 网格中的中心切片 (X-Z 平面)
figure('Name', '蒙特卡洛光子传输模拟结果', 'Color', 'w', 'Position', [100 100 1200 500]);
% 子图 1: 光子在组织深度方向的能量沉积衰减曲线
subplot(1, 2, 1);
plot(depth_profile, 1:grid_size(3), 'b-', 'LineWidth', 2);
set(gca, 'YDir', 'reverse'); % 翻转Y轴,使Z=1在顶部 (模拟从上往下入射)
title('光子能量随组织深度的沉积分布');
xlabel('能量沉积 (任意单位)');
ylabel('组织深度 (体素数)');
grid on;
% 子图 2: 组织内部能量分布的 2D 切片热力图
subplot(1, 2, 2);
imagesc(energy_deposition(:,:,round(grid_size(3)/2))); % 显示中间深度的切片
title('组织内部能量沉积二维切片图 (俯视图)');
xlabel('X 轴方向');
ylabel('Y 轴方向');
colorbar;
axis equal;
colormap('hot'); % 使用热度图配色
sgtitle('基于蒙特卡洛算法的生物组织光子传输仿真');
3. 代码核心模块解析
- 光学参数 (μa,μs,g{\mu}_a, {\mu}_s, gμa,μs,g) :
mu_a(吸收系数):决定了光子在介质中被吸收的难易程度。黑色素较多的皮肤此值较高。mu_s(散射系数):决定了光子发生碰撞偏转的频率。生物组织通常属于高散射介质 (μs≫μa{\mu}_s \gg {\mu}_aμs≫μa)。g(各向异性因子):g=0g=0g=0 代表各向同性散射,g≈0.8∼0.9g \approx 0.8 \sim 0.9g≈0.8∼0.9 代表强烈的前向散射,这符合生物组织中胶质颗粒对光的散射特性。
- 步长抽样 (Exponential Sampling) :
代码中的s = -log(rand()) / (mu_a + mu_s)是根据概率密度函数 p(s)=μte−μtsp(s) = \mu_t e^{-\mu_t s}p(s)=μte−μts 进行逆变换抽样,这是蒙特卡洛模拟中最核心的数学操作之一。 - Henyey-Greenstein 函数 :
这是生物医光学中描述光在随机介质中散射角度分布的经验公式。代码通过随机数 ξ\xiξ 反解出偏转角 cos(θ)\cos(\theta)cos(θ),从而更新光子的三维运动方向。 - 边界条件与能量守恒 :
光子在网格边缘被判定为"逃逸"。同时,代码引入了Russian Roulette 算法:当光子权重过低时,通过一定概率直接pass光子以避免无意义的长时间追踪,从而保证整个系统的能量守恒。
参考代码 关于蒙特卡洛算法,用于模拟光子在人体皮肤 www.youwenfan.com/contentcsu/63374.html
4. 后续
如果希望将此基础框架应用于更真实的医学或科研场景,可以考虑参考一下以下扩展:
- 多层皮肤结构 :将单一的
mu_a,mu_s替换为三维矩阵,从而定义表皮(Epidermis)、真皮(Dermis)以及皮下脂肪等不同层次的折射率和光学属性。 - 光束类型 :修改初始位置
pos和方向dir的生成方式,以模拟高斯光束(激光)或漫反射光源。 - 相干性模拟:如果需要研究散斑成像(Speckle Imaging)或光学相干断层扫描(OCT),则需要追踪光子的波长(或频率)以及偏振态的变化。