# Synthetic CT from MRI - editing MRI segments to Hounsfield Units

**URL:** <https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351>\
**Category:** Support\
**Tags:** dicom\
**Created:** [October 26, 2021, 2:09am UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351 "2021-10-26T02:09:46Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Harsforn](https://avatars.discourse-cdn.com/v4/letter/h/85e7bf/32.png) [@Harsforn](https://discourse.slicer.org/u/Harsforn)\
**Post date:** [October 26, 2021, 2:09am UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/1 "2021-10-26T02:09:46Z")

</div>

Hi all,

I’m trying to generate a synthetic CT from an MRI for use in an MRI-only radiotherapy treatment planning approach (with SlicerRT).

I’ve segmented out bone, air, tissue, and a mock tumour from the MRI - is there a way to convert their voxel values to Hounsfield Units? This is an exploratory approach so I only need those 4 basic features in the sCT; ideally I would like to set the HU for each segment (similar to assigning label values in the ‘Model to LabelMap’ module).

Thanks for your time.

---

<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 26, 2021, 3:26am UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/2 "2021-10-26T03:26:43Z")

</div>

You can use the segmentation to change voxels of a volume of the same geometry using numpy array operations, something like this:

```python
volumeNode = getNode('MRHead')
segmentationNode = getNode('Segmentation')

segmentNames = ['bone', 'air', 'tissue', 'tumor']
voxelIntensities = [2000, -1000, 60, 150]

volumeArray = slicer.util.arrayFromVolume(volumeNode)

for segmentName, voxelIntensity in zip(segmentNames, voxelIntensities):
    # Get segment as numpy array
    segmentId = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(segmentName)
    segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId, volumeNode)
    # Update voxel of the volume
    volumeArray[segmentArray > 0] = voxelIntensity

slicer.util.arrayFromVolumeModified(volumeNode)

```

---

<div class="post-metadata">

**Author:** ![Harsforn](https://avatars.discourse-cdn.com/v4/letter/h/85e7bf/32.png) [@Harsforn](https://discourse.slicer.org/u/Harsforn)\
**Post date:** [October 26, 2021, 4:06am UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/3 "2021-10-26T04:06:45Z")

</div>

Thanks for the reply, Andras. I’m getting the following error:

```auto
Traceback (most recent call last):
File "<console>", line 3, in <module>
TypeError: arrayFromSegmentBinaryLabelmap() takes 2 positional arguments but 3 were given

```

I’ve tried limiting it to two (of those three) arguments but it errs every time. Any ideas?

---

<div class="post-metadata">

**Author:** ![PaoloZaffino](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/paolozaffino/32/81052_2.png) [@PaoloZaffino](https://discourse.slicer.org/u/PaoloZaffino)\
**Post date:** [October 26, 2021, 8:01am UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/4 "2021-10-26T08:01:24Z")

</div>

There are several AI-based algorithms for converting MRI into sCT.

However, to check quality conversion, you can use this module:  
[https://www.slicer.org/wiki/Documentation/Nightly/Extensions/ImageCompare](https://www.slicer.org/wiki/Documentation/Nightly/Extensions/ImageCompare)

Best,  
Paolo

---

<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 26, 2021, 11:45am UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/5 "2021-10-26T11:45:20Z")

</div>

> [@Harsforn](#):
>
> I’ve tried limiting it to two (of those three) arguments but it errs every time. Any ideas?

The code snippet works in recent Slicer Preview Releases. The latest Slicer Stable Release users slightly different syntax.

---

<div class="post-metadata">

**Author:** ![Harsforn](https://avatars.discourse-cdn.com/v4/letter/h/85e7bf/32.png) [@Harsforn](https://discourse.slicer.org/u/Harsforn)\
**Post date:** [October 26, 2021, 12:35pm UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/6 "2021-10-26T12:35:48Z")

</div>

Thanks for the help. I’ve downloaded the most recent preview release but I’m now getting a different error - I’ve attached a screenshot in case the problem is my structuring of the nodes/segments.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/7/a7a689184a70a312df22e2aa3e6c92f579cca97b.jpeg)

The code I’m using is:

```auto
volumeNode = getNode('101')
segmentationNode = getNode('Segmentation')

segmentNames = ['bone', 'gas', 'tissue', 'mass']
voxelIntensities = [2000, -1000, 60, 150]

for segmentName, voxelIntensity in zip(segmentNames, voxelIntensities):
    segmentId = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(segmentName)
    segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId, volumeNode)
    volumeArray[segmentArray > 0] = voxelIntensity

slicer.util.arrayFromVolumeModified(volumeNode)

```

---

<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 26, 2021, 8:50pm UTC](https://discourse.slicer.org/t/synthetic-ct-from-mri-editing-mri-segments-to-hounsfield-units/20351/7 "2021-10-26T20:50:38Z")

</div>

It seems that I’ve missed a line. Call `volumeArray = slicer.util.arrayFromVolume(volumeNode)` after setting `volumeNode`.
