# Misalignment between Eigen Artemis DICOM image and segmentation

**URL:** https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008
**Category:** Support
**Tags:** segmentation, dicom
**Created:** [April 8, 2021, 10:09pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008 "2021-04-08T22:09:13Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 8, 2021, 10:09pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/1 "2021-04-08T22:09:13Z")

</div>

Hi,

I wanted to ask this point, that why my segmentation output during export placed at the corner of NRRD volume. Even though the volume origin is at (0.0, 0.0, 0.0).  
Below is the code that I am using to export a vtk model to a segmentation label map.

```
# Center the view
layoutManager = slicer.app.layoutManager()
threeDWidget = layoutManager.threeDWidget(0)
threeDView = threeDWidget.threeDView()
threeDView.resetFocalPoint()

usPath = "/Volumes/REC00000" 
segPath = "/Volumes/SURFRCON.vtk"

volumeNode = slicer.util.loadVolume(usPath)
prostateNode = slicer.util.loadModel(segPath)

seg = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode')
seg.SetReferenceImageGeometryParameterFromVolumeNode(volumeNode)
slicer.modules.segmentations.logic().ImportModelToSegmentationNode(prostateNode, seg)
# seg.CreateBinaryLabelmapRepresentation()

labelmapVolumeNode1 = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
slicer.modules.segmentations.logic().ExportVisibleSegmentsToLabelmapNode(seg, labelmapVolumeNode1, volumeNode)

outputpath = "/Volumes/test.nrrd"
slicer.util.saveNode(labelmapVolumeNode1, outputpath)
slicer.mrmlScene.RemoveNode(labelmapVolumeNode1)
slicer.mrmlScene.Clear(0)

```

This is the output of GetOrigin(), GetSpacing() for reference volume (volumeNode) and exported NRRD (test.nrrd) .

```
test.nrrd:(0.0, 0.0, 0.0) (0.37800000000000006, 0.37800000000000006, 1.0)
REC00000: (0.0, 0.0, 0.0) (0.37800000000000006, 0.37800000000000006, 1.0)

```

This is also the nrrd output. As you can see the segmentation map is centered in upper right corner.

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

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 10, 2021, 6:17am UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/2 "2021-04-10T06:17:42Z")

</div>

Hi @lassoan

Could you please help me with this problem?

---

<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: [April 10, 2021, 3:25pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/3 "2021-04-10T15:25:19Z")

</div>

Volume origin is defined in physical space: IJK=(0,0,0) voxel content will be whatever is in the segmentation at the physical RAS=(0,0,0) position.

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 13, 2021, 4:35pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/4 "2021-04-13T16:35:09Z")

</div>

Thank you @lassoan , I have checked my data and as you correctly mentioned, my volumeNode is in IJK coordinate and my vtk mesh file is in RAS coordinate (with different origin and pixel spacing).

I looked in the forum on how to convert RAS to IJK coordinates but could not really make it. I was wondering if there is a python example that can help me!

Another question is that should I export my vtk mesh file from RAS to IJK before ExportVisibleSegmentsToLabelmapNode or after?

---

<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: [April 13, 2021, 4:49pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/5 "2021-04-13T16:49:13Z")

</div>

You can find example to IJK\<-\>RAS conversions in the [script repository](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Get_volume_voxel_coordinates_from_markup_fiducial_RAS_coordinates).

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 15, 2021, 6:51pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/6 "2021-04-15T18:51:46Z")

</div>

Thanks @lassoan.

I could figure it out the problem and could align the volume with segmentation label map using the following piece of code (I know centering the volume in this way is not recommended but since I am just exporting the label maps to NRRD for my segmentation task, and it solved my issue):

```
# Center volume 
if center_volume:
     volumesLogic = slicer.modules.volumes.logic()
     volumesLogic.CenterVolume(volumeNode)

```

I explored my multi-frames DICOM images and I noticed that I am working with raw data. It means the DICOM header does not have the **PixelSpacing** tag, but that information stored in metadata as a private tag. When I load the images into the 3D Slicer, it automatically map the volume to a pixel spacing of **[1.0 , 1.0, 1.0] mm** and origin of **[0.0, 0.0, 0.0]**.

I was wondering if there is any way, that we can tell the Slicer to pick the Pixel-Spacing from the private tag when we load the data? I tried to resample the data but it was not a practical approach.

