/CT_Images

Primary LanguagePython

CT DICOM Images

  1. select a folder containing DICOM images

    We walk the folder and organize DICOM images by a 4-level hierarchy patient/study/series/instance.

    It's inspired from The Structure of DICOMDIR and Read DICOM directory.

    DicomFolder is should have a similar API as DicomDir.

    Note: In pydicom 1.4, it does not support creating DICOMDIR and the feature will be introduced in future version (2.0). The example of reading DICOMDIR uses the DICOMDIR generated by dcmtk.

  2. render DicomFolder as tree view

    This version is using PySimpleGUI-tkinter port to show tree view.

    Note: In Mac, the Apple-supplied Tcl/Tk 8.5 has serious bugs, so try to cirvumvent the Apple-supplied Pythons. Instead, install and use a newer versions of Pythons. To check which Tck/Tk version is,

    python -m tkinter -c 'tkinter._test()'

    Reference:
    Tcl/Tk: IDLE and tkinter with Tcl/Tk on macOS
    Tcl/Tk Binary installers
    Install python by pyenv w/ tcl/tk on MacOS 10.14.6 (Mojave)
    PyEnv Python installation steps to get the latest tcl/tk version on Mac OS 10.14.6 (Mojave)

    PySimpleGUI-tkinter port:
    PySimpleGUI
    Tree Element

    QT QML Treeview:
    Tutorial Qt Creator - QML - TreeView
    empty TreeView in QML from jsonModel
    TreeModelFromJSONApp
    QML TreeView
    Create Model for QML TreeView
    Qt qml treeview 树控件
    QML 自定义树控件(TreeView 的 style 加上节点可拖动)
    QT QWidget Treeview:
    PyQt5 Treeview

  3. select a Series and enter Viewer

    • first run the algorithm at background worker and get the analysis
    • have standard DICOM viewer features
    • overlay the analysis to instance, render ROI in timeline

Usage

Requirement: Python 3.7+, pipenv

pipenv run ./app.py
# OR
pipenv shell
./app.py

DICOM CT Images Sorting

How the DICOM CT images should be sorted is ultimately dependent on the usage context, but as a rule of thumb I would recommend that you first group the images based on (patient), study and series using these tags:

(0010,0020)  Patient ID
(0020,000D)  Study Instance UID
(0020,000E)  Series Instance UID

To sort the images within one series, you could use the Instance Number (0020,0013), although there is no guarantee that this value is set since it is a type 2 attribute.

Another alternative is to use the Image Position (Patient) (0020,0032), which is mandatory in CT images. You would need to check the Image Orientation (Patient) (0020,0037) to decide how to sort on position. Often CT image orientation is (1,0,0), (0,1,0), and then the Z (third) component of the image position can be used as the basis for sorting.

If the series also contains a localizer image, this image would have to be excluded from positional sorting.

TODO

  • DicomFolder only have children while DicomDir has patient_records
    rename children by patient_records in DicomFolder

  • Do not show instances in tree see comments in Run event
    our business logic should be seperated from UI data structure
    (meaning that our own data structure should support our business logic's need)
    the last param in tree node is user data, we now insert a complete Series data to it

  • remove Browse button, automatically doing Scan job after Scan button to select a folder
    with enable_events=True in InputText
    ideally selecting the same folder should not trigger "Scan"?
    however the folder might have files added or deleted, which means Scan job is needed.

  • double click on tree to trigger "View"
    this is better than right click menu, which is quite buggy and non-standard

  • add progressing when doing Scan job
    used OneLineProgressMeter element

  • mock running an algorithm function in main thread after triggering View
    show progress by using yield
    no need to use a background thread to run in this application?
    because:

     1. it has a progress bar
     2. inference is always fast(<1s)?
     3. the main thread GUI does not need do other jobs or show other things due to progress bar already existing
    
  • create a viewer window (the second window) after running an algorithm
    only 1 viewer window is visible and available at a time
    both main window and viewer window are active at the same time
    change to support only 1 active window? hide the main window after opening viewer window, close the viewer window will show main window?

  • implement Viewer
    Use sg.canvas.TkCanvas(): tk.canvas to render DICOM pixel data
    Viewing Images — pydicom 1.4.1 documentation
    The Tkinter Canvas Widget

  • add cache for analysis result to avoid running algorithm for same series

  • decouple the code better