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

enhance interfile utils

parent 777a9e16
No related branches found
No related tags found
No related merge requests found
......@@ -55,39 +55,6 @@ number of time frames := 1
!END OF INTERFILE :=
"""
HEADER_TEMPLATE_PROJ = """
!INTERFILE :=
!imaging modality := nucmed
!version of keys := 3.3
name of data file := {DATA_FILE}
;data offset in bytes := 0
!GENERAL IMAGE DATA :=
!type of data := Tomographic
imagedata byte order := LITTLEENDIAN
!number format := float
!number of bytes per pixel := 4
!SPECT STUDY (General) :=
;number of dimensions := 2
;matrix axis label [2] := axial coordinate
!matrix size [2] := {ROWS}
!scaling factor (mm/pixel) [2] := {SPACING_X}
;matrix axis label [1] := bin coordinate
!matrix size [1] := {COLUMNS}
!scaling factor (mm/pixel) [1] := {SPACING_Y}
!number of projections := {N_PROJECTIONS}
!extent of rotation := {ROTATION}
!process status := acquired
!SPECT STUDY (acquired data) :=
!direction of rotation := CW
start angle := {START_ANGLE}
orbit := circular
radius := {RADIUS}
!END OF INTERFILE :=
"""
def type_by_format(number_format: str, bytes_per_pixel: int) -> type:
......@@ -105,23 +72,33 @@ def type_by_format(number_format: str, bytes_per_pixel: int) -> type:
raise ValueError("Unknown mapping from format {number_format} with {bytes_per_pixel} bytes to numpy type")
def parse_interfile_header(filename: str) -> Dict[str, str]:
def parse_interfile_header_str(header: str) -> Dict[str, str]:
"""
Parse an INTERFILE header into a dict.
This is done by splitting non-empty lines in the INTERFILE header by ":=".
:param filename: the filename of the INTERFILE header
:param header: the text of an INTERFILE header
:return: a dictionary of value in the header
"""
with open(filename, mode="r") as f:
lines = f.readlines()
lines = header.strip().split("\n")
items = map(lambda line: line.split(":="), lines)
items = filter(lambda item: len(item) == 2, items)
items = map(lambda item: [item[0].strip(), item[1].strip()], items)
return dict(items)
def parse_interfile_header(filename: str) -> Dict[str, str]:
"""
Parse an INTERFILE header into a dict.
This is done by splitting non-empty lines in the INTERFILE header by ":=".
:param filename: the filename of the INTERFILE header
:return: a dictionary of value in the header
"""
with open(filename, mode="r") as f:
return parse_interfile_header_str(f.read())
def load_interfile(filename: str) -> Tuple[Dict[str, str], np.ndarray]:
"""
Load an INTERFILE header and its image as a numpy array.
......@@ -164,7 +141,10 @@ def write_interfile(filename: str, header: Dict[str, str], image: np.ndarray):
header[KEY_DATA_FILE] = os.path.basename(filename_data)
header[KEY_DIM_3] = str(image.shape[0])
header[KEY_DIM_2] = str(image.shape[1])
header[KEY_DIM_1] = str(image.shape[2])
image = image.astype(np.float32)
header_str = map(lambda item: f"{item[0]} := {item[1]}", header.items())
header_str = "\n".join(header_str)
......@@ -181,7 +161,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Modify an interfile image")
parser.add_argument("--interfile", type=str, required=True, help="the interfile input")
parser.add_argument("--out", type=str, help="the interfile output - if not set the input file will be overwritte")
parser.add_argument("--cmd", choices=["fill", "crop", "pad"], help="the modification to perform")
parser.add_argument("--cmd", choices=["fill", "crop", "pad", "flip"], help="the modification to perform")
parser.add_argument("--param", type=int, required=True, help="the parameters for the modification [fill: value, crop & pad: target size of z dimension]")
args = parser.parse_args()
args.out = args.interfile if args.out is None else args.out
......@@ -210,6 +190,8 @@ if __name__ == "__main__":
crop_lower = center - math.floor(diff)
crop_upper = center + math.ceil(diff)
image = image[crop_lower:crop_upper]
if args.cmd == "flip":
image = image[:, :, ::-1]
write_interfile(args.out, header, image)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment