Newer
Older
"""
Module contains a GUI that allows to label if the first and/or last slice
of an attenuation map is broken.
In addition, there is a utility function to remove these labeled slices.
"""

Tamino Huxohl
committed
from typing import Optional
import numpy as np
import pandas as pd
HEADER_DISC_FIRST = "discard_first"
HEADER_DISC_LAST = "discard_last"
def discard_slices(
row: pd.Series, μ_map: np.ndarray, recon: Optional[np.ndarray] = None
) -> np.ndarray:
Discard slices based on the flags in the row of the according table.
The row is expected to contain the flags 'discard_first' and 'discard_last'.
Parameters
----------
row: pd.Series
the row of meta configuration file of a dataset
μ_map: np.ndarray
the μ_map
recon: np.ndarray, optional
reconstruction of which the same slice is discarded so that the alignment stays the same
Returns
-------
np.ndarray
the μ_map (and reconstruction) with according slices removed
"""
_res = μ_map
if row[HEADER_DISC_FIRST]:
_res = _res[1:]

Tamino Huxohl
committed
if recon is not None:
recon = recon[1:]
if row[HEADER_DISC_LAST]:
_res = _res[:-1]

Tamino Huxohl
committed
if recon is not None:
recon = recon[:-1]
if recon is not None:
return _res, recon
return _res
if __name__ == "__main__":
import argparse
import cv2 as cv
from mu_map.dataset.default import MuMapDataset
from mu_map.util import to_grayscale, COLOR_WHITE, COLOR_BLACK
parser = argparse.ArgumentParser(
description="review all μ-maps in a dataset for broken slices at the start or end",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"dataset_dir", type=str, help="directory containing the dataset"
)
parser.add_argument(
"--view", action="store_true", help="only visualize the current state"
)
parser.add_argument(
"--force",
action="store_true",
help="do not ask for permission to replace discard flags in the table",
)
args = parser.parse_args()
dataset = MuMapDataset(
dataset_dir=args.dataset_dir,
bed_contours_file=None,
discard_mu_map_slices=args.view,
)
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
if (
not args.view
and not args.force
and (
(
HEADER_DISC_FIRST in dataset.table
and not (dataset.table[HEADER_DISC_FIRST] == False).all()
)
or (
HEADER_DISC_LAST in dataset.table
and not (dataset.table[HEADER_DISC_LAST] == False).all()
)
)
):
print(
f"This operation is going to set all discard_first and discard_last flags in {dataset.csv_file}. If you only want to see the current state use the --view flag."
)
_input = input("Are you okay with setting these flags to false? (y/n): ")
if _input.lower() != "y":
exit(0)
if not args.view:
dataset.table[HEADER_DISC_FIRST] = False
dataset.table[HEADER_DISC_LAST] = False
wname = "μ-map"
cv.namedWindow(wname, cv.WINDOW_NORMAL)
cv.resizeWindow(wname, 1600, 900)
controls = "l = discard last, f = discard first, b = discard both, n = discard none"
for i, (_, μ_map) in enumerate(dataset):
print(f"Image {str(i + 1):>{len(str(len(dataset)))}}/{len(dataset)}", end="\r")
slice_first = to_grayscale(μ_map[0])
slice_last = to_grayscale(μ_map[-1])
slice_first = cv.resize(slice_first, (512, 512), interpolation=cv.INTER_AREA)
slice_last = cv.resize(slice_last, (512, 512), interpolation=cv.INTER_AREA)
cv.putText(
slice_first, "First", (0, 30), cv.FONT_HERSHEY_SIMPLEX, 1, COLOR_BLACK, 3
)
cv.putText(
slice_first, "First", (0, 30), cv.FONT_HERSHEY_SIMPLEX, 1, COLOR_WHITE, 1
)
cv.putText(
slice_last, "Last", (0, 30), cv.FONT_HERSHEY_SIMPLEX, 1, COLOR_BLACK, 3
)
cv.putText(
slice_last, "Last", (0, 30), cv.FONT_HERSHEY_SIMPLEX, 1, COLOR_WHITE, 1
)
space = np.full((slice_first.shape[0], 10), 239, np.uint8)
to_show = np.hstack((slice_first, space, slice_last))
textposition = (0, to_show.shape[0] - 12)
cv.putText(
to_show,
controls,
textposition,
cv.FONT_HERSHEY_SIMPLEX,
0.75,
COLOR_BLACK,
3,
)
cv.putText(
to_show,
controls,
textposition,
cv.FONT_HERSHEY_SIMPLEX,
0.75,
COLOR_WHITE,
1,
)
cv.imshow(wname, to_show)
key = cv.waitKey(0)
if key == ord("q"):
exit(0)
elif key == ord("l"):
dataset.table.loc[i, (HEADER_DISC_LAST)] = True
elif key == ord("f"):
dataset.table.loc[i, (HEADER_DISC_FIRST)] = True
elif key == ord("b"):
dataset.table.loc[i, (HEADER_DISC_LAST)] = True
dataset.table.loc[i, (HEADER_DISC_FIRST)] = True
if not args.view:
dataset.table.to_csv(dataset.csv_file, index=False)