Converting DICOM to NRRD on Docker via a Python script

Hello, I would like to start off thanking all of you for the great work with 3D Slicer. It is truly a phenomenal piece of software! The issue we are having requires some description, so I will split this question into two main sections.

1) Setup

I am working on a containerized application to perform some processing of DICOM images, and part of the pipeline involves first converting the DICOM files into an .nrrd file. Performing the conversion must be done via the 3D Slicer interface for a very particular reason (this a hard requirement for us for the time being). Therefore in order to be able to do it, we wrote a short python script to perform this conversion. The script is as follows (I have omitted part of the code related to parsing the CL arguments):

import sys
import argparse
import slicer

import DICOMLib.DICOMUtils as utils
import DICOMScalarVolumePlugin


def main():
    input_arg = sys.argv[1]
    output_arg = sys.argv[2]

    with utils.TemporaryDICOMDatabase() as db:
        utils.importDicom(input_arg, db)
        patient = db.patients()[0]
        study = db.studiesForPatient(patient)[0]
        series = db.seriesForStudy(study)[0]
        files = db.filesForSeries(series)
        reader = DICOMScalarVolumePlugin.DICOMScalarVolumePluginClass()
        loadable = reader.examineForImport([files])[0]
        node = reader.load(loadable)
        slicer.util.saveNode(node, output_arg)


if __name__ == '__main__':
    main()
    sys.exit(0)

We are able to run this without issues using a Windows 3D Slicer executable via the command line, as described here.

Since this needs to be done in Docker, we are using the slicer-notebook image provided by @lassoan as a testing environment. This the Dockerfile that we are using for this purpose:

FROM lassoan/slicer-notebook:2021-10-15-b3077c2
WORKDIR /app

COPY dicom2nrrd.py .

2) The Problem

The problem arises when trying to execute this script, as we have attempted to do it in two different ways, each yielding a different error.

Using the Executable

This is similar to this example:

/home/sliceruser/Slicer/Slicer --no-splash --no-main-window --testing --python-script /app/dicom2nrrd.py --input /app/dicoms/ --output /app/temp_nrrd.nrrd

The error message:

qt.qpa.xcb: could not connect to display :10
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: xcb.

We have seen that others had a similar issue before (1, 2) but the proposed solutions (installing the xinerama0 package) unfortunately did not work.

As an alternative, we also tried launching the script directly from 3D Slicer’s Python environment.

Using the Python environment

This is the command used:

/home/sliceruser/Slicer/bin/PythonSlicer  /app/dicom2nrrd.py --input /app/dicoms/ --output /app/temp_nrrd.nrrd

The error message:

Traceback (most recent call last):
  File "/app/dicom2nrrd.py", line 7, in <module>
    import DICOMLib.DICOMUtils as utils
  File "/home/sliceruser/Slicer/lib/Slicer-4.13/qt-scripted-modules/DICOMLib/__init__.py", line 1, in <module>
    from .DICOMProcesses import *
  File "/home/sliceruser/Slicer/lib/Slicer-4.13/qt-scripted-modules/DICOMLib/DICOMProcesses.py", line 3, in <module>
    import qt
  File "/home/sliceruser/Slicer/bin/Python/qt/__init__.py", line 19, in <module>
    from PythonQt.private import QObject
ModuleNotFoundError: No module named 'PythonQt'

Scripts which do not result in the program attempting to import qt work without any issue, but as soon as we include modules which do depend on qt (in this case the DICOMProcesses module) we end up with this error message.

We have tried many different possible solutions, including building the containers described here as-is, as well as explicitly installing the dependencies and extracting the Slicer build manually, but we still encounter the same error. For more information, we are using Windows machines running Docker Desktop to perform these tests.

We would greatly appreciate any help on this, or at least some clarification on the origin of these errors, and possible solutions. Thank you very much!

1 Like

Have you tried calling Slicer like this?

You can run arbitrary Slicer python scripts in virtual X server with this command template:

p.s. for many dicom to nrrd conversion tasks you can also consider dcm2niix, which is much faster if that’s the only feature you need.

I met the same error :sob: :sob: :sob:But I want to convert RTStruct file to .vtp file, who could help me, thanks a lot

There’s a batch struct conversion script in SlicerRT that could be run in docker using a similar formula. Be aware that RTStruct can be a tricky format due to variable vendor compliance issues, but SlicerRT is generally good at handling most cases.

At first, thanks for your reply :slightly_smiling_face:

I think this problem has nothing to do with “RT to .vtp” or “dicom to nrrd”, the problem is we cannot use slicer python script on docker. :sob:

Hi there, apologies for the very late reply, but this suggestion put us on the right track towards solving this issue. Many thanks!

1 Like