1. CT重构概述
CT(Computed Tomography,计算机断层扫描)重构是指从物体在不同角度下采集的投影数据(X射线衰减数据)中,通过数学算法重建出物体内部三维结构图像的过程。它是医学影像、工业无损检测等领域的关键技术。
CT重构的核心问题是求解一个逆问题:已知投影数据(Radon变换结果),反求原始物体的衰减系数分布。根据数据采集的完备性和算法原理,主要分为解析法和迭代法两大类。
2. 解析法重构原理
解析法基于Radon变换及其逆变换的严格数学理论,计算速度快,是临床CT的主流方法。
2.1 滤波反投影(FBP)算法
滤波反投影(Filtered Back Projection, FBP)是解析法的代表。其基本原理可分为三步:
- 投影数据预处理:对采集的投影数据 \( p(\theta, t) \) 进行必要的校正,如对数变换、空气校正等。
- 滤波:在频域或空域对投影数据进行滤波,以补偿直接反投影带来的"星状伪影"。常用滤波器有Ram-Lak、Shepp-Logan、Cosine等。
- 反投影:将滤波后的投影数据沿原投影路径"反投"回图像空间,对所有角度积分,得到重建图像 \( f(x, y) \)。
数学表达式为:
\ f(x, y) = \\int_{0}\^{\\pi} \\left\[ p(\\theta, t) \* h(t) \\right_{t = x \cos\theta + y \sin\theta} d\theta \]
其中 \( h(t) \) 为滤波函数,\( * \) 表示卷积运算。
为了更直观地展示FBP算法的流程,下面用流程图说明其三个核心步骤:
流程图说明:
- 输入:原始投影数据 \( p(\theta, t) \) 作为算法起点。
- 第一步:投影数据预处理 - 对原始数据进行必要的校正,如对数变换将衰减值转换为线性数据、空气校正消除系统误差等。
- 第二步:滤波处理 - 在频域或空域对预处理后的数据进行滤波,补偿直接反投影会产生的"星状伪影",常用滤波器包括Ram-Lak(斜坡滤波器)、Shepp-Logan(sinc窗滤波器)、Cosine等。
- 第三步:反投影重建 - 将滤波后的投影数据沿原X射线路径"反投"回图像空间,并对所有投影角度进行积分,最终得到重建图像 \( f(x, y) \)。
- 输出:重建后的断层图像,反映物体内部的衰减系数分布。
2.2 扇束与锥束重构
根据X射线源和探测器的几何排列,可分为平行束、扇束和锥束扫描。FBP算法需要针对不同的几何进行重排或加权修正。
- 扇束重构:常用于早期单排探测器CT。可通过重排算法将扇束数据转换为等效平行束数据,再应用FBP。
- 锥束重构:用于现代多排探测器螺旋CT。FDK(Feldkamp-Davis-Kress)算法是锥束几何下FBP的经典近似算法。
3. 迭代法重构原理
迭代法通过建立投影数据与图像之间的系统模型,构造目标函数,并采用迭代优化算法求解。它更适合于投影数据不完全、低剂量或有限角度等场景,但计算量远大于解析法。
3.1 代数重建技术(ART)
代数重建技术(Algebraic Reconstruction Technique, ART)将重建问题转化为求解大型线性方程组 \( \mathbf{Ax} = \mathbf{b} \)。其中 \( \mathbf{A} \) 为系统矩阵(描述像素对射线的贡献),\( \mathbf{x} \) 为待求图像向量,\( \mathbf{b} \) 为投影数据向量。
ART采用逐投影更新策略,第 \( k+1 \) 次迭代公式为:
\ \\mathbf{x}\^{(k+1)} = \\mathbf{x}\^{(k)} + \\lambda \\frac{b_i - \\mathbf{a}_i\^T \\mathbf{x}\^{(k)}}{\\\|\\mathbf{a}_i\\\|\^2} \\mathbf{a}_i \\
其中 \( \mathbf{a}_i^T \) 是系统矩阵 \( \mathbf{A} \) 的第 \( i \) 行,\( b_i \) 是对应的投影值,\( \lambda \) 为松弛因子。
3.2 统计迭代重建
统计迭代重建(如ML-EM, OSEM)将投影数据视为服从泊松分布的随机变量,通过最大化似然函数进行重建。它能有效抑制噪声,提升低剂量图像质量。
最大似然期望最大化(ML-EM)算法迭代公式为:
\ x_j\^{(k+1)} = \\frac{x_j\^{(k)}}{\\sum_i a_{ij}} \\sum_i \\left\[ a_{ij} \\frac{b_i}{\\sum_{l} a_{il} x_l\^{(k)}} \\right \]
其中 \( a_{ij} \) 是系统矩阵元素,表示第 \( j \) 个像素对第 \( i \) 条射线的贡献。
4. C++代码实现示例(FBP算法)
以下是一个简化的平行束几何FBP算法C++实现框架,展示了核心步骤。
cpp
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <fftw3.h> // 用于FFT,需链接libfftw3
/**
@brief 生成Shepp-Logan滤波核(离散Ramp滤波器加窗)
@param n 滤波器长度(应为投影数据采样点数)
@return 滤波核向量
*/
std::vector<double> generateSheppLoganFilter(int n) {
std::vector<double> filter(n);
int half = n / 2;
for (int i = -half; i < half; ++i) {
double freq = static_cast<double>(i) / half;
if (i == 0) {
filter[i + half] = 1.0;
} else {
// Shepp-Logan窗:sinc函数
filter[i + half] = std::sin(M_PI * freq) / (M_PI * freq);
}
// 乘以Ramp滤波器 |freq|
filter[i + half] *= std::abs(freq);
}
return filter;
}
/**
@brief 一维卷积(频域滤波)
@param proj 输入投影数据(单角度)
@param filter 滤波核
@return 滤波后的投影数据
*/
std::vector<double> filterProjection(const std::vector<double>& proj, const std::vector<double>& filter) {
int n = proj.size();
// 使用FFTW进行卷积(实际为频域相乘)
fftw_complex in = (fftw_complex) fftw_malloc(sizeof(fftw_complex) * n);
fftw_complex out = (fftw_complex) fftw_malloc(sizeof(fftw_complex) * n);
fftw_plan p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_plan q = fftw_plan_dft_1d(n, out, in, FFTW_BACKWARD, FFTW_ESTIMATE);
// 填充输入数据(实数转复数)
for (int i = 0; i < n; ++i) {
in[i][0] = proj[i];
in[i][1] = 0.0;
}
fftw_execute(p); // 正向FFT
// 频域滤波(乘以滤波器)
for (int i = 0; i < n; ++i) {
out[i][0] *= filter[i];
out[i][1] *= filter[i];
}
fftw_execute(q); // 反向FFT
// 取实部并归一化
std::vector<double> filtered(n);
for (int i = 0; i < n; ++i) {
filtered[i] = in[i][0] / n;
}
fftw_destroy_plan(p);
fftw_destroy_plan(q);
fftw_free(in);
fftw_free(out);
return filtered;
}
/**
@brief 反投影步骤
@param filteredSinogram 滤波后的正弦图 [角度][探测器单元]
@param imgSize 重建图像尺寸(正方形边长)
@return 重建图像矩阵
*/
std::vector<std::vector<double>> backProject(const std::vector<std::vector<double>>& filteredSinogram, int imgSize) {
int numAngles = filteredSinogram.size();
int numDetectors = filteredSinogram[0].size();
double detSpacing = 2.0 / (numDetectors - 1); // 探测器间距(归一化到[-1,1])
std::vector<std::vector<double>> image(imgSize, std::vector<double>(imgSize, 0.0));
double center = (imgSize - 1) / 2.0;
for (int angIdx = 0; angIdx < numAngles; ++angIdx) {
double theta = angIdx * M_PI / numAngles; // 投影角度
double cosTheta = std::cos(theta);
double sinTheta = std::sin(theta);
for (int i = 0; i < imgSize; ++i) {
for (int j = 0; j < imgSize; ++j) {
// 图像坐标转归一化坐标
double x = (j - center) / center;
double y = (i - center) / center;
// 计算投影坐标 t = x*cos + y*sin
double t = x * cosTheta + y * sinTheta;
// 将t映射到探测器索引
double detIdx = (t + 1.0) / detSpacing; // +1将范围从[-1,1]映射到[0, numDetectors-1]
int idx0 = static_cast<int>(std::floor(detIdx));
int idx1 = idx0 + 1;
// 线性插值
double weight = detIdx - idx0;
double projValue = 0.0;
if (idx0 >= 0 && idx1 < numDetectors) {
projValue = (1 - weight) * filteredSinogram[angIdx][idx0] + weight * filteredSinogram[angIdx][idx1];
} else if (idx0 < 0) {
projValue = filteredSinogram[angIdx][0];
} else if (idx1 >= numDetectors) {
projValue = filteredSinogram[angIdx][numDetectors - 1];
}
image[i][j] += projValue;
}
}
}
// 归一化(除以角度数)
for (int i = 0; i < imgSize; ++i) {
for (int j = 0; j < imgSize; ++j) {
image[i][j] /= numAngles;
}
}
return image;
}
/**
@brief 主函数:FBP重建流程
*/
int main() {
// 1. 参数设置
int numAngles = 180; // 投影角度数
int numDetectors = 256; // 探测器单元数
int imgSize = 256; // 重建图像尺寸
// 2. 模拟或读取正弦图数据 [角度][探测器]
std::vector<std::vector<double>> sinogram(numAngles, std::vector<double>(numDetectors, 0.0));
// TODO: 此处应填充真实的投影数据
// 3. 生成滤波核
auto filter = generateSheppLoganFilter(numDetectors);
// 4. 逐角度滤波
std::vector<std::vector<double>> filteredSinogram(numAngles);
for (int ang = 0; ang < numAngles; ++ang) {
filteredSinogram[ang] = filterProjection(sinogram[ang], filter);
}
// 5. 反投影重建
auto reconstructedImage = backProject(filteredSinogram, imgSize);
// 6. 输出或保存图像
std::cout << "FBP reconstruction completed. Image size: " << imgSize << "x" << imgSize << std::endl;
return 0;
}
代码说明:
- 该示例实现了平行束FBP的核心流程,包含滤波核生成、频域滤波和反投影。
- 使用了FFTW库进行快速傅里叶变换,需在编译时链接
-lfftw3。 - 为简化,投影数据(
sinogram)需由用户模拟或从文件读取。 - 反投影中采用了线性插值以提高精度。
5. 总结与扩展
CT重构是连接物理测量与视觉图像的关键桥梁。FBP因其速度快、稳定性好而成为临床标准,迭代法则在应对不完备数据时展现出优势。实际应用中需根据扫描几何、剂量限制和硬件条件灵活选择或融合算法。
扩展方向:
- GPU加速:反投影是计算瓶颈,可用CUDA/OpenCL并行化。
- 深度学习重构:利用卷积神经网络直接从正弦图或初步重建图像中恢复高质量图像,是当前研究热点。
- 迭代算法的优化:研究更快的收敛算法(如ADMM)以及系统矩阵的快速计算(如基于GPU的投影/反投影)。