1. I realized, what if I add a new tag to DICOM headers of my RAW DICOMS as “PixelSpacing” and copy the information from private tag and store it as a new DICOM file, would it load on 3D Slicer correctly? I am not sure.

Best.

---

<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: [April 15, 2021, 7:14pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/7 "2021-04-15T19:14:06Z")

</div>

In general, basic image metadata, such as pixel spacing must not be stored in private tags. Unfortunately, some imaging vendors do use private tags (and it takes time to convince them to better adhere to standards) and for these cases we add DICOM plugins to retrieve and use metadata in private fields.

The `(1129, 1016)` tag is used by Eigen Artemis 3D ultrasound systems to store pixel spacing information. We already have a plugin for this device in SlicerHeart extension. All you need to do is to install SlicerHeart extension and the [DICOMUltrasoundPlugin](https://github.com/SlicerHeart/SlicerHeart/blob/master/DicomUltrasoundPlugin/DicomUltrasoundPlugin.py) will recognize this image and load it correctly.

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 16, 2021, 3:34pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/8 "2021-04-16T15:34:16Z")

</div>

Thank you @lassoan for your always support. You are correct, my images come for Eigen Artemis 3D ultrasound system.  
I have installed SlicerHeart as you said and I can see it in the list of plugins on DICOM module when I load my DICOM images. However, it does not work and it loads the data as 2D image only rather multi-frame 3D like before. When you go to volume module the origin and spacing again pointing at [1.0, 1.0, 1.0] and [0.0 ,0.0, 0.0].

I copied the python function **examineEigenArtemis3DUS** form **DICOMUltrasoundPlugin** for troubleshooting and tested manually on Jupyter. For outputSpace and OutputOrigin, it gives me the correct conversion when I give a test sample:

```
OutputSpace: [0.24960000813007, 0.24960000813007, 0.24960000813007] 
OutputOrigin: [61.90080201625736, 61.90080201625736, -36.31680118292518] 

```

I was wondering, if I can use this new OutputSpace and OutputOrigin to enforce Slicer python use them as the coordinates when I call slicer.util.loadVolume, rather than the default spacing and origin.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/f/cf36c4ab1284920d8362048dbbd43732fb9f8c76.jpeg)  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/9/599ac1e65df03ce6a274b66234b0ba16158b3709.png)

---

<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: [April 16, 2021, 3:52pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/9 "2021-04-16T15:52:31Z")

</div>

Make sure your SlicerHeart extension is up-to-date. Either install latest Slicer Stable Release and update SlicerHeart extension; or install latest Slicer Preview Release and install SlicerHeart extension.

For example, [Artemis images that are available in TCIA](https://wiki.cancerimagingarchive.net/pages/viewpage.action?pageId=68550661) load perfectly with latest Slicer Preview Release:

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

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 16, 2021, 5:44pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/10 "2021-04-16T17:44:35Z")

</div>

Hi @lassoan

I downgraded my Slicer to up-to-date stable version. To make sure everything works perfectly, I downloaded the TICA data as well.

Here is as you see: the top row is the same image that you loaded and the second row is our internal data (both Artemis).

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

One thing I noticed that when I load our own data, gets the following warning:

 ![Screen Shot 2021-04-16 at 10.26.52 AM](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/4/0/40dac1d6de027eb76a3e9180a58bee4af2a87f4e.png)

This is the metadata tag list that we have for my internal DICOM (sorry I can’t send you a sample), I thought maybe there is a difference in terms of tags naming or something else that give the warning and cause this problem in **DICOMUltrasoundPlugin**.

