LION.operators.ct.ct_utils¶
Functions
|
Converts an image in Hounsfield Units into (approximate) mass density in g/cm^3, linearly: air (-1000 HU) -> 0.0012, water (0 HU) -> 1.0137, 500 HU -> 1.52. |
Converts an image in Hounsfield units into a material index: 0 air (< -950), 1 lung [-950, -750), 2 bronchi [-750, -150), 3 fat [-150, 0), 4 muscle [0, 150), 5 bone marrow [150, 300), 6 bone (>= 300). |
|
|
Linear attenuation coefficient mu = density * (mu/rho), per length unit (default 1/mm, as LION geometries are in mm), with |
|
Converts image in Hounsfield Units (air-> -1000, bone->500) into a [0-1] image. |
|
Adds realistic noise to sinograms (see _sinogram_add_noise), with or without gradients. |
- LION.operators.ct.ct_utils.from_HU_to_density(img)[source]¶
Converts an image in Hounsfield Units into (approximate) mass density in g/cm^3, linearly: air (-1000 HU) -> 0.0012, water (0 HU) -> 1.0137, 500 HU -> 1.52. Real tissue is closer to bilinear (bone is denser per HU); this is the conversion LION uses for its simulated datasets. Commercial scanners use a piecewise linear function. STIR has scanner-specific bilinear conversions from HU to attenuation (for PET/SPECT attenuation correction, so at those photon energies): https://raw.githubusercontent.com/UCL/STIR/85cc1940c297b1749cf44a9fba937d7cefdccd47/src/utilities/share/ct_slopes.json
- LION.operators.ct.ct_utils.from_HU_to_material_id(img)[source]¶
Converts an image in Hounsfield units into a material index: 0 air (< -950), 1 lung [-950, -750), 2 bronchi [-750, -150), 3 fat [-150, 0), 4 muscle [0, 150), 5 bone marrow [150, 300), 6 bone (>= 300). Returns a new uint8 array/tensor; the input is not modified. May require some image filtering preprocessing
- LION.operators.ct.ct_utils.from_HU_to_mu(img, mass_attenuation=None, length_unit_cm=0.1)[source]¶
Linear attenuation coefficient mu = density * (mu/rho), per length unit (default 1/mm, as LION geometries are in mm), with
mass_attenuationthe mass attenuation coefficient mu/rho in cm^2/g (e.g.WATER_MASS_ATTENUATION[80], from the NIST tables cited there: water-equivalent, monochromatic).Without
mass_attenuationit returns the density (g/cm^3) offrom_HU_to_density, as it did before October 2026 (when its docstring called that the attenuation).
- LION.operators.ct.ct_utils.from_HU_to_normal(img)[source]¶
Converts image in Hounsfield Units (air-> -1000, bone->500) into a [0-1] image. Comercial scanners use a piecewise linear function. Check STIR for real values. (https://raw.githubusercontent.com/UCL/STIR/85cc1940c297b1749cf44a9fba937d7cefdccd47/src/utilities/share/ct_slopes.json)
- LION.operators.ct.ct_utils.sinogram_add_noise(proj, I0=1000, sigma=5, sigma_blur=0.3015, ks_value=3, flat_field=None, dark_field=None, enable_gradients=False, model='physical', detector='energy_integrating', mass_attenuation=0.1837, length_unit_cm=0.1, min_counts=1.0)[source]¶
Adds realistic noise to sinograms (see _sinogram_add_noise), with or without gradients.
modelsays how the line integralsprojbecome attenuation, i.e. whatI0means:"physical"(default):projare line integrals of a density image (g/cm^3, e.g. fromfrom_HU_to_density) inlength_unit_cm(0.1: mm, as LION geometries), and the transmission is exp(-mass_attenuation * proj * length_unit_cm), withmass_attenuationthe mu/rho of water in cm^2/g (defaultDEFAULT_MASS_ATTENUATION, water at 80 keV; monochromatic, water-equivalent).I0is the number of photons per detector pixel in vacuum, as in XCIST, and larger objects get noisier data, as in a scanner."relative":projis divided by the maximum of each sample, so the most attenuating ray always keeps e^-1 of I0, whatever the object and its units. LION’s model before October 2026 (mass_attenuationunused).
The returned sinogram has the units of
projin both cases. The physical model only makes sense for density line integrals in the given length unit (as LION’s simulated experiments produce, seect_experiments); for sinograms in other units, usemodel="relative".detector:"energy_integrating"(default; most clinical scanners): Poisson photon counts, detector cross-talk (a Gaussian blur of stdsigma_blurpixels along the detector) and Gaussian electronic noise of stdsigmaphotons, as in XCIST."photon_counting": the Poisson photon counts themselves. The energy threshold rejects electronic noise, sosigmaandsigma_blurare not used, and the counts are integers >= 0. Charge sharing, pulse pile-up and energy resolution are not modelled.
min_counts: the detector signal (photons plus electronic noise, the dark field subtracted) can be 0 or negative when a ray gets (almost) no photons, and the log needs a positive value. Signals belowmin_counts(in photons; default 1) are set to it, so a starved ray reads as at most log(I0 / min_counts) of attenuation. None: LION’s old rule, signals <= 0 become 1e-6, i.e. log(I0) + 13.8, far beyond any real attenuation, which turns starved rays into strong streaks. It only matters when rays are starved, so in practice only with the physical model. A photon-counting detector’s signal is never negative, but it can be 0.LION’s noise before October 2026 was the relative model with three errors, since fixed and not kept as an option (Ander, 25 Oct 2026): detector cross-talk blurred across neighbouring angles as well as detectors, the attenuation scaled by the maximum of the whole batch, and the 1e-6 rule.