
简介锥形束CTCBCT是口腔医学与工业无损检测中的常见成像方式其三维重建质量直接依赖重建算法的选择与工程实现。FDK算法作为圆轨道锥束扫描的标准近似重建方法自1984年提出以来凭借较低的算力需求和可接受的图像质量成为CBCT快速重建的默认方案。然而面对数百张投影数据和512³体素规模CPU串行重建往往耗时数十分钟严重制约临床与工业实时应用。借助GPU并行计算通过CUDA内核优化、纹理内存采样与cuFFT频域滤波可将重建时间压缩至数秒量级。本文从FDK的加权、滤波、反投影三步原理出发详细剖析了GPU加速的工程落地过程涵盖线程映射、内存布局、几何标定、伪影抑制环状伪影、锥束伪影、截断伪影及性能调优策略为从事三维图像重建、CT算法及GPU计算开发的工程师提供完整的实践参考。 做CBCT重建这一年多我折腾最多的就是FDK算法和它的GPU加速。要说这项目到底干了什么其实一句话就能讲清楚把口腔CBCT扫描出来的几百张锥形束投影数据用FDK算法在GPU上重建出512³的三维体数据把原本CPU上要跑半小时以上的重建过程压缩到十几秒。CBCT的FDK重建不算新东西但真正把算法落地、把性能压榨出来、再把各种伪影调顺中间坑非常多。这篇文章不是教科书复述是一个在工程里踩过坑的人把整个思路、代码结构、优化手段和排查方法完整摊开讲一次给同样在做三维图像重建、CT算法、GPU计算的朋友参考。1. 整体思路为什么CBCT重建认准FDK1.1 锥形束CT的几何特点和FDK的定位CBCT和咱们平时在医院看到的螺旋CT不一样。螺旋CT用的是扇形束加多层探测器扫描时床面连续移动重建算法走的是螺旋orbital重建那一套而CBCT用的是平板探测器X射线源发出的是一个锥形束整个照射视野是个锥体。口腔CBCT、C臂CT、工业CT大多是这个结构扫描时要么机架绕物体转一圈要么物体在机架里转一圈把各个角度的投影图像采下来然后用算法从这些二维投影里还原出三维体素灰度。FDK算法全称Feldkamp-Davis-Kress1984年提出的是锥形束CT在圆轨道扫描下的标准近似重建算法。为什么说“近似”因为锥形束的每一个探测器行其实对应的是一个倾斜的扇束不是标准平面内的扇束严格来说用二维FBP直接套是套不上去的。FDK的核心思想是把锥形束忽略成一个近似对每一行探测器数据做经典的滤波反投影只加一个与锥角有关的余弦加权和三维反投影的距离加权最终得到一个可接受的重建结果。在锥角不太大的场景下比如口腔CBCT通常锥角也就几度到十几度FDK重建的图像质量临床上是完全能接受的。这也是为什么这套算法从八几年用到现在依然是各厂商CBCT设备里做快速三维图像重建的默认选择。另外还要回答一个很多人会问的问题为什么不用迭代重建比如SART、OS-SART、ART这类迭代重建确实能处理稀疏角度、减少伪影、降低辐射剂量但代价是计算量比FDK大一到两个数量级。一个512³的体素网格跑十几轮迭代CPU算到天荒地老GPU也要好几分钟。在实际医疗设备里扫描完立刻要看到重建结果十几秒就是用户的耐心上限所以快速重建这条路上FDK基本是唯一解。迭代算法更适合剂量敏感或图像质量要求超高的场景这是后话。1.2 FDK三步流程拆解加权、滤波、反投影FDK从实现角度拆开就三步第一步是余弦加权。锥形束照到探测器边缘时射线是斜着入射的越往探测器四周走单位面积上的光子数越少。这个修正因子本质上是射线与探测器面法线夹角的余弦值对每一幅投影图的每个像素算一个权重乘上去。几何上可以写成 w(u,v) R / sqrt(R² u² v²)R是源到旋转中心的距离u、v是像素相对探测器中心的物理坐标。第二步是滤波。沿探测器行方向做一维斜坡滤波ramp filter这一步跟二维FBP里的滤波完全一样作用是对投影数据进行高频补偿不然反投影出来的图像会糊成一片。工程上一般用频域实现先对每一行做FFT乘上斜坡滤波器频率响应 |ω|再做IFFT。实际操作中还会加窗函数比如Hamming窗用来抑制高频噪声的放大。第三步是反投影。这是整个FDK里计算量最大的环节也是GPU加速的主战场。对每个体素点遍历所有投影角度根据当前角度的几何关系计算该体素在探测器上的投影坐标从滤波后的投影图里取出对应位置的数值乘上距离加权因子累加到这个体素上。所有角度累加完之后再乘一个角度步长系数就得到最终的体素灰度值。理论上核心就是这三步但真正落地时每一步都藏着无数细节。坐标符号、探测器中心偏移、体素坐标系、像素索引和物理坐标的换算任何一步错了重建出来的图像就是错位的、镜像的、糊的。我下面会把这些坑一个一个讲清楚。2. 工程架构与GPU加速方案怎么设计2.1 原始数据格式与几何标定参数做重建之前先把输入数据搞明白。不同CBCT设备导出的数据格式千差万别但核心信息是一致的投影图像张数 Nproj以及每张图对应的角度值。有些设备导出的角度是固定间隔有些是随便拍的、每个角度要单独读。探测器尺寸 Nrow × Ncol以及每个像素的物理尺寸 detPx、detPy单位是毫米每像素。几何参数SOD源到旋转中心的距离、SDD源到探测器的距离。这两个参数决定了几何放大倍数。探测器中心相对旋转轴投影的位置偏移。理想情况下旋转轴在探测器中心但实际总有偏差必须标定否则重建出来边缘重影。体素网格大小 nx × ny × nz体素尺寸 voxSize。口腔CBCT常用的是0.25mm到0.4mm的等方性体素。我这里举一个实际项目的参数例子后面所有计算量估算和性能数据都基于这个配置投影角度数360张覆盖360度探测器尺寸1024 × 768像素0.2mmSOD 500mmSDD 700mm体素网格512 × 512 × 512体素0.3mm数据精度float32把参数确定下来之后先在纸上把几何关系画一遍。直角坐标系里z轴是旋转轴xy平面是扫描平面。源在某个角度β时投影方向是确定的。体素(x, y, z)在当前角度下先算出它相对源和探测器平面的几何投影位置再决定采样坐标。这一步值得花一整天去推坐标系没统一后面全是白干。2.2 反投影为什么是绝对瓶颈算算复杂度很多人上来就用GPU但不知道GPU到底在加速什么。先把计算量算清楚才能针对性优化。反投影的计算量是体素数乘以角度数。512³ 1.34亿个体素乘以360个角度等于483亿次采样累加操作。每次操作里包含坐标计算几次乘加、纹理采样、权重修正CPU单核心一秒大概能跑几千万次这种运算算下来反投影一次要十来分钟甚至更久。加上滤波和加权虽然也不小但和反投影比是零头。具体算一下滤波是对每张投影的每一行做一次FFT1024×768的投影、360张一行1024点FFT要处理768×36027.6万行。这个量级CPU用FFTW也要几十秒GPU用cuFFT几秒就搞定。加权更简单对每个像素乘一个系数768×1024×3602.8亿次乘法GPU上一瞬的事情。所以结论很明确反投影必须放GPU而且优化重点就是反投影kernel。滤波可以顺手放GPU因为反正投影数据已经拷贝到显存了没必要来回搬。2.3 GPU方案选型CUDA、数据流和内存布局GPU加速方案我的选择是CUDA理由很朴素生态最成熟、排错资料最多、性能上限最高。如果你的显卡是NVIDIA直接用CUDA如果是AMD卡或者要跨平台OpenCL也能做但优化体验会痛苦一些。医学影像行业里NVIDIA还是主流CUDA基本是默认选项。反投影的并行策略我选择了voxel-driven也就是每个CUDA线程负责一个体素或者一条z方向的一列体素在内层循环里遍历所有角度。为什么不用ray-driven因为voxel-driven天然适合GPU的并行模型百万个线程互相独立数据访问模式固定容易做合并访存。ray-driven更适合体素稀疏的场合比如表面重建对全稠密体数据来说线程分支和遍历开销反而更大。内存布局方面有一个核心技巧把滤波后的投影数据绑定到纹理内存texture object。纹理内存自带硬件双线性插值反投影采样坐标几乎不会落在整数像素上用纹理采样能省掉手写双线性插值而且纹理cache对局部性访问友好速度提升非常明显。这一点后面还会展开。全局内存到显存的传输策略投影数据360张每张1024×768×4字节一共约1.13GB。现在主流显卡8GB显存完全够用所以一次性把投影全部拷贝到显存重建过程中不做任何Host-Device数据搬移所有步骤都在显存里流水完成。3. 实操实现三个核心步骤的关键细节3.1 预处理余弦加权和平场校正拿到原始投影数据之后不要急着做加权。先看数据有没有做过暗场、平场校准。CBCT的平板探测器每个像素的增益和偏置不完全一致如果直接用原始投影重建图像上会全是环状伪影。标准流程是暗场校正在没有X射线时采集一幅暗场图像记录每个像素的暗电流偏置后续每幅投影先减去暗场。平场校正在均匀射线场中采集一幅亮场图像计算每个像素的增益系数后续投影除以这个系数。如果设备已经出了处理好的投影可以跳过这步。但我在项目中遇到过设备导出时只做了部分校正结果重建图像上还是有细环最后在预处理链里加了一步坏像素修复统计每幅投影的异常像素点值过高或过低、与邻域偏差超过阈值用邻域均值替换这招对环状伪影的抑制很有效。余弦加权本身不复杂但坐标必须对齐。假设探测器像素索引是row、col那么像素中心的物理坐标是u (col - col_center) * detPxv (row - row_center) * detPy也就是说先要找到探测器中心索引在哪。很多数据集会给“center offset”比如探测器中心在col511.5而不是511这种0.5的偏差在重建中影响很大必须精确处理。加权乘子是 R / sqrt(R² u² v²)其中R取SOD。如果数据源给的是SDD要仔细换算加权公式里用的是源到旋转中心的距离不是源到探测器的距离。这个公式的几何意义是射线与探测器法线的夹角余弦锥束边缘的投影需要减弱权重。我在项目里把加权写成了一个独立的CUDA kernel输入原始投影输出加权后的投影。反正数据已经在显存里kernel里每个线程处理一个像素做一个乘法360张图用不了几毫秒。3.2 斜坡滤波的工程实现cuFFT和窗函数选择滤波沿探测器行方向进行也就是对每个row、每个角度对该行的col方向做一维FFT。工程实现上我用了cuFFT的批量模式。先做一个cufftPlanMany把360张投影图拉平成一个大数组每行的起点按stride算一次调用完成所有行的FFT变换。要注意的是cuFFT默认是in-place还是out-of-place、数据是否连续这些都会影响结果建议先用小数据画个波形验证正确性。频域滤波器构造也容易踩坑。斜坡滤波器的频响是 |ω|ω从-0.5到0.5归一化频率。这里有个细节FFT输出的频率分量的排列是0到Nyquist然后负频率不是从低频到高频排列的。构造滤波核时要把频率轴对齐最稳妥的办法是先在空间域构造斜坡卷积核然后用FFT变换到频域再在频域和投影行相乘。这样避免手写频率轴排列出错。窗函数方面Ramp filter直接乘会把高频噪声放得很大实际重建结果会显得颗粒感重。我试过不加窗、Hamming窗、Hann窗最终选的是Hamming窗。在口腔CBCT这种噪声不算大的场景下Hamming窗能在分辨率和高频噪声抑制之间取得平衡。如果你处理的投影信噪比很低可以考虑更平滑的窗。频域滤波的伪代码流程大概是for each projection: for each row: FFT each row - spectrum multiply spectrum by filter_spectrum (precomputed) IFFT each row - filtered projection用cuFFT实现时可以分成三步先batch FFT再数组乘法filter spectrum做广播再batch IFFT。乘法这一步我单独写了一个CUDA kernel效率和可读性都更好。还有一个容易忽略的点FFT长度。1024点输入滤波在频域相乘后IFFT理论上没问题。但如果投影边缘有突变FFT的循环卷积特性会导致行两端出现振铃。解决办法是给每行做padding比如把1024点pad到2048滤波完再裁回1024。实测下来对于口腔CBCT这种投影数据不padding的振铃在骨组织高对比边界会有可见条纹padding以后基本消除。代价是FFT时间翻倍但对整体性能影响很小。3.3 反投影CUDA Kernel线程映射、纹理采样和坐标计算反投影是整个项目最核心的部分kernel设计直接决定重建时间。下面给出这个kernel的完整思路和一份可直接参考的CUDA代码。线程映射方案用三维block遍历体素。gridDim设为(ceil(nx/blockX), ceil(ny/blockY), ceil(nz/blockZ))比如blockDim (32, 8, 4)这种配置。为什么这样分因为体素格在内存中是z轴连续布局z变化时地址连续所以z维度用连续的smallDim而x、y维度可以用更大的block这样合并访存效果比较好。我在实际项目里用的是另一种方案一个线程处理一个体素blockDim (16, 16)通过遍历z方向串行处理多个切面。这种方式的好处是每个线程的任务独立寄存器压力小适合体素规模较大的情况。具体哪种好取决于体素规模和显卡架构建议两个方案都试一下用Nsight测实际时间。坐标计算的公式需要严谨推导。约定旋转坐标系当角度β0时源在x轴正方向探测器在y轴方向这只是我项目里的约定不同实现可以不同但必须定义清楚。在当前角度β下体素坐标(x, y, z)在旋转到源所在坐标系后的坐标是t x·cosβ y·sinβ沿射线方向的分量用于计算放大率s -x·sinβ y·cosβ垂直于射线方向的分量决定探测器横向坐标源到体素沿射线方向的距离为 d R - t这里R是SOD。那么体素投影到探测器平面上的横向索引为u_det (s * SDD / d) / detPx col_center纵向索引为v_det (z * SDD / d) / detPy row_center加权因子为weight (R / d)²这个weight正是FDK的距离加权表示远离旋转中心、靠近源的体素在反投影时强度变化的修正。kernel里用纹理对象对滤波后的投影做采样。纹理坐标是float类型自然带双线性插值。注意纹理坐标原点CUDA纹理采样默认从像素中心(0.5, 0.5)开始或者用normalized coordinates要提前确认坐标系定义否则整体会偏移半个像素。参考kernel代码CUDA C__global__ void fdk_backprojection( float* volume, cudaTextureObject_t texFilteredProj, const float* __restrict__ cosAngle, const float* __restrict__ sinAngle, int nx, int ny, int nz, float voxSize, float R, float SDD, float detPx, float detPy, float colCenter, float rowCenter, int nproj, float angStep) { int ix blockIdx.x * blockDim.x threadIdx.x; int iy blockIdx.y * blockDim.y threadIdx.y; if (ix nx || iy ny) return; // 体素物理坐标原点在体素网格中心 float fx (ix - (nx - 1) * 0.5f) * voxSize; float fy (iy - (ny - 1) * 0.5f) * voxSize; for (int iz 0; iz nz; iz) { float fz (iz - (nz - 1) * 0.5f) * voxSize; float acc 0.0f; for (int p 0; p nproj; p) { float c cosAngle[p]; float s sinAngle[p]; // 旋转坐标系分量 float t fx * c fy * s; float sPerp -fx * s fy * c; float d R - t; float invD 1.0f / d; float uDet (sPerp * SDD * invD) * (1.0f / detPx) colCenter; float vDet (fz * SDD * invD) * (1.0f / detPy) rowCenter; float weight (R * invD) * (R * invD); float projVal tex2Dfloat(texFilteredProj, uDet, vDet); acc weight * projVal; } float* volPtr volume ((iz * ny iy) * nx ix); // 注意角度步长如果是弧度且投影覆盖全周需要乘(π / nproj) *volPtr acc * angStep; } }这段代码可以直接当参考但有几个前提要确认纹理对象的坐标范围和归一化模式、体素原点在网格中心还是角点、角度列表是0到2π还是-π到π。我项目里实际踩过最深的一次坑就是角度方向搞反了重建出来的牙齿左右颠倒花了半天时间排查才发现是角度符号的问题。3.4 参数选择与端到端验证跑全尺寸数据之前强烈建议先做一个小规模端到端验证。用128³体素或64³体素投影张数减到90张跑通全流程确认图像方向和几何坐标正确再上全尺寸。我每次开发新算法或换新数据格式都会先做一个仿真体膜Shepp-Logan或者简单几个椭球在CPU端生成投影、GPU端重建和原始体模对比确认误差在一个合理范围内。这一步为什么重要因为GPU kernel如果有一处坐标符号错了结果是全图错乱但程序不会报错。直接拿真实扫描数据你根本分不清是算法错了还是设备标定有问题。用仿真数据可以排除设备因素精准定位算法bug。体素尺寸的选择要平衡分辨率和显存0.3mm体素在512³网格下显存占用约0.5GB如果换0.1mm体素体素数变成1536³显存直接飙到13.8GB消费级显卡就扛不住了。口腔CBCT的结构分辨率一般在1mm以上0.25-0.35mm的体素足够再细没有临床意义反而增加噪声和计算时间。4. 性能优化实录从半小时到十几秒4.1 基线版本性能与瓶颈分析先说我项目里CPU基线的数据。单线程C实现反投影用最朴素的逐体素循环360张1024×768投影、512³体素跑完整个重建约40分钟。后来加了OpenMP多线程因为反投影的体素循环完全并行直接拉到8线程降到7分半。这个速度在开发调试阶段能忍但离临床应用差太远。GPU初版做出来后我没有直接对比总时间而是用Nsight Compute和nvprof分别profile了每个kernel的耗时。结果如下预处理加权kernel约3mscuFFT批量滤波约180ms反投影kernel约14秒其他拷贝和辅助操作约200ms反投影占了总时间的97%这就是明确的优化方向。所以后续所有优化都聚焦在反投影kernel上。4.2 三版反投影优化记录第一版反投影kernel是直接逐体素遍历角度的朴素实现每个线程处理一个体素blockDim(16,16)循环内用tex2D采样。实测约14秒。Nsight分析发现主要问题全局内存写不连续。一个warp的32个线程在x方向是连续的但if (ixnx || iyny) return之后很多线程被裁掉写体素时地址跨越很大cache利用率低。角度循环内重复计算cos、sin的索引以及SDD/detPx等倒数浪费了寄存器。第二版优化把blockDim调成(32, 8)让x方向的32个线程正好覆盖一个warp内存写尽量连续。预计算所有角度的cos、sin放进常量内存。把SDD/detPx、SDD/detPy、1/detPx、1/detPy等系数在kernel外求倒数循环内用乘法。把体素循环改成z方向用外循环对每个z切片单独启动block减少不必要的线程分支。这版优化后反投影降到9秒左右。提升不算大但方向明确。第三版是质变把内层角度循环和体素循环的嵌套顺序做了调整。原本每个线程遍历所有角度投影数据在纹理cache里基本没有复用。改成让一个block固定处理一个z切片并且block内线程在xy方向上构成一个小区域这样一个warp采样的投影坐标会落在投影图局部邻域纹理cache命中率大幅提升。使用cudaOccupancyMaxPotentialBlockSize调整block大小和寄存器占用把每个SM的占用率跑到85%以上。对体素写操作做窄行缓存在kernel里先用寄存器/共享内存累积一个小块的体素结果最后统一写回显存。不过这版代码复杂度增加不少实际收益大约在15%左右。最终反投影kernel稳定在4.8-5.6秒加上滤波和加权整体重建时间在5.5秒左右RTX 3060 12G。对比CPU单线程40分钟加速比约430倍对比OpenMP版本也有约80倍提升。4.3 实测数据对比表下面这个表是我项目里实际记录的数据显卡是RTX 3060CPU是i7-12700实现方式反投影时间加权滤波时间总重建时间备注CPU 单线程~36分钟~4分钟~40分钟朴素循环未优化CPU OpenMP 8线程~6分50秒~40秒~7分30秒反投影并行滤波用FFTWGPU 初版14秒0.2秒14.5秒朴素kernel未优化GPU 第二版9秒0.2秒9.5秒合并访存常量内存GPU 第三版5.2秒0.2秒5.6秒纹理cache优化block尺寸调整补充一个经验如果你发现总时间卡在10秒以上不要先怀疑CUDA kernel写得不好先确认数据是不是在显存里反复搬运了。我之前有一版代码在滤完波后把数据拷回CPU再拷进GPU反投影时间虽然只有5秒但总时间到16秒全浪费在PCIe传输上。多GPU之间传递数据也一样能留显存就留显存。5. 重建结果常见伪影与排查实录5.1 环状伪影最烦人的探测器问题环状伪影的表现是重建图像上以旋转中心为圆心的一圈圈同心亮环或暗环越靠近中心越密。原因基本都出在投影数据上探测器某个像素点响应异常增益偏大或偏小或者暗场、平场校正没有完全做干净。由于这个坏点在每一张投影上都是同一个位置反投影之后就会在三维空间里形成一个环形结构。排查思路分两步先在原始投影里找坏点。取几张不同角度的投影图逐像素统计均值和标准差异常像素会很明显地偏离正常分布。确认坏点后优先做校正重做暗场、平场如果坏点是硬性损伤死像素就用邻域插值修补或者做一个坏像素掩码在反投影时跳过这些位置直接插值。实话说环状伪影的根治在探测器校准层面。算法层面能做的是尽量减小影响我用过的有效手段是把坏像素掩码应用到反投影采样阶段如果采样坐标落在坏像素附近就用周围正常像素的均值。这比在投影域里替换坏点更能保持重建一致性。5.2 旋转中心偏移导致的双边缘伪影这个伪影的特征是物体边缘出现重影或双边缘像是物体轮廓被复制了一份。很多时候就是旋转中心标定不准确导致的。CBCT扫描时旋转轴在探测器上的投影不一定在探测器正中心可能偏了几个像素。如果你的重建代码里默认旋转轴在探测器中心就会出这个问题。排查方法用一个对称的小钢球或者圆柱体做标定扫描重建后观察边缘是否清晰。如果旋转中心偏了边缘会明显出现“双影”。修正方法是调整几何参数里的colCenter或rowCenter加一个偏移量。我在项目里写了一个自动搜索脚本在-5像素到5像素范围里以0.1像素为步长改变center offset重建一个小体积区域用图像锐度或对称性指标自动寻找最优值几分钟就能标定完成。要注意的是center offset的偏差除了和机械安装有关还可能和投影数据的裁剪方式有关。有些设备导出投影时会去掉边缘几行几列如果你不知道几何参数就会整体偏移。所以拿到新数据源第一件事就是确认投影图和设备原始分辨率的对应关系。5.3 锥束伪影与截断伪影FDK算法本身的局限锥束伪影是FDK算法近似性带来的固有缺陷表现在远离中心平面的切片上CT值不准结构出现拉伸或明暗不均。锥角越大伪影越明显。如果设备锥角已经很大比如超过15度靠调参数很难彻底解决只能考虑换迭代重建或者让扫描物体尽量靠近旋转中心减小有效锥角。截断伪影的成因是物体超出了探测器视野FOV投影在边缘处被硬生生截断。重建后图像边缘会出现杯状亮带或强度下沉。这种问题在口腔CBCT里其实很常见因为口腔结构的宽度经常逼近探测器FOV边界。缓解办法是在投影域做外推把截断区域向外平滑延伸但效果有限根治还是要增大FOV物理上换更大探测器或使用专门的截断抑制算法。5.4 常见问题速查表现象可能原因排查和解决重建图像整体翻转/镜像角度方向符号反了、坐标约定不一致用仿真体模确认图像方向修正旋转方向边缘重影、双边缘旋转中心偏移未标定自动搜索最优center offset同心环状伪影探测器坏点、平场校正不彻底坏点掩码、投影域插值、重做校准图像模糊、分辨率差滤波核没加窗或FFT频率轴排列错检查滤波核、用Hamming窗、padding上下层切面CT值不准锥束伪影增大SOD、减小锥角、换迭代重建图像边缘有亮带截断伪影投影域外推、扩大FOV重建速度慢、GPU占用低数据在PCIe反复搬移、kernel占用率低数据全留显存用Nsight调block尺寸CUDA报out of memory体素网格太大或投影数据过多降低体素分辨率、分批处理角度最后再说一个调试策略层面的心得。这个项目真正花时间的不是写CUDA kernel而是定位几何和标定问题。所有坐标公式、角度方向、中心偏移全部用仿真数据验证过再上真实扫描数据。我后来养成了一个习惯每改一处几何参数就重建一个很小的钢球数据验证图像方向和聚焦度一秒钟就能看出有没有问题。别一上来就直接跑全尺寸真实数据一个错位就是半小时的重建时间改起来还摸不着头脑。做CBCT的GPU加速重建本质上就是三件事把FDK的原理吃透把CUDA kernel的性能压榨到极限再把各种伪影按图索骥地解决掉。这条路走通之后同样的思路完全可以迁移到其他锥束CT重建场景——换数据格式、换设备、换GPU框架都不用动。希望这篇记录能帮你少走几个弯路。本文还有配套的精品资源点击获取