I have just started using 3D slicer this month, I am new to image processing. I am trying to register the CT of a 3d-printed (Powder Bed Fusion) metal cylinder (very simple geometry, diameter = 2mm, with indents every 2mm height-wise to facilitate feature identification for registration) to the optical stack of the same part (taken with a DSLR camera during operation of the 3d printer).
The camera takes images of the powder bed in the printer (after the laser has melted it) every 30 micron, thus building a stack of slices with resolution (7 x 7 x 30 micron); the CT has resolution (2.5 x 2.5 x 2.5 micron).
To prepare for the registration I first crop all unwanted regions from both stacks (e.g. slices containing CT artifacts), rotate the CT 180° to more or less match the direction of the optical stack, and perform a first fiducial registration (Fiducial Registration module) using 10 fiducials placed at various heights on the coronal view (see screenshot).
At this point the stacks match in height, but the cross-section area (i.e. each slice) of the CT is clearly larger than that of the optical stack. The final step would ideally be a registration that allows the CT to be rescaled in x and y to match the optical stack exactly, but I am not sure how to do this. I have mostly been attempting affine and b-spline registrations with a variety of modules for this, but to no avail.
Having very little experience with image registration I am unsure of the reasons for which none of these methods work. Does 3d slicer have a module that allows for obtaining this final registration step with relative ease?
You can start the registration with an affine landmark transformation, and fine-tune it at the end with intensity based automatic image registration.
Affine landmark transformation is needed very rarely (most common are rigid and bspline, sometimes similarity), therefore this option is not exposed in most registration modules to not clutter the user interface. Currently, I think the only landmark registration module that offers affine transformation is “Landmark registration” in Slicer core. It is not very convenient for large volume differences because it automatically places the corresponding point in the corresponding image and it is tedious to move it to the correct position, but it should be still usable. Fiducial registration wizard module would be easier to use, but affine option is not exposed on its interface. Probably you only need to add 20-30 lines of code to add this option, so if you are willing to build Slicer and you understand a little C++ then it should be quite easy to add (we can help you getting started).
After you have your initial alignment (hardened the landmark transform on the moving image), I would recommend to get a refined registration using “General registration (Elastix)” module (provided by SlicerElastix extension), because it usually works with default parameter set, without any tuning.
In the end the fiducial registration wizard’s interface options were sufficient, all it took was two sets of fiducials in the axial view (one set at an indent and another set at the next indent) and the warping transformation achieved a fairly accurate result. The final registration using Elastix almost achieved a perfect registration.
I just had two more questions, if I may:
The final Elastix registration has a few misalignments, I suspect this is due to the “bubbles” in the CT volume (see screenshot below), which in reality are fused metal powder particles that do not form part of the printed part and should therefore be removed.
I have tried adding a mask to the volume such that the mask only encompasses the actual volume and not the bubbles, I can achieve this for one slice but I was hoping there might be a semi-automatic way of extending the mask to all slices (approx. 2400 in total, manually doing each would take too long).
The CT file (the moving image) is pretty large (> 1 GB) and Elastix registration requires approx. 2 hrs to complete on my laptop. Is there any way of improving the registration time? Are there any alternatives to simply downsampling the CT stack?
Apologies, I forgot to mention, I am using the Level Tracing function to semi-automatically mask the slices, since it seems to work quite well (but only for individual slices).
For affine registration, it should be enough to have a few hundred points along each axis (you would get the same registration results as on the full-resolution data set). Apply some Gaussian smoothing and then use Crop volume module with a spacing scale of 5 to 10. This will make everything about 100x faster.
To get rid of the bubbles, you can use Grow from seeds or Watershed effects to segment only the dense core of the material. You can also try Smoothing effect.