Skip to content
Snippets Groups Projects
Commit 4ef0e02b authored by Tamino Huxohl's avatar Tamino Huxohl
Browse files

move file conversion into one script

parent 8d9f7577
Branches
Tags
No related merge requests found
import numpy as np
from mu_map.file.dicom import DICOM
from mu_map.file.interfile import (
Interfile,
parse_interfile_header_str,
TEMPLATE_HEADER_IMAGE,
)
"""
Module for the conversion between the different formats.
"""
def dicom_to_interfile(dcm: DICOM, image: np.ndarray) -> Interfile:
"""
Convert a DICOM image to Interfile format.
:param dcm: the DICOM image
:param image: the image as a numpy array
:return: an Interfile as a combination of header and image
"""
header = TEMPLATE_HEADER_IMAGE.replace("{ROWS}", str(dcm.Rows))
header = header.replace("{SPACING_X}", f"{dcm.PixelSpacing[0]:.4f}")
header = header.replace("{COLUMNS}", str(dcm.Columns))
header = header.replace("{SPACING_Y}", f"{dcm.PixelSpacing[1]:.4f}")
header = header.replace("{SLICES}", str(dcm.NumberOfSlices))
header = header.replace("{SPACING_Z}", f"{dcm.SliceThickness:.4f}")
header = header.replace("{OFFSET_X}", str(-0.5 * dcm.Rows * dcm.PixelSpacing[0]))
header = header.replace("{OFFSET_Y}", str(-0.5 * dcm.Columns * dcm.PixelSpacing[1]))
header = parse_interfile_header_str(header)
return Interfile(header, image.astype(np.float32))
if __name__ == "__main__":
import argparse
import os
import pydicom
from mu_map.file.dicom import change_uid, load_dcm, update_dcm, EXTENSION_DICOM
from mu_map.file.interfile import write_interfile, load_interfile_img
def main_interfile(args):
args.out = args.file if args.out is None else args.out
dcm, image = load_dcm(args.file)
interfile = dicom_to_interfile(dcm, image)
write_interfile(args.out, interfile)
def main_dicom(args):
args.out = args.file if args.out is None else args.out
args.out = os.path.splitext(args.out)[0]
args.out = f"{args.out}{EXTENSION_DICOM}"
image = load_interfile_img(args.file)
reference = pydicom.dcmread(args.reference)
dcm = update_dcm(reference.copy(), image)
dcm = change_uid(dcm)
if args.description:
dcm.SeriesDescription = args.description
pydicom.dcmwrite(args.out, dcm)
parser = argparse.ArgumentParser(
description="convert images between different formats",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"file",
type=str,
help="the file to be converted (a DICOM image or an Interfile header)",
)
parser.add_argument(
"--out",
type=str,
help="the filename for the output file. If not specified it defaults to the input name with different extensions.",
)
subparsers = parser.add_subparsers(help="file to convert to")
parser_dcm = subparsers.add_parser("dicom", help="convert to a DICOM file")
parser_dcm.add_argument(
"--reference",
type=str,
required=True,
help="reference DICOM file to use for the header",
)
parser_dcm.add_argument(
"--description", type=str, help="update the series description"
)
parser_dcm.set_defaults(func=main_dicom)
parser_inter = subparsers.add_parser("interfile", help="convert to an Interfile")
parser_inter.set_defaults(func=main_interfile)
args = parser.parse_args()
args.func(args)
from typing import Dict, Tuple
import numpy as np
from pydicom.dataset import FileDataset as DCMImage
from mu_map.file.interfile import TEMPLATE_HEADER_IMAGE, parse_interfile_header_str
def to_interfile(dcm: DCMImage, image: np.ndarray) -> Tuple[Dict[str, str], np.ndarray]:
"""
Convert a DICOM image to INTERFILE format.
:param dcm: the DICOM image
:param image: the image as a numpy array
:return: the header and image in INTERFILE format
"""
header = TEMPLATE_HEADER_IMAGE.replace("{ROWS}", str(dcm.Rows))
header = header.replace("{SPACING_X}", f"{dcm.PixelSpacing[0]:.4f}")
header = header.replace("{COLUMNS}", str(dcm.Columns))
header = header.replace("{SPACING_Y}", f"{dcm.PixelSpacing[1]:.4f}")
header = header.replace("{SLICES}", str(dcm.NumberOfSlices))
header = header.replace("{SPACING_Z}", f"{dcm.SliceThickness:.4f}")
header = header.replace("{OFFSET_X}", str(-0.5 * dcm.Rows * dcm.PixelSpacing[0]))
header = header.replace("{OFFSET_Y}", str(-0.5 * dcm.Columns * dcm.PixelSpacing[1]))
header = parse_interfile_header_str(header)
return header, image.astype(np.float32)
if __name__ == "__main__":
import argparse
import os
from mu_map.file.dicom import load_dcm
from mu_map.file.interfile import write_interfile
parser = argparse.ArgumentParser(
description="convert a DICOM image to the INTERFILE format"
)
parser.add_argument(
"--dcm", type=str, required=True, help="the DICOM image to convert"
)
parser.add_argument(
"--out",
type=str,
help="the filename for the resulting INTERFILE format. If not specified it defaults to the input name with different extensions.",
)
args = parser.parse_args()
args.out = args.dcm if args.out is None else args.out
args.out = os.path.splitext(args.out)[
0
] # make sure the output file does not have an extension
dcm, image = load_dcm(args.dcm)
header, image = to_interfile(dcm, image)
write_interfile(args.out, header, image)
import argparse
import os
import numpy as np
import pydicom
from mu_map.file.dicom import update_dcm, change_uid
from mu_map.file.interfile import load_interfile_img
parser = argparse.ArgumentParser(
description="convert an Interfile image to a DICOM image",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"--inter", type=str, required=True, help="the Interfile image to be converted"
)
parser.add_argument(
"--dcm",
type=str,
required=True,
help="a DICOM reference image - data and according fields are exchanged from the Interfile image",
)
parser.add_argument(
"--out",
type=str,
help="the output file - defaults to the Interfile input with a dcm extension",
)
parser.add_argument(
"--description",
type=str,
help="if provided the series description will be updated",
)
args = parser.parse_args()
if args.out is None:
args.out = os.path.splitext(args.inter)[0] + ".dcm"
image = load_interfile_img(args.inter)
dcm = pydicom.dcmread(args.dcm)
dcm = update_dcm(dcm.copy(), image)
dcm = change_uid(dcm)
if args.description:
dcm.SeriesDescription = args.description
pydicom.dcmwrite(args.out, dcm)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment