Пример #1
0
def main():

    input_parser = InputArgparser(description="Convert NIfTI to DICOM image", )
    input_parser.add_filename(required=True)
    input_parser.add_option(
        option_string="--template",
        type=str,
        required=True,
        help="Template DICOM to extract relevant DICOM tags.",
    )
    input_parser.add_dir_output(required=True)
    input_parser.add_label(
        help="Label used for series description of DICOM output.",
        default="SRR_NiftyMIC")
    input_parser.add_argument(
        "--volume",
        "-volume",
        action='store_true',
        help="If given, the output DICOM file is combined as 3D volume")
    args = input_parser.parse_args()
    input_parser.print_arguments(args)

    # Prepare for final DICOM output
    ph.create_directory(args.dir_output)

    if args.volume:
        dir_output_2d_slices = os.path.join(DIR_TMP, "dicom_slices")
    else:
        dir_output_2d_slices = os.path.join(args.dir_output, args.label)
    ph.create_directory(dir_output_2d_slices, delete_files=True)

    # read NiftyMIC version (if available)
    data_reader = dr.ImageHeaderReader(args.filename)
    data_reader.read_data()
    niftymic_version = data_reader.get_niftymic_version()
    if niftymic_version is None:
        niftymic_version = "NiftyMIC"
    else:
        niftymic_version = "NiftyMIC-v%s" % niftymic_version

    # Create set of 2D DICOM slices from 3D NIfTI image
    # (correct image orientation!)
    ph.print_title("Create set of 2D DICOM slices from 3D NIfTI image")
    cmd_args = ["nifti2dicom"]
    cmd_args.append("-i '%s'" % args.filename)
    cmd_args.append("-o '%s'" % dir_output_2d_slices)
    cmd_args.append("-d '%s'" % args.template)
    cmd_args.append("--prefix ''")
    cmd_args.append("--seriesdescription '%s'" % args.label)
    cmd_args.append("--accessionnumber '%s'" % ACCESSION_NUMBER)
    cmd_args.append("--seriesnumber '%s'" % SERIES_NUMBER)
    cmd_args.append("--institutionname '%s'" % IMAGE_COMMENTS)

    # Overwrite default "nifti2dicom" tags which would be added otherwise
    # (no deletion/update with empty '' sufficient to overwrite them)
    cmd_args.append("--manufacturersmodelname '%s'" % "NiftyMIC")
    cmd_args.append("--protocolname '%s'" % niftymic_version)

    cmd_args.append("-y")
    ph.execute_command(" ".join(cmd_args))

    if args.volume:
        path_to_output = os.path.join(args.dir_output, "%s.dcm" % args.label)
        # Combine set of 2D DICOM slices to form 3D DICOM image
        # (image orientation stays correct)
        ph.print_title("Combine set of 2D DICOM slices to form 3D DICOM image")
        cmd_args = ["medcon"]
        cmd_args.append("-f '%s'/*.dcm" % dir_output_2d_slices)
        cmd_args.append("-o '%s'" % path_to_output)
        cmd_args.append("-c dicom")
        cmd_args.append("-stack3d")
        cmd_args.append("-n")
        cmd_args.append("-qc")
        cmd_args.append("-w")
        ph.execute_command(" ".join(cmd_args))

        # Update all relevant DICOM tags accordingly
        ph.print_title("Update all relevant DICOM tags accordingly")
        print("")
        dataset_template = pydicom.dcmread(args.template)
        dataset = pydicom.dcmread(path_to_output)

        # Copy tags from template (to guarantee grouping with original data)
        update_dicom_tags = {}
        for tag in COPY_DICOM_TAGS:
            try:
                update_dicom_tags[tag] = getattr(dataset_template, tag)
            except:
                update_dicom_tags[tag] = ""

        # Additional tags
        update_dicom_tags["SeriesDescription"] = args.label
        update_dicom_tags["InstitutionName"] = institution_name
        update_dicom_tags["ImageComments"] = IMAGE_COMMENTS
        update_dicom_tags["AccessionNumber"] = ACCESSION_NUMBER
        update_dicom_tags["SeriesNumber"] = SERIES_NUMBER

        for tag in sorted(update_dicom_tags.keys()):
            value = update_dicom_tags[tag]
            setattr(dataset, tag, value)
            ph.print_info("%s: '%s'" % (tag, value))

        dataset.save_as(path_to_output)
        print("")
        ph.print_info("3D DICOM image written to '%s'" % path_to_output)

    else:
        ph.print_info("DICOM images written to '%s'" % dir_output_2d_slices)

    return 0
Пример #2
0
def main():

    time_start = ph.start_timing()

    np.set_printoptions(precision=3)

    input_parser = InputArgparser(
        description="Perform Bias Field correction using N4ITK.", )
    input_parser.add_filename(required=True)
    input_parser.add_output(required=True)
    input_parser.add_filename_mask()
    input_parser.add_option(
        option_string="--convergence-threshold",
        type=float,
        help="Specify the convergence threshold.",
        default=1e-6,
    )
    input_parser.add_option(
        option_string="--spline-order",
        type=int,
        help="Specify the spline order defining the bias field estimate.",
        default=3,
    )
    input_parser.add_option(
        option_string="--wiener-filter-noise",
        type=float,
        help="Specify the noise estimate defining the Wiener filter.",
        default=0.11,
    )
    input_parser.add_option(
        option_string="--bias-field-fwhm",
        type=float,
        help="Specify the full width at half maximum parameter characterizing "
        "the width of the Gaussian deconvolution.",
        default=0.15,
    )
    input_parser.add_log_config(default=1)
    input_parser.add_verbose(default=0)

    args = input_parser.parse_args()
    input_parser.print_arguments(args)

    if np.alltrue([not args.output.endswith(t) for t in ALLOWED_EXTENSIONS]):
        raise ValueError(
            "output filename invalid; allowed extensions are: %s" %
            ", ".join(ALLOWED_EXTENSIONS))

    if args.log_config:
        input_parser.log_config(os.path.abspath(__file__))

    # Read data
    stack = st.Stack.from_filename(
        file_path=args.filename,
        file_path_mask=args.filename_mask,
        extract_slices=False,
    )

    # Perform Bias Field Correction
    # ph.print_title("Perform Bias Field Correction")
    bias_field_corrector = n4itk.N4BiasFieldCorrection(
        stack=stack,
        use_mask=True if args.filename_mask is not None else False,
        convergence_threshold=args.convergence_threshold,
        spline_order=args.spline_order,
        wiener_filter_noise=args.wiener_filter_noise,
        bias_field_fwhm=args.bias_field_fwhm,
    )
    ph.print_info("N4ITK Bias Field Correction ... ", newline=False)
    bias_field_corrector.run_bias_field_correction()
    stack_corrected = bias_field_corrector.get_bias_field_corrected_stack()
    print("done")

    dw.DataWriter.write_image(stack_corrected.sitk, args.output)

    elapsed_time = ph.stop_timing(time_start)

    if args.verbose:
        ph.show_niftis([args.filename, args.output])

    ph.print_title("Summary")
    exe_file_info = os.path.basename(os.path.abspath(__file__)).split(".")[0]
    print("%s | Computational Time for Bias Field Correction: %s" %
          (exe_file_info, elapsed_time))

    return 0