llnl / llnl/LEAP

segmented artifacts along the Z-axis with a periodicity equal to the pitch in helical CT

Open
#196 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Cuda
Stars
249
Forks
37
PR merge metrics
No merged PRs in 30d

Description

Why does reconstruction using the Leap helical CT projection map produce segmented artifacts along the Z-axis with a periodicity equal to the pitch? The code is as follows:

import numpy as np
import cv2
from skimage.transform import resize 
from skimage.data import shepp_logan_phantom

# simulate 3D data
phantom = shepp_logan_phantom()
phantom = resize(phantom, (1024, 1024))
phantom_vec = np.zeros([432, 1024, 1024])  
for i in range(24,406):
    phantom_vec[i, :, :] = phantom 
    
#params
ViewNum = 720
det_row_count = 32
det_col_count = 864
detector_spacing_x = 1.06 
detector_spacing_y = 1.12
px_of_one_det = 32
sod = 630 
odd = 340
absolute_pitch = 12.0 # mm/circle
helical_pitch = absolute_pitch / (detector_spacing_y  * det_row_count  * sod / (sod + odd))
print(helical_pitch)

#Leap setting
from leapctype import *
leapct = tomographicModels()
volume_section_num_per_circle = 24
circle_num = 20

angles = leapct.setAngleArray(circle_num * ViewNum, 360.0*circle_num) 
leapct.set_conebeam(circle_num * ViewNum, det_row_count, det_col_count, detector_spacing_y, detector_spacing_x, 0.5*(det_row_count-1), 0.5*(det_col_count-1), angles, sod, sod + odd)
leapct.set_curvedDetector()

voxel_height = abs(absolute_pitch / volume_section_num_per_circle)
print(f'slice thick:{voxel_height}')
leapct.set_normalizedHelicalPitch(helical_pitch)

volume_section_num = volume_section_num_per_circle * (circle_num - 2)
leapct.set_volume(1024, 1024, volume_section_num, voxelWidth=0.5, voxelHeight=voxel_height)

#project
g = leapct.allocate_projections()
print(g.shape)
leapct.project(g,phantom_vec.astype(np.float32))

#back project
res = leapct.FBP(g)

the following code shows segmented artifacts:

import matplotlib.pyplot as plt
slice_height, slice_width = res.shape[0], res.shape[1]  
dpi = plt.gcf().dpi
fig = plt.figure(figsize=(slice_width / dpi, slice_height / dpi))
ax2 = fig.add_subplot(1, 1, 1)
ax2.imshow(res[:, :, 256], vmin=np.max(res[:, :, 256]) * 0.9, vmax=np.max(res[:, :, 256]), cmap='gray')
plt.show()
plt.close(fig)
Image

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the artifact with the provided Python snippet, starting at the helical geometry setup and the leapct.project and leapct.FBP entry points. Check the relationship between set_normalizedHelicalPitch, detector geometry, volume_section_num_per_circle, and voxelHeight, then compare the reconstructed slices with the expected uniform phantom. Done means identifying the cause and documenting or correcting the relevant behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-vision
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.