# Linking lung nodules across CT scans using nodule centroid anatomical coordinates

**URL:** <https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823>\
**Category:** Support\
**Tags:** segmentation, dicom\
**Created:** [October 17, 2019, 9:36pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823 "2019-10-17T21:36:23Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [October 22, 2019, 8:16pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/21 "2019-10-22T20:16:32Z")

</div>

This is a longer explanation of what Andras already said.

Download MRBrainTumor1 and 2 from sample data. Create a Fiducial (markup) on the edge of the left ventricle of the Tumor2. Note point is not on the edge of the ventricle in Tumor1 dataset.

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/a/ca3170b3cefc6fdee255ddba331b08e661a8f48a.png)

Switch to General Registration(Brains) module. Set Tumor1 as fixed, Tumor2 as moving. Choose all registration options including bspline. Expand **Expert Only Parameters** and create an Output Transform. This helps you concatenate the linear and non-linear portions of the transformation into a single transform that you can apply to markups and volumes.

When you execute this flow, Tumor2 will be put under the Output Transform but not the point. If you add the F to the output transform you can now see it lining up on the edge of the ventricle for both Tumor1 and Tumor2.

I am sure you can do all this with Elastix as well, I am not very familiar with it.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 22, 2019, 8:46pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/22 "2019-10-22T20:46:44Z")

</div>

> [@matt-warkentin](#):
>
> Would it be more reliable to see how much voxel intersection there is between the original mask and the transformed mask, rather than fuzzy matching the transformed centroid coordinate?

You can transform volumes, markup fiducial points, segmentations, models, etc. the same way, using Transforms module (see documentation and/or demo video at [Documentation/Nightly/Modules/Transforms - Slicer Wiki](https://www.slicer.org/wiki/Documentation/Nightly/Modules/Transforms)) or using Data module (double-click on the transform column in the row of the node that you would like to transform).

Once you have the aligned segmentations, you can use “Segment editor” module’s “Logical operators” effect to compute intersection of each segment pairs and then use “Segment statistics” module to get the volumes of the intersecting regions. This is of course very tedious to do manually (using the GUI), so if you confirmed that everything works well then it is worth writing a short Python script to automate it. There are many code snippets in the [script repository](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Segmentations) that you can combine/modify to get what you need.

---

<div class="post-metadata">

**Author:** ![matt-warkentin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/matt-warkentin/32/4962_2.png) [@matt-warkentin](https://discourse.slicer.org/u/matt-warkentin)\
**Post date:** [October 23, 2019, 3:04pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/23 "2019-10-23T15:04:13Z")

</div>

Thanks @muratmaga and @lassoan. This is very helpful.

I think I am very close to getting my test example to work using the GUI. I am stuck on getting the intersection of the transformed binary mask and the baseline/fixed mask. I used the `Elastix` extension to get the transformation of the follow-up scan to the baseline geometry. Then I applied the transformation to the binary mask in the `Data` module as you described. Upon visual inspection, I can now see the two masks are closely aligned.

Using the `Segment Editor` I then `Create new Segmentation`. Then using the `Master volume:` option I `Add` both of the masks. I then selected `Logical operators` and the `intersect` operation. In the upper box I selected one mask, and in the lower box (`Intersect with segmet:`) I selected the second mask and hit apply. However, nothing seems to happen, and `Segment Statistics` produces an empty table for the resulting segmentation. Am I using the logical operators wrong? It feels like it.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 23, 2019, 5:33pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/24 "2019-10-23T17:33:35Z")

</div>

You need to _harden the transform_ on the segmentation to apply the transform permanently (even if you copy/move segments to another segmentation).

When you apply intersection operation do you see that the non-overlapping part of the segment disappears?

---

<div class="post-metadata">

**Author:** ![matt-warkentin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/matt-warkentin/32/4962_2.png) [@matt-warkentin](https://discourse.slicer.org/u/matt-warkentin)\
**Post date:** [October 23, 2019, 8:45pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/25 "2019-10-23T20:45:59Z")

</div>

So I was eventually able to get it working. I had to harden the transform, as you mentioned. The other issue was that I was loading in the binary label maps (`.nrrd` files) as volumes (and selecting the `LabelMap` option). Once I changed the `Description` to `Segmentation`, I was able to intersect the two nodules and use the `Segment Statistics` module to generate volume statistics.

I don’t think I’m entirely clear on whether I should load binary label maps as `Volumes` with the `LabelMap` or whether they should be loaded as `Segmentations`.

The overlap fraction (`intersection volume / min(nodule1_volume, nodule2_volume) * 100`) was rather low (~8%). This, of course, could be the result of two segmentation masks that do not overlap much, but could some of this be attributable to poor CT registration?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 23, 2019, 10:08pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/26 "2019-10-23T22:08:02Z")

</div>

> [@matt-warkentin](#):
>
> I was eventually able to get it working

Awesome.

> [@matt-warkentin](#):
>
> whether I should load binary label maps as `Volumes` with the `LabelMap` or whether they should be loaded as `Segmentations` .

If you use Segment Editor module to process these images then it makes sense to load them as segmentation nodes directly.

> [@matt-warkentin](#):
>
> could be the result of two segmentation masks that do not overlap much, but could some of this be attributable to poor CT registration?

You can fade between the registered CT volumes to verify how well they are aligned.

If you find that overlap volume is not a sensitive enough metric then you can also compute average distance from each segment. To do this, export one segment to a labelmap and use Simple Filters module to generate distance map image. Then use Seent statistics module with the distance map as input scalar volume to get average distance. You may also use Segment Comparison module to compute overlap and diatance between segments.

---

<div class="post-metadata">

**Author:** ![matt-warkentin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/matt-warkentin/32/4962_2.png) [@matt-warkentin](https://discourse.slicer.org/u/matt-warkentin)\
**Post date:** [October 24, 2019, 7:34pm UTC](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823/27 "2019-10-24T19:34:40Z")

</div>

So I think I was able to follow your instructions to compute the average distance metric.

1. I imported one binary label map as a label map; and imported one binary label map as a segmentation node (I hardened the transform to this segmentation).

2. I used the `Simple Filters` module and chose the filter `ApproximateSignedDistanceMapImageFilter` and selected the label map as the input volume. I created a new output volume for this distance map.

3. I then used the `Segment Statistics` module with the segmentation node as the `Segmentation`, and the distance map as the `Scalar volume`. I was able to produce a table with several statistics including a `Mean` of 1.74.

I am not entirely sure on how to interpret this number in absolute terms, but I have to think smaller numbers indicate shorter distances, and vice versa.

1. Lastly, I went back a re-imported the first binary label map as a segmentation node directly. I then used the `Segment Comparison` module to compare the nodes. I obtained some Hausdorff distance metrics (`Max: 3.6, Min: 1.9, 95% 3.1`) and Dice similarity metrics (e.g. `Coef: 0.067, Ref center: (126,-38,-167), Compare center: (127,-35,-167), Ref volume: 0.06, Compare volume: 0.05`).

I suppose I could use any number of metrics to make a determination on whether they are the “same” nodule.

Sorry for the long write-up. I am partly documenting my steps for my own sake, but also in case this is useful for anyone who stumbles upon this thread in the future.

[Previous page](https://discourse.slicer.org/t/linking-lung-nodules-across-ct-scans-using-nodule-centroid-anatomical-coordinates/8823.md?page=1)