```
Dataset.file_meta -------------------------------
(0002, 0002) Media Storage SOP Class UID UI: Ultrasound Multi-frame Image Storage
(0002, 0013) Implementation Version Name SH: 'EIGEN_361'
(0002, 0016) Source Application Entity Title AE: 'ARTEMIS'
-------------------------------------------------
(0008, 0020) Date DA: '2015'
(0008, 0064) Conversion Type CS: 'SYN'
(0008, 0070) Manufacturer LO: 'Eigen'
(0018, 1020) Software Versions LO: '2.3.0.81'
(0018, 106a) Synchronization Trigger CS: 'EXTERNAL'
(0018, 5010) Transducer Data LO: ['Hitachi', 'Noblus', 'Hitachi C41V']
(0020, 0200) Synchronization Frame of Reference UI: Universal Coordinated Time
(0028, 0002) Samples per Pixel US: 1
(0028, 0004) Photometric Interpretation CS: 'MONOCHROME2'
(0028, 0008) Number of Frames IS: "291"
(0028, 0009) Frame Increment Pointer AT: (0054, 0080)
(0028, 0010) Rows US: 496
(0028, 0011) Columns US: 496
(0028, 0034) Pixel Aspect Ratio IS: [249, 249]
(0028, 0100) Bits Allocated US: 8
(0028, 0101) Bits Stored US: 8
(0028, 0102) High Bit US: 7
(0028, 0103) Pixel Representation US: 0
(0028, 1050) Window Center DS: "50.0"
(0028, 1051) Window Width DS: "0.0"
(0054, 0081) Number of Slices US: 291
(1129, 0010) Private Creator LO: 'Eigen, Inc'
(1129, 1002) Private tag data LO: 'EigProc67'
(1129, 1008) Private tag data DS: "0.0"
(1129, 1016) Private tag data DS: [0.24960000813007, 0.24960000813007, 0.24960000813007]
(1129, 1017) Private tag data DS: "4.0"

```

---

<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: [April 16, 2021, 7:57pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/11 "2021-04-16T19:57:10Z")

</div>

You can fix up the current plugin to make it read your images as well. It is just a Python script and you can attach a debugger to go through the code step by step to see why it is not recognized.

If that does not work for you then please acquire image of a phantom (or even an empty water tank) and send us that image.

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 17, 2021, 12:18am UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/12 "2021-04-17T00:18:48Z")

</div>

Thanks a lot @lassoan

I found the error after debugging the python code. In my Ultrasound DICOM images the PixelSpacingPrivateTag store the values as a list e.g. [0.17, 017, 017], while in TCIA data the PixelSpacingPrivateTag value is a single value e.g. 0.17. The code needs to be updated so it can consider both list and single value otherwise float () throw the error.

This was the fix that I made in the current plugin, not a very fancy way as the return of `ds[pixelSpacingPrivateTag].value` is sometimes object:

```
try:
   pixelSpacingPrivate = float(ds[pixelSpacingPrivateTag].value)
except:
   pixelSpacingPrivate = ds[pixelSpacingPrivateTag].value
   pixelSpacingPrivate = float(pixelSpacingPrivate[0])

```

I am almost there, this fix nicely solved my issue with TCIA data and STL files alignment (the one that I had problem with centering the volumes). I can’t understand why the vendors don’t follow the same standards for DICOM header, that could save alot of time.

Just one last small problem still here. My local data has gland segmentation as vtk file. If you look at the screenshot it looks like the axial/coronal/sagittal views for vtk model miss-placed. The vtk file generated originally based on the same Ultrasound volumes. Do you have any suggestion on how to correct this issue. I checked the RAS and LPS version when I load vtks but none of them correct the issue.

As I said, this problem is not exist anymore with TCIA data and they are nicely aligned.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/f/5fdee5bc87308e837a6783d627d8f4d3f853ba39.jpeg)

---

<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: [April 17, 2021, 1:08am UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/13 "2021-04-17T01:08:01Z")

</div>

If you have 3 pixel spacing values then read all 3 and set them in the volume node as x, y, z spacing. If it works well then please send a pull request. Please also add a comment that Artemis Eigen 2.3.0.81 software version generates such images.

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 18, 2021, 5:56am UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/14 "2021-04-18T05:56:28Z")

</div>

Actually, the pixel spacing values in my data are always the same. However, I set them in the volume node as x,y,z, but it gives a warning and Slicer load them with default origin and spacing. There should be a fix for this probably.

Regarding the issue that i mentioned for my local data miss-alignment, the following transformation with rotating the model [-90, 0.0, -90], aligned the vtk with Ultrasound volume. However, I wish Slicer could solve this rather than applying transformation.

I will create a pull request on Github though and report the fix for Artemis.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/8/c82c1b8f3d6b8b8e4ad2c15ecdecd38a4c8e2594.jpeg)

---

<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: [April 18, 2021, 3:31pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/15 "2021-04-18T15:31:52Z")

</div>

