lungmask

repository·master·Indexed 21 days ago

https://github.com/johof/lungmask

Package for automated lung segmentation in CT scans, version 0.2.21. It provides the LMInferer class for inference and a command line tool to generate lung masks from single images or DICOM folders. The library supports various pre-trained UNet models (R231, LTRCLobes, R231CovidWeb) and allows for model fusing to improve segmentation quality, even in the presence of tumors or effusions.

Tokens
5K
Snippets
22
Records
24
Agent score
72%

What's inside lungmask

  1. Available lung segmentation models

    master

    The package provides several pre-trained U-net models depending on your requirements:

    • R231: The default model. Trained on diverse data, performs slice-by-slice segmentation, extracts right/left lungs separately, and includes air pockets, tumors, and effusions. Does not include the trachea.
    • LTRCLobes: Trained on the LTRC dataset. Segments individual lung lobes but may struggle with dense pathologies or invisible fissures.
    • LTRCLobes_R231: A fused model that runs both LTRCLobes and R231 to improve accuracy by filling false negatives and removing false positives.
    • R231CovidWeb: Optimized for COVID-19 CT scans, specifically those that may have been converted from regular image formats (non-HU).
    # Example of selecting the COVID-optimized model via CLI
    lungmask INPUT OUTPUT --modelname R231CovidWeb
  2. Process non-HU images (JPG, PNG)

    master

    If you are processing images that are not encoded in Hounsfield Units (HU), such as JPG or PNG files, you must use the --noHU flag.

    Warning: This feature is primarily supported in versions 0.2.5 through 0.2.14. When using --noHU, only single slices can be processed, and results may be unreliable if the images are heavily cropped or have significant intensity shifts, as the models were trained on proper CT scans.

    # Process a non-HU image via CLI
    lungmask INPUT OUTPUT --noHU
  3. Install lungmask

    master

    You can install the lungmask package using pip or conda. On Windows, ensure you have a torch installation with CUDA support if you intend to use a GPU for faster inference.

    # Using pip
    pip install lungmask
    # Or from GitHub
    pip install git+https://github.com/JoHof/lungmask
    
    # Using conda
    conda install conda-forge::lungmask
  4. Fuse two models for improved segmentation with LMInferer

    master

    You can improve segmentation quality by providing both a base model and a fillmodel. The LMInferer will run inference with both and fuse the results, using the fillmodel to fill in areas that the base model missed.

    When fillmodel is used, the class performs a fusion step that may take several minutes for large volumes.

    from lungmask import LMInferer
    
    # Use LTRCLobes as base and R231 to fill gaps
    inferer = LMInferer(modelname="LTRCLobes", fillmodel="R231")
    
    mask = inferer.apply(image)
  5. Configure LMInferer models and fusing

    master

    When initializing LMInferer, you can specify different models or use the model fusing capability to combine results from two different models.

    # Load a specific model (e.g., COVID-19 optimized)
    inferer = LMInferer(modelname="R231CovidWeb")
    
    # Use model fusing (e.g., LTRCLobes combined with R231)
    # This fills false negatives from LTRCLobes with R231 predictions
    # and removes false positives from LTRCLobes.
    # Note: This is computationally intensive.
    inferer = LMInferer(modelname='LTRCLobes', fillmodel='R231')
  6. Use lungmask as a Python module

    master

    You can integrate lung segmentation into your Python workflows using the LMInferer class. The apply method accepts a SimpleITK object or a numpy array.

    Numpy Array Requirements: If passing a numpy array, it must follow this axis order:

    1. Slices
    2. Chest to back
    3. Right to left
    from lungmask import LMInferer
    import SimpleITK as sitk
    
    # Initialize the inferer (defaults to U-net(R231))
    inferer = LMInferer()
    
    # Load image as SimpleITK object
    input_image = sitk.ReadImage("path/to/input.nii.gz")
    
    # Perform segmentation
    segmentation = inferer.apply(input_image)
  7. Understand segmentation label semantics

    master

    The output labels vary depending on the model used:

    Two-label models (Left-Right):

    • 1: Right lung
    • 2: Left lung

    Five-label models (Lung lobes):

    • 1: Left upper lobe
    • 2: Left lower lobe
    • 3: Right upper lobe
    • 4: Right middle lobe
    • 5: Right lower lobe
  8. Use lungmask as a command line tool

    master

    The CLI allows you to process a single file or an entire directory of DICOM series. If a directory is provided, the largest volume found (by voxel count) is used. All ITK formats are supported as output.

    To avoid CUDA out-of-memory errors, you can reduce the batch size using the --batchsize flag.

    # Basic usage (defaults to U-net(R231) model)
    lungmask INPUT OUTPUT
    
    # Specify an alternative model
    lungmask INPUT OUTPUT --modelname LTRCLobes
    
    # Reduce batch size to prevent GPU OOM
    lungmask INPUT OUTPUT --batchsize 1
  9. Preprocess CT images for segmentation

    master

    Use preprocess() to prepare a 3D CT image for the model. This function clips the Hounsfield Unit (HU) values to the range [-1024, 600], crops the image to the body, and resizes each slice to a target resolution.

    Args:

    • img (np.ndarray): The input 3D CT image.
    • resolution (list, optional): The target [width, height] for resizing. Defaults to [192, 192].
    import numpy as np
    from lungmask.utils import preprocess
    
    # Assuming img is a 3D numpy array representing a CT volume
    preprocessed_img, bounding_boxes = preprocess(img, resolution=[192, 192])
  10. Load a specific lung segmentation model with get_model()

    master

    Use get_model() to load a pre-trained UNet model for lung segmentation. If modelpath is not provided, the function will automatically download the weights from the official repository based on the modelname.

    Supported modelname values:

    • R231
    • LTRCLobes
    • R231CovidWeb

    If you provide a modelpath, the modelname argument is ignored and the weights are loaded from your local file.

    from lungmask import get_model
    
    # Download and load the R231 model automatically
    model = get_model(modelname="R231")
    
    # Or load from a local path
    model = get_model(modelname="", modelpath="/path/to/your/model.pth")
  11. Get the list of DICOM tags to preserve

    master

    Call get_DICOM_tags_to_keep() to retrieve the standard list of DICOM metadata tags that the library preserves during processing. These include StudyDate, PatientName, PatientID, and others.

    from lungmask.utils import get_DICOM_tags_to_keep
    
    tags = get_DICOM_tags_to_keep()
    # Returns a tuple of tags like ('0008|0020', '0008|0030', ...)
  12. Compute a 3D bounding box for a labelmap

    master

    Use bbox_3D() to find the spatial extent of a 3D labelmap, optionally adding a margin around the detected object.

    Args:

    • labelmap (np.ndarray): The input 3D labelmap.
    • margin (int, optional): The number of voxels to add as a margin to each side. Defaults to 2.

    Returns:

    • A flattened np.ndarray representing the bounding box as [zmin, zmax, ymin, ymax, xmin, xmax].
    from lungmask.utils import bbox_3D
    
    # bbox is [zmin, zmax, ymin, ymax, xmin, xmax]
    bbox = bbox_3D(my_label_map, margin=5)