32.5. Projection Images
Table of Contents
Creating projection data
Projection images are the basic data product of a SPECT acquisition. Each projection records how many photons are detected by the gamma camera at a particular angle around the object. In GATE, you do not create a 2D image directly at the detector level. Instead, you record individual detector events, then bin these events into a projection matrix in a separate analysis step. This section focuses on how to go from simulated events to projection images, building on the concepts introduced earlier in the SPECT and gamma camera chapters.
From detected events to image coordinates
During the simulation, a SPECT detector head and collimator are rotated around the object, and an actor records information about each detected photon, typically after digitization. For projection data, the most important quantities are detection position, detection energy, detection time, projection angle, and event identifiers.
In a typical SPECT setup, the detector is modeled as a planar crystal. Each interaction in the crystal has a position in the detector coordinate system. Even if you do not explicitly define detector pixels in the geometry, you can treat the crystal as a continuous surface that will later be discretized into pixels during analysis.
To create a projection image for a single angle, you conceptually overlay a 2D grid on the detector crystal. Each grid cell corresponds to one pixel in the projection image. For each detected photon that passes your selection criteria, you determine which pixel grid cell contains its detection position and increment the count in that pixel by one.
The same principle applies if the camera rotates. For each projection angle, you construct a separate 2D grid, and you bin events detected at that angle into the corresponding grid. This results in a stack of 2D images, one per projection angle, that together form the full SPECT projection dataset.
Choosing the projection grid
Before binning, you must define how fine your projection grid will be. The grid is characterized by the number of pixels in each direction and the physical size of each pixel. These choices should be consistent with your simulated crystal dimensions and with the spatial resolution of your collimator and detector.
Consider a planar crystal of width $L_x$ and height $L_y$ centered at $(0, 0)$ in its own coordinate system. If you choose $N_x$ pixels along $x$ and $N_y$ along $y$, the pixel sizes $\Delta x$ and $\Delta y$ are:
$$
\Delta x = \frac{L_x}{N_x}, \quad \Delta y = \frac{L_y}{N_y}.
$$
You then define pixel index ranges, for example $i = 0, 1, \dots, N_x - 1$ and $j = 0, 1, \dots, N_y - 1$. A detector hit at position $(x, y)$ is mapped to indices $(i, j)$ using:
$$
i = \left\lfloor \frac{x + \frac{L_x}{2}}{\Delta x} \right\rfloor,
\quad
j = \left\lfloor \frac{y + \frac{L_y}{2}}{\Delta y} \right\rfloor.
$$
If $(i, j)$ lies inside the valid index range, you increment the count in that pixel. If it is outside, the event is ignored because it corresponds to a position outside the active area.
You do not need to perform these calculations inside GATE. Instead, you record event positions and define the grid in your analysis code, for example with Python and NumPy.
A simple conceptual mapping between detector coordinates and pixel indices is:
| Quantity | Symbol | Typical source |
|---|---|---|
| Crystal width | $L_x$ | Geometry definition |
| Crystal height | $L_y$ | Geometry definition |
| Number of pixels x | $N_x$ | Analysis choice |
| Number of pixels y | $N_y$ | Analysis choice |
| Pixel size x | $\Delta x$ | $L_x / N_x$ |
| Pixel size y | $\Delta y$ | $L_y / N_y$ |
| Hit position | $(x, y)$ | Detector or hits actor in GATE output |
| Pixel indices | $(i, j)$ | Computed in analysis |
Grouping events by projection angle
In a SPECT acquisition, the gamma camera rotates around the patient or phantom, stopping at a series of angles. In GATE, this is typically implemented with time-dependent rotation of the detector head, combined with an acquisition schedule. Each detected event can be associated with the camera angle at which it was recorded.
There are two common strategies to distinguish projection angles in the output:
You can record the global time of each event as well as the rotation schedule of the detector. In analysis, you use the time to determine which angle was active when the event was detected. For example, if you simulate 60 projections over 360 degrees and assign equal acquisition time to each angle, you can divide the total acquisition time into 60 equal intervals. Events whose detection times fall into the same interval belong to the same projection.
Alternatively, you can encode the angle directly as an attribute in the output, for example by updating a user-defined variable whenever the detector rotates to a new angle. Some users attach separate actors for different angles, but for SPECT this becomes less practical for many projections.
Once each event is tagged with a projection index $k$, corresponding to an angle $\theta_k$, you can think of your data as three dimensional: two spatial indices $(i, j)$ and one angular index $k$.
A natural representation for this is a 3D array $P[k, j, i]$, where for each projection $k$ the slice $P[k, :, :]$ is a 2D image.
Applying energy windows before binning
Real SPECT cameras apply an energy window around the photopeak to select primary photons and to reduce scatter and noise. In your simulation, you mimic this behavior by filtering events based on their detected energy before constructing the projection images.
For a radionuclide with main photon energy $E_0$, for example Tc-99m at about $140$ keV, a simple symmetric energy window with width $w$ percent is defined as:
$$
E_{\text{min}} = E_0 \left(1 - \frac{w}{100}\right), \quad
E_{\text{max}} = E_0 \left(1 + \frac{w}{100}\right).
$$
Only events with detected energy $E$ satisfying
$$
E_{\text{min}} \leq E \leq E_{\text{max}}
$$
are accepted into the main projection image.
In SPECT projection creation, always apply the energy window filter before spatial binning. This ensures that your projection counts represent the desired energy-selected photons and not the full spectrum of detected events.
If you simulate multiple windows, such as a primary photopeak window and one or more scatter windows, you typically generate a separate projection dataset for each window. This is done by repeating the binning process for events that satisfy each window condition.
Building 2D projection matrices
Once you have chosen the grid, grouped events by angle, and applied your energy window, you are ready to create the projection matrices. The steps can be summarized as:
For each projection index $k$, initialize a 2D array of zeros with shape $(N_y, N_x)$. For each event associated with angle $k$, check that its energy lies within the relevant window. If it passes the filter, compute $(i, j)$ from its detector coordinates and increment the corresponding pixel in the array. After processing all events for that angle, the array represents the projection image at $\theta_k$.
Repeating this for all projection indices produces a 3D dataset with dimensions $N_{\text{angles}} \times N_y \times N_x$.
Some analysis workflows also normalize each projection by the acquisition time at that angle, so that the pixel values represent count rates instead of raw counts. This is useful when acquisition times differ from angle to angle.
Organizing projection images as a sinogram
Although SPECT projection data are often handled as a set of 2D images, it is also convenient to organize them as a sinogram. In a sinogram, one axis corresponds to detector position along a chosen direction and the other axis corresponds to projection angle. For planar SPECT this is most natural in one dimension, but for completeness you can think of each row or column of the 2D detector array being treated as a separate 1D detector.
You can construct a sinogram by selecting a line across the detector, for example a central row of pixels, and stacking it as a function of angle. Each such line for angle $\theta_k$ forms one row in the sinogram matrix.
This representation is often used in reconstruction algorithms, but for basic SPECT projection handling it is enough to remember that projection images can be summarized along one axis to produce sinograms that are more compact and sometimes easier to visualize.
Image formats and saving projection data
After constructing your projection arrays in analysis, you need to save them in a format suitable for further processing, visualization, or reconstruction. Common formats include NumPy arrays saved to disk, simple text or CSV tables for small datasets, or medical image formats such as MHD or NIfTI when you want to reuse them in image processing or reconstruction tools.
A typical approach is to store the full 3D projection dataset as a single file where axes are organized as angle, y, x. Alongside the projection data itself, you should save metadata, including the list of projection angles, the pixel sizes in millimeters, the detector field of view, the used energy window, and the acquisition time per angle. This metadata ensures that later reconstruction steps can interpret the projection data correctly and that your results are reproducible.
Basic checks on projection images
Once your projection images are generated, it is important to perform a few simple checks before using them for reconstruction or quantitative analysis.
Visually inspect a few projections at different angles. For a point source, you should see a bright spot that moves consistently with the detector rotation. For an extended phantom, the projections should show shapes consistent with the phantom geometry and radionuclide distribution.
Check the total counts per projection as a function of angle. For a uniform cylindrical phantom and a full rotation, the total counts should not vary strongly between angles, except for geometric effects or attenuation patterns that you expect based on the phantom.
Plot the energy spectrum from the same filtered events to ensure that your energy window has been applied correctly. The projection images should be derived only from events in the correct energy range.
These checks close the loop between detector-level simulation and the creation of projection images, and they provide confidence that the data you pass to reconstruction or analysis tools accurately reflect the simulated SPECT acquisition.
Views: 13
KAHIBARO