> [@sulaimanvesal](#):
>
> However, I set them in the volume node as x,y,z, but it gives a warning

Can you copy here the entire warning message?

> [@sulaimanvesal](#):
>
> Regarding the issue that i mentioned for my local data miss-alignment, the following transformation with rotating the model [-90, 0.0, -90], aligned the vtk with Ultrasound volume.

In medical image computing, LPS coordinate system is used most commonly (x=patient left, y=patient posterior, z=patient superior). Therefore if directions of an image or model are known relative to a patient then it makes the most sense to use this convention.

In ultrasound imaging, the probe can be placed on the patient in various orientations, so often you have no clue how image axes relate to patient axes. However, due to human anatomy, endocavity ultrasound probes are quite constrained in their insertion direction, so you can have a good approximation for image to patient matrix for a specific device. This is why the Artemis DICOM plugin applies a rotation in its IJK to RAS matrix:

> <https://github.com/SlicerHeart/SlicerHeart/blob/d8f9b6e45ddc3b869046c151210f3dae0b80eb82/DicomUltrasoundPlugin/DicomUltrasoundPlugin.py#L800-L810>

I understand that this rotation may be unexpected, but it is not arbitrary and I would encourage you to apply the same rotation matrix to the model loaded model.

The only better solution I can think of is would be if Eigen better adhered to DICOM standard and specified image axes in LPS coordinate systems in the first place.

@fedorov Are you in contact with Eigen? Do you know about this ambiguity of the spacing field content (sometimes contains one value, sometimes contains a sequence of 3 values)? Do you know if they are aware that their lack of following DICOM standard or conventions is causing trouble for users?

---

<div class="post-metadata">

### Author: ![fedorov](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/fedorov/32/14_2.png) [@fedorov](https://discourse.slicer.org/u/fedorov)
#### Post date: [April 22, 2021, 3:06pm UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/17 "2021-04-22T15:06:28Z")

</div>

> [@lassoan](#):
>
> @fedorov Are you in contact with Eigen? Do you know about this ambiguity of the spacing field content (sometimes contains one value, sometimes contains a sequence of 3 values)? Do you know if they are aware that their lack of following DICOM standard or conventions is causing trouble for users?

@lassoan no, I am not in constant contact with Eigen. I do know someone at Eigen, who may have more insight on this, and I will forward the thread. However, based on my experience, I don’t recall when vendors were eager to address this kind of issues raised by researchers. For anything to change, those should be raised by paying customers. I am afraid the reality is that 1) lack of following DICOM standard or conventions as in this example often **does not** cause troubles for **paying** users (clinical users); 2) attempts to follow the standard precisely **may** cause troubles for paying users, because the downstream systems working with the data may not be able to deal with the proper implementation of the standard.

I agree we all should keep raising those issues with the vendors. But most importantly, I hope that paying customers do this more often.

---

<div class="post-metadata">

### Author: ![sulaimanvesal](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulaimanvesal/32/10463_2.png) [@sulaimanvesal](https://discourse.slicer.org/u/sulaimanvesal)
#### Post date: [April 28, 2021, 6:11am UTC](https://discourse.slicer.org/t/misalignment-between-eigen-artemis-dicom-image-and-segmentation/17008/18 "2021-04-28T06:11:26Z")

</div>

Hi @lassoan,

Sorry for not responding as I was kinda sick for past few days. Thank you so much for detailed response.

Actually, I have solved all my issues. I found the reason behind that missalignment between the 3D Ultrasound image and mesh file after correcting the pixel-spacing and origin. For Eigen Artmeis ultrasound images, there is no tag for patient orientation information and they don’t even store it as private tag. So I needed a transformation ([0, 1, 0, 0, 0, 1, 1, 0, 0] to apply to all mesh files, and it worked well (I saw now your comment that you also pointed this out).

One more bug that I found in “DICOMULtrasoundPlugin” for Eigen Artemis function that it always takes the private tag as final output-spacing. However, in my dataset I had images that had both standard ds.PixelSpacing tag and also private tag (the values were different, and the correct spacing was the one from ds.PixelSpacing). So, for these type of the images the code should choose the default ds.PixelSpacing to correctly show the images. I have corrected in my version of plugin code, and I thought to share it here also. I am not sure, how common this can be, but for my dataset I found some cases.
