Skip to content

Commit 943cd5d

Browse files
committed
chore: add scripts for combining a stack of single images to a volume and reducing the number of projections
1 parent 567d0d7 commit 943cd5d

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

src/scripts/combine_stack.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/python3
2+
"""Convert image stack to a volume via CLI."""
3+
4+
# Authors
5+
# -------
6+
# Author: Lukas Behammer
7+
# Research Center Wels
8+
# University of Applied Sciences Upper Austria, 2023
9+
# CT Research Group
10+
#
11+
# Modifications
12+
# -------------
13+
# Original code, 2025, Lukas Behammer
14+
#
15+
# License
16+
# -------
17+
# BSD-3-Clause License
18+
19+
import glob
20+
import os
21+
import sys
22+
23+
import numpy as np
24+
from viqa.utils.loading import _load_binary, _parse_bitdepth
25+
26+
27+
def combine_image_stack(input_path, size, bitdepth, file_type="raw"):
28+
"""Combine a stack of single images to a volume."""
29+
files = glob.glob(os.path.join(input_path, f"*.{file_type}"))
30+
data_type = _parse_bitdepth(bitdepth)
31+
32+
if len(files) != 0:
33+
vol = []
34+
for file in files:
35+
vol.append(_load_binary(file, data_type, size))
36+
37+
vol = np.array(vol)
38+
return vol
39+
40+
41+
def save_volume(output_path, vol, bitdepth, file_type="raw"):
42+
"""Save a volume to disk."""
43+
data_type = _parse_bitdepth(bitdepth)
44+
if not os.path.exists(output_path):
45+
os.makedirs(output_path)
46+
vol_shape = vol.shape
47+
vol = vol.astype(data_type)
48+
# save volume
49+
vol.tofile(
50+
os.path.join(
51+
output_path,
52+
f"volume_{vol_shape[2]}x{vol_shape[1]}x{vol_shape[0]}_{bitdepth}.{file_type}",
53+
)
54+
)
55+
56+
57+
if __name__ == "__main__":
58+
if len(sys.argv) == 9:
59+
input_path = sys.argv[1]
60+
output_path = sys.argv[2]
61+
size = [int(sys.argv[3]), int(sys.argv[4]), int(sys.argv[5])]
62+
bitdepth = sys.argv[6]
63+
file_type_input = sys.argv[7]
64+
file_type_output = sys.argv[8]
65+
66+
vol = combine_image_stack(input_path, size, bitdepth, file_type_input)
67+
save_volume(output_path, vol, bitdepth, file_type_output)
68+
else:
69+
print(
70+
"Usage: combine_raw_stack.py <input_path> <output_path> <size_x> "
71+
"<size_y> <size_z> <bitdepth> <file_type_input> <file_type_output>"
72+
)
73+
sys.exit(1)

src/scripts/reduce_projections.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/python3
2+
"""Reduce the number of projections via CLI."""
3+
4+
# Authors
5+
# -------
6+
# Author: Lukas Behammer
7+
# Research Center Wels
8+
# University of Applied Sciences Upper Austria, 2023
9+
# CT Research Group
10+
#
11+
# Modifications
12+
# -------------
13+
# Original code, 2025, Lukas Behammer
14+
#
15+
# License
16+
# -------
17+
# BSD-3-Clause License
18+
19+
import os
20+
import sys
21+
22+
from viqa.utils.loading import _load_binary, _parse_bitdepth
23+
24+
25+
def load_projection(file, size, bitdepth):
26+
"""Load projection images from a binary file."""
27+
data_type = _parse_bitdepth(bitdepth)
28+
vol = _load_binary(file, data_type, size)
29+
vol_shape = vol.shape
30+
vol = vol.reshape(*vol_shape[::-1])
31+
return vol
32+
33+
34+
def get_n_projections(volume, reducing_factor):
35+
"""Reduce the number of projections."""
36+
if reducing_factor == 1:
37+
raise ValueError(f"Error: factor must be greater than 1, got {reducing_factor}")
38+
39+
volume_new = volume[..., ::reducing_factor]
40+
return volume_new
41+
42+
43+
def save_volume(output, vol, bitdepth):
44+
"""Save the volume to a binary file."""
45+
output_folder = os.path.dirname(output)
46+
if not os.path.exists(output_folder):
47+
os.makedirs(output_folder)
48+
data_type = _parse_bitdepth(bitdepth)
49+
vol = vol.astype(data_type)
50+
# save volume
51+
vol.tofile(output)
52+
53+
54+
if __name__ == "__main__":
55+
if len(sys.argv) == 8:
56+
input_path = sys.argv[1]
57+
output_path = sys.argv[2]
58+
size = [int(sys.argv[3]), int(sys.argv[4]), int(sys.argv[5])]
59+
bitdepth = sys.argv[6]
60+
factor = int(sys.argv[7])
61+
62+
vol = load_projection(input_path, size, bitdepth)
63+
vol = get_n_projections(vol, factor)
64+
save_volume(output_path, vol, bitdepth)
65+
else:
66+
print(
67+
"Usage: reduce_projections.py <input_path> <output_path> <size_x> "
68+
"<size_y> <size_z> <bitdepth> <factor>"
69+
)
70+
sys.exit(1)

0 commit comments

Comments
 (0)