Viewing XCIST image files using ImageJ - xcist/documentation GitHub Wiki
ImageJ is a widely-used image viewer. This page is intended for users who are unfamiliar with ImageJ, and to help all users understand the specifics related to XCIST image files. ImageJ can be downloaded from here.
In XCIST, there are several types of image files:
- Input data files (e.g. some phantom-related files)
- Projections (the result of the simulation phase using CatSim)
- Reconstructed image files (the result of the reconstruction phase)
The phantom used for a particular simulation is specified in Phantom.cfg. For example, see Phantom.cfg.
There are several different phantom types, including voxelized, analytic, polygonal, and NURBS. The latter three are specified in text files, and are not applicable to this discussion. For information about XCIST's phantom types, see Phantoms and projectors.
For details about the file format for voxelized phantom files, see Phantom files: Voxelized format.
In ImageJ,
-
Select File -> Import -> Raw, browse to one of the "density" files (location depends on your installation of XCIST, but they will be under Catsim\main-master\catsim\data\phantom), and click Open. For this example, we'll view CatSim_logo.density_1.
-
In the dialog box, enter the data (which you learned from the .json file discussed in Phantom files: Voxelized format as shown, and click OK.
- You should see an image that looks like this:
- Note that the image is rotated and flipped - that's because CatSim's image file format (column, row) is different from ImageJ's expectation.
-
Select Image -> Transform -> Rotate 90 degrees Right.
-
Select Image -> Transform -> Flip Horizontally. The image should now look like this:
-
Rotate-flip shortcuts: so that you can quickly do this rotate/flip when you load XCIST images, you can add shortcuts to ImageJ:
- Plugins -> Shortcuts -> Add Shortcut, Dropdown F1, Dropdown "Rotate 90 Degrees Right", OK.
- Plugins -> Shortcuts -> Add Shortcut, Dropdown F2, Dropdown "Flip Horizontally", OK.
-
Select File -> Import -> Raw, browse to CatSim_logo.density_2 (location depends on your installation of XCIST), and click Open.
-
In the dialog box, the same data should be there - click OK.
-
Press F1, then F2. You should see this image:
You have now viewed the phantom files for input to CatSim. If you ran the example simulation that uses these, you can now view the results.
The output format depends on parameters that are specified in several configuration files (*.cfg). Four output files are produced by a typical scan: *.offset, *.air, *.scan, and *.prep, where * is the resultsName specified in Protocol.cfg, example here.
These files are always in "float" (32-bit) datatype.
*.offset and *.air are usually relatively simple, so we will focus on *.scan and *.prep. These files are "sinograms" - three-dimensional files of dimensions (NumRows, NumColumns, NumViews). *.scan files can have a very wide dynamic range, so they're generally difficult to visualize. *.prep files are usually "post-log", i.e., contain the log of the data from *.scan files. Therefore, they're easier to visualize.
Assuming that you've run the example simulation, you should find the output files in CatSim\main-master\catsim\data\phantom (below wherever you installed the code).
In Scanner.cfg, you can find the number of rows and columns:
scanner.detectorColsPerMod = 1 # number of detector columns per module
scanner.detectorRowsPerMod = 16 # number of detector rows per module
scanner.detectorColCount = 900 # total number of detector columns
scanner.detectorRowCount = scanner.detectorRowsPerMod # total number of detector rows
In Protocol.cfg, you can find the number of views per rotation, and the total number of views (which implies number of rotations):
protocol.viewsPerRotation = 800 # total numbers of view per rotation
protocol.viewCount = 800 # total number of views in scan
So for this example, the file dimensions (NumRows, NumColumns, NumViews) = (16, 900, 800).
In ImageJ,
-
Select File -> Import -> Raw, browse to the output files (location depends on your installation of XCIST, but they will be under CatSim\main-master\EXE\results). For this example, select simulation_test.prep, and click Open.
-
In the dialog box, enter the data (which you learned from the *.cfg files above) as shown, and click OK.
- You should see this image:
- You are now looking at a projection of the phantom from one angle (looking through the phantom edgewise). The vertical lines are because the phantom is constant in the Z direction; the variation in the X direction is due to the various path lengths through the features in the phantom.
- You can quickly zoom in in the image by pressing control-+. Do this five times and you should see:
- ImageJ automatically chooses a window/level. You can change it by selecting Image -> Adjust -> Window/Level. You should see this:
- click "Set", enter these, and press "OK":
- You should see:
- and the image should look like this:
- With this relatively narrow window, you can see that there is some variability along each column in the image; this is due to the noise introduced by the simulated X-ray and detector physics.
You can move the "Level" slider in the "W&L" dialog box to vary the brightness - this will allow viewing the noise along each column.
-
Until now, you have been looking at one projection from an angle midway through the scan. To review other projections, move the slider at the bottom of the image window.
-
You can save a video of the projections: File -> Save as -> AVI. Here is the video I saved. You should be able to download it and view it with your computer's video viewer.
- As you can see, it saved the entire un-zoomed images - not very interesting, because the pixels are too small.
- So, you can crop the entire stack of projections. First, drag a rectangle over the zoomed image (note the yellow boundary in this image:
- Then select Image -> Crop.
- Make another video, but use a faster playback speed:
Here's what I got. Voila!
These files are always in "float" (32-bit) datatype.
In XCIST, reconstructed images are stored individually; therefore, only the XY matrix size is required to view the images. However, it is often helpful to review an entire image "stack" and scroll through the slices. Therefore, to read in a reconstructed dataset, we want to know the XY matrix size and the number of slices.
In the XY direction, the standard matrix size for reconstructed diagnostic clinical CT images is 512 x 512 pixels. However, for other types of CT systems (e.g., micro-CT, breast CT, and non-destructive testing), other matrix sizes are commonly used. In the Z direction, the number of slices varies widely, depending on number of detector rows (typically 16 to 256 in modern clinical CT systems) and scan type (e.g., single-rotation axial, step-and-shoot axial, "cine" axial, and helical). Therefore, these parameters must be specified at reconstruction time and known when reading a reconstructed dataset.
Once we read in images, most visualization tools (including ImageJ) permit scaling to the actual voxel size. For a reconstructed image, the voxel size in the XY (in-plane) direction is determined by the reconstructed field of view (FOV) divided by the matrix size. In the Z direction, the voxel size (slice thickness) is specified directly. These parameters are specified in Recon.cfg:
recon.fov = 300.0 # diameter of the reconstruction field-of-view (in mm)
recon.imageSize = 512 # number of columns and rows to be reconstructed (square)
recon.sliceCount = 1 # number of slices to reconstruct
recon.sliceThickness = 1.0 # reconstruction inter-slice interval (in mm)
Background information: The detector's pixel dimensions are specified at the detector. At isocenter (the center of rotation of the scanner), the resulting "native" voxel size is determined by the scanner's geometric magnification, which is the source-to-detector distance (SDD) divided by the source-to-isocenter distance (SID). All the relevant parameters are specified in Scanner.cfg:
scanner.sid = 540.0 # source-to-iso distance (in mm)
scanner.sdd = 950.0 # source-to-detector distance (in mm)
scanner.detectorColSize = 1.0 # detector column pitch or size (in mm)
scanner.detectorRowSize = 1.0 # detector row pitch or size (in mm)
The "native" voxel dimensions at isocenter are the pixel dimensions at the detector divided by the geometric magnification. For this example, M = SDD/SID = 950 mm/540 mm = 1.76, and the "native" voxel dimensions at isocenter are 1.0 mm/1.76 = 0.57 mm.
A reconstruction can be done using the native voxel size, but it doesn't necessarily need to be that, and a slightly larger voxel size could be chosen to maintain the scanner's native 500-mm FOV (the native FOV is determined by the detector geometry and the SDD, and is 500 mm for this example scanner).
However, for this recon, a 300-mm FOV was chosen, to zoom in on the phantom, which is approximately 220 mm in diameter. The resulting pixel size in the reconstructed image is 300 mm / 512 pixels = 0.586 mm/pixel.
XCIST's reconstruction tools have been implemented, but we are currently in the process of integrating and testing these. Therefore, The example that you ran did not produce reconstructed images. However, we provided an example image for review (reconstructed by Mingye, using the projections that you reviewed and a "manual" reconstruction tool).
In ImageJ,
-
Select File -> Import -> Raw, browse to the output files (location depends on your installation of XCIST, but they will be under CatSim\EXE\results). For this example, select simulation_test_512r512s16.raw, and click Open
-
In the dialog box, enter the data (which you learned from the *.cfg files above) as shown, and click OK.
- Assuming that you installed the ImageJ rotate-flip shortcuts, press F1, then F2. You should see this image:
- Note that the size of the CatSim logo appears to be smaller than that of the original phantom in the above figures. That is due to the choice of a 300-mm FOV. If a 220-mm FOV had been specified, they should have appeared identical in size. However, the choice of a 300-mm FOV provides the opportunity to evaluate the geometric scaling of the entire simulation & reconstruction process.
- Using ImageJ, you can compare the size of the logo in the original phantom with the size of the logo in the reconstructed image by scaling both images to mm using Image -> Properties. You can then measure the same feature in each image using ImageJ's line tool. I found the images to be in close agreement (below). This isn't perfectly precise due to the manual line drawing, but it's reasonable confirmation that the entire simulation chain is working correctly from a geometric perspective.