CT扫描图像中的环形伪影 (Ring Artifacts)主要由探测器通道响应不一致、数据采集偏差或硬件缺陷引起,表现为图像中同心圆环状的亮度/对比度异常,严重影响图像质量和诊断准确性。Matlab提供了多种去除环形伪影的方法,涵盖投影域滤波 、图像域变换 和高级算法(如小波变换),以下是具体实现步骤和代码示例:
一、基础方法:投影域高斯滤波(适合轻度伪影)
该方法通过在投影域(而非图像域)对原始数据进行滤波,抵消探测器通道的不一致性,步骤简单且易实现。
1. 方法原理
-
投影数据平均:对同一角度的多个投影数据进行平均,降低随机噪声。
-
高斯滤波:对平均后的投影数据应用高斯滤波,平滑通道间的响应差异。
-
坏点校正:用滤波后的投影数据减去原始投影数据与滤波结果的差值,校正通道不一致性。
2. Matlab代码实现
matlab
function cor_proj = ProjFilter_Ring_Artifacts(projections, Num_angles)
% 输入:projections(投影数据,维度:det_col_count × Num_angles × det_row_count)
% Num_angles(投影角度数量)
% 输出:cor_proj(校正后的投影数据)
% 1. 计算投影数据的平均值(按角度平均)
[X, Y] = size(projections(:, 1, :)); % X:探测器列数,Y:探测器行数
R = zeros(X, Y); % 初始化平均投影矩阵
for i = 1:Num_angles
R = R + squeeze(projections(:, i, :)); % 累加每个角度的投影数据
end
R = R / Num_angles; % 平均投影
% 2. 高斯滤波(平滑投影数据)
core = fspecial('gaussian', [5, 5], 1); % 5×5高斯核,标准差1
R2 = filter2(core, R); % 滤波后的投影
% 3. 坏点校正(校正通道不一致性)
diff = R - R2; % 原始投影与滤波结果的差值(坏点信号)
cor_proj = single(zeros(X, Num_angles, Y)); % 初始化校正后的投影
for i = 1:Num_angles
% 用原始投影减去坏点信号,得到校正后的投影
cor_proj(:, i, :) = squeeze(projections(:, i, :)) - diff;
end
end
3. 使用示例
matlab
% 加载原始投影数据(假设projections为3D矩阵,维度:det_col × angles × det_row)
load('ct_projections.mat');
Num_angles = size(projections, 2); % 投影角度数量
% 调用函数校正环形伪影
cor_proj = ProjFilter_Ring_Artifacts(projections, Num_angles);
% 重建校正后的CT图像(使用滤波反投影算法,如iradon)
theta = linspace(0, 180, Num_angles); % 投影角度范围
recon_img = iradon(cor_proj, theta); % 重建图像
% 显示原始与校正后的图像
figure;
subplot(1, 2, 1); imshow(recon_img_original, []); title('原始图像(含环形伪影)');
subplot(1, 2, 2); imshow(recon_img, []); title('校正后图像(环形伪影缓解)');
二、中级方法:极坐标变换+傅里叶低通滤波(适合中度伪影)
该方法通过将直角坐标系 的环形伪影转换为极坐标系的线性伪影,再用傅里叶变换去除高频噪声,步骤稍复杂但效果更稳定。
1. 方法原理
-
极坐标变换 :将CT图像从直角坐标(x, y)转换为极坐标(r, θ),环形伪影变为垂直方向的线性伪影。
-
傅里叶变换:对极坐标下的图像进行傅里叶变换,得到频谱图。
-
低通滤波:设计二维低通滤波器,去除频谱图中的高频成分(对应线性伪影)。
-
逆变换:对滤波后的频谱图进行傅里叶逆变换,再转换回直角坐标,得到校正后的图像。
2. Matlab代码实现
matlab
function corrected_img = Polar_FFT_RingRemoval(img)
% 输入:img(原始CT图像,灰度图)
% 输出:corrected_img(校正后的图像)
% 1. 极坐标变换(将环形伪影转为线性伪影)
[rows, cols] = size(img);
center = [rows/2, cols/2]; % 图像中心(极坐标原点)
max_radius = min(center); % 最大半径(避免超出图像边界)
% 生成极坐标网格
[r, theta] = meshgrid(linspace(0, max_radius, rows), linspace(0, 2*pi, cols));
x = center(1) + r .* cos(theta); % 极坐标转直角坐标
y = center(2) + r .* sin(theta);
% 插值得到极坐标下的图像
polar_img = interp2(img, x, y, 'bilinear', 0); % 双线性插值,边界填充0
% 2. 傅里叶变换(获取频谱图)
fft_img = fft2(polar_img); % 二维傅里叶变换
fft_shift = fftshift(fft_img); % 频谱中心化
% 3. 设计低通滤波器(去除高频噪声)
[rows_p, cols_p] = size(polar_img);
mask = zeros(rows_p, cols_p);
center_p = [rows_p/2, cols_p/2];
radius = min(center_p) * 0.8; % 低通滤波器半径(保留低频成分)
for i = 1:rows_p
for j = 1:cols_p
if sqrt((i - center_p(1))^2 + (j - center_p(2))^2) < radius
mask(i, j) = 1; % 低通区域(保留)
end
end
end
fft_filtered = fft_shift .* mask; % 滤波后的频谱
% 4. 逆傅里叶变换(回到空间域)
ifft_shift = ifftshift(fft_filtered); % 频谱去中心化
polar_corrected = real(ifft2(ifft_shift)); % 逆傅里叶变换(取实部)
% 5. 极坐标逆变换(回到直角坐标)
[r, theta] = meshgrid(linspace(0, max_radius, rows), linspace(0, 2*pi, cols));
x = center(1) + r .* cos(theta);
y = center(2) + r .* sin(theta);
corrected_img = interp2(polar_corrected, x, y, 'bilinear', 0); % 插值回直角坐标
% 归一化到0-255(灰度图范围)
corrected_img = mat2gray(corrected_img);
end
3. 使用示例
matlab
% 加载原始CT图像(灰度图)
img = imread('ct_image_with_rings.png');
img = rgb2gray(img); % 转为灰度图(如果是RGB)
% 调用函数去除环形伪影
corrected_img = Polar_FFT_RingRemoval(img);
% 显示结果
figure;
subplot(1, 2, 1); imshow(img, []); title('原始图像(含环形伪影)');
subplot(1, 2, 2); imshow(corrected_img, []); title('校正后图像(环形伪影去除)');
三、高级方法:投影域小波变换(适合重度伪影)
该方法通过在投影域对数据进行小波分解,去除高频噪声(对应环形伪影),再重构投影数据,效果更优但计算复杂度较高。
1. 方法原理
-
子投影分割:将原始投影数据分割为多个子投影,消除相邻探测器通道的相关性。
-
小波分解:对每个子投影进行小波分解,得到近似分量(低频)和细节分量(高频)。
-
滤波处理:对近似分量和垂直细节分量进行加权均值滤波,去除环形伪影。
-
小波重构:将滤波后的小波系数重构为新的子投影,合并后得到校正后的投影数据。
2. Matlab代码实现
matlab
function corrected_proj = Wavelet_Proj_RingRemoval(projections, L)
% 输入:projections(原始投影数据,维度:det_col × angles × det_row)
% L(子投影数量,通常取4)
% 输出:corrected_proj(校正后的投影数据)
[det_col, Num_angles, det_row] = size(projections);
corrected_proj = zeros(det_col, Num_angles, det_row); % 初始化校正后的投影
% 1. 将投影数据分割为L个子投影(消除相邻通道相关性)
sub_projs = cell(L, 1); % 存储子投影
for l = 1:L
% 按列分割(每隔L列取一列)
sub_projs{l} = projections(:, mod(1:Num_angles, L) == l, :);
end
% 2. 对每个子投影进行小波分解与滤波
wavelet = 'db4'; % 小波基(Daubechies 4)
level = 1; % 小波分解层数(1层足够)
for l = 1:L
sub_proj = sub_projs{l}; % 当前子投影(det_col × angles × det_row)
[det_col_sub, Num_angles_sub, det_row_sub] = size(sub_proj);
% 初始化滤波后的子投影
sub_proj_filtered = zeros(det_col_sub, Num_angles_sub, det_row_sub);
% 对每个探测器行进行处理(逐行小波分解)
for row = 1:det_row_sub
row_data = squeeze(sub_proj(:, :, row)); % 当前行的投影数据(det_col × angles)
% 小波分解(1层)
[cA, cH, cV, cD] = dwt2(row_data, wavelet); % cA:近似分量,cH:水平细节,cV:垂直细节,cD:对角线细节
% 对近似分量和垂直细节分量进行加权均值滤波
psi = 0.3; % 调节因子(平衡局部均值与原始值)
cA_filtered = weighted_mean_filter(cA, psi); % 近似分量滤波
cV_filtered = weighted_mean_filter(cV, psi); % 垂直细节分量滤波
% 重构小波系数(用滤波后的分量替换原始分量)
row_data_filtered = idwt2(cA_filtered, cH, cV_filtered, cD, wavelet);
% 存储滤波后的行数据
sub_proj_filtered(:, :, row) = row_data_filtered;
end
% 将滤波后的子投影存入校正后的投影
corrected_proj(:, mod(1:Num_angles, L) == l, :) = sub_proj_filtered;
end
end
% 辅助函数:加权均值滤波(用于小波分量)
function filtered = weighted_mean_filter(matrix, psi)
[rows, cols] = size(matrix);
filtered = zeros(rows, cols);
N = 1; % 局部均值窗口大小(3×3窗口,N=1)
for i = 1:rows
for j = 1:cols
% 计算局部均值(3×3窗口)
window = matrix(max(1, i-N):min(rows, i+N), max(1, j-N):min(cols, j+N));
local_mean = mean(window(:));
% 加权均值滤波(psi×局部均值 + (1-psi)×原始值)
filtered(i, j) = psi * local_mean + (1 - psi) * matrix(i, j);
end
end
end
3. 使用示例
matlab
% 加载原始投影数据(假设projections为3D矩阵)
load('ct_projections.mat');
L = 4; % 子投影数量(通常取4)
% 调用函数校正环形伪影
corrected_proj = Wavelet_Proj_RingRemoval(projections, L);
% 重建校正后的CT图像(使用iradon)
theta = linspace(0, 180, size(corrected_proj, 2)); % 投影角度范围
recon_img = iradon(corrected_proj, theta); % 重建图像
% 显示结果
figure;
subplot(1, 2, 1); imshow(recon_img_original, []); title('原始图像(含环形伪影)');
subplot(1, 2, 2); imshow(recon_img, []); title('校正后图像(环形伪影去除)');
四、方法选择与优化建议
| 方法 | 适合场景 | 优点 | 缺点 |
|---|---|---|---|
| 投影域高斯滤波 | 轻度环形伪影 | 步骤简单、计算快 | 对重度伪影效果有限 |
| 极坐标+傅里叶滤波 | 中度环形伪影 | 效果稳定、保留边缘信息 | 需要坐标变换,计算复杂度中等 |
| 投影域小波变换 | 重度环形伪影 | 效果好、针对性强(去除高频噪声) | 计算复杂、需要调整小波参数 |
优化建议
-
参数调整:
-
高斯滤波的核大小(如
fspecial('gaussian', [7,7], 2))可根据伪影严重程度调整(核越大,平滑效果越强)。 -
小波变换的基函数(如
'db4'改为'sym8')和分解层数(如level=2)可尝试不同组合,寻找最优效果。
-
-
多方法组合:
- 先用投影域高斯滤波去除轻度伪影,再用极坐标+傅里叶滤波处理残留伪影,最后用小波变换优化细节。
-
硬件加速:
- 对于大规模数据,可使用Matlab的
parfor循环(并行计算)加速投影域处理,或使用GPU加速(如gpuArray)。
- 对于大规模数据,可使用Matlab的
参考代码 Matlab去除CT扫描得到的图像的环形伪影 www.youwenfan.com/contentcsq/65736.html
五、注意事项
-
数据预处理:
-
输入的投影数据需进行平场校正 (Flat-field Correction)和暗场校正(Dark-field Correction),去除硬件本身的噪声(如探测器的暗电流)。
-
图像数据需转为灰度图(如果是RGB),并确保像素值在0-255范围内。
-
-
结果验证:
-
校正后的图像需与原始图像对比,评估环形伪影的去除效果(如计算伪影区域的信噪比(SNR)或结构相似性(SSIM))。
-
避免过度滤波导致图像细节丢失(如边缘模糊),可通过调整滤波参数(如高斯核大小、小波分解层数)平衡去伪影效果与细节保留。
-
六、总结
Matlab提供了多种去除CT图像环形伪影的方法,从基础的投影域滤波到高级的小波变换,覆盖了不同程度的伪影场景。用户可根据伪影严重程度选择合适的方法,并通过参数调整和多方法组合优化效果。对于重度伪影 ,推荐使用投影域小波变换 ;对于轻度伪影 ,投影域高斯滤波足以应对。实际应用中,需结合数据预处理(如平场校正)和结果验证,确保校正后的图像满足诊断要求。