Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 37 additions & 55 deletions httomolib/misc/blend.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
__check_variable_type,
__check_if_data_3D_array,
__check_if_data_correct_type,
__check_if_positive_nonzero,
)

__all__ = [
Expand All @@ -36,27 +37,24 @@

def seam_blend_stitched_data(
data: np.ndarray,
seam_index: Optional[int] = None,
blending_width: Optional[int] = None,
path_to_stitched_params_file: Optional[str] = None,
shift_seam_index: int = 0,
overlap: int,
seam_index: int = 2560,
shift_seam_index: Optional[int] = None,
) -> np.ndarray:
"""
Function blends the seam present in the stitched projection data. It uses the redundant by blending_width data present on both sides of the seam.
Used in HTTomo for seamless stitching of datasets coming from two different PCO cameras.
Function blends the seam present in the stitched projection data using the overlap value provided.
Used in HTTomo for seamless stitching of datasets coming from two different (PCO) cameras.

Parameters
----------
data : np.ndarray
3d array of the stitched data, assuming the following axis ["angles", "detY", "detX"].
seam_index : Optional, int
The horizontal index of the seam along the 'detX' axis. If None and 'path_to_stitched_params_file' is provided, it will be taken from the file, otherwise middle of the horizontal axis.
blending_width : Optional, int
The area for symmetric blending (e.g. with the ramp filter) around the seam position (seam_index) of the stitched data. If None and 'path_to_stitched_params_file' is provided, it will be taken from the file, otherwise 0.
path_to_stitched_params_file : Optional, str
Path to the text file with the stiching parameters. If provided 'seam_index' and 'blending_width' parameters will be overridden by the ones provided in the file.
shift_seam_index : int
performs a shift of the seam index with seam_index - shift_seam_index. This is purely an HTTomo related feature and should be ignored by users.
overlap : int
Overlap between the LEFT and the RIGHT images of the stitched data. Usually known from the experiment.
seam_index : int
The horizontal index of the seam in the stitched data. Normally equals to the width of one frame/projection before the stitching.
shift_seam_index : optional, int
performs a shift of the 'seam index' that is introduced by the data cropping. This is an HTTomo related feature and should be ignored by users.
Raises
----------
ValueError: When data is not 3D.
Expand All @@ -66,63 +64,47 @@ def seam_blend_stitched_data(
np.ndarray: stitched data without the seam.
"""
### Data and parameters checks ###
methods_name = "seam_blender"
methods_name = "seam_blend_stitched_data"
__check_if_data_3D_array(data, methods_name)
__check_if_data_correct_type(
data,
accepted_type=["float64", "float32", "uint8", "uint16", "uint32"],
methods_name=methods_name,
)
__check_variable_type(seam_index, [int, type(None)], "seam_index", [], methods_name)
__check_variable_type(
blending_width, [int, type(None)], "blending_width", [], methods_name
__check_if_positive_nonzero(
seam_index,
"seam_index",
True,
True,
methods_name,
)
__check_variable_type(seam_index, [int], "seam_index", [], methods_name)
__check_variable_type(
path_to_stitched_params_file,
[str, type(None)],
"path_to_stitched_params_file",
[],
methods_name,
shift_seam_index, [int, type(None)], "shift_seam_index", [], methods_name
)
###################################

angles_dim, detY, detX = data.shape

if path_to_stitched_params_file is not None:
params = {}
with open(path_to_stitched_params_file) as f:
for line in f:
key, value = line.split()
params[key] = int(value)
if shift_seam_index is None:
shift_seam_index = 0

blending_width = params.get("blending_width")
seam_index = params.get("seam_index")

if blending_width is None:
blending_width = 0
if seam_index is None:
seam_index = int(detX // 2)

blending_width *= 2
seam_index -= shift_seam_index

if seam_index >= detX - blending_width:
err_str = f"Seam index given as '{seam_index}' must be smaller than the horizontal dimension of the data '{detX}' minus blending width."
angles_dim, detY, detX = data.shape
if seam_index < 0 or seam_index >= detX:
err_str = f"Seam index '{seam_index}' cannot be negative or larger than the horizontal dimension of the data '{detX}'. Check 'shift_seam_index'."
raise ValueError(err_str)

# Split regions of data
left_part = data[:, :, 0 : (seam_index - blending_width)]
right_part = data[:, :, (seam_index + blending_width) : :]

# Overlap regions
left_overlap = data[:, :, (seam_index - blending_width) : seam_index]
right_overlap = data[:, :, seam_index : (seam_index + blending_width)]
ramp = np.linspace(0, 1, overlap)

# Create ramp weights (0 → 1)
ramp = np.float32(np.linspace(0, 1, blending_width))
ramp = np.tile(ramp, (detY, 1))
blended_data = np.empty((angles_dim, detY, detX - overlap), dtype=data.dtype)

# Blend
blended_overlap = (1 - ramp) * left_overlap + ramp * right_overlap
blended_data[:, :, 0 : seam_index - overlap] = data[
:, :, 0 : seam_index - overlap
] # left side
blended_data[:, :, seam_index::] = data[:, :, seam_index + overlap :] # right side
blended_data[:, :, seam_index - overlap : seam_index] = (
data[:, :, seam_index - overlap : seam_index] * ramp[::-1]
+ data[:, :, seam_index : seam_index + overlap] * ramp
) # overlap area

return np.dstack([left_part, blended_overlap, right_part])
return blended_data
6 changes: 0 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ def data_stitched(test_data_path):
return np.load(in_file)


@pytest.fixture(scope="session")
def data_stitched_txt(test_data_path):
in_file = os.path.join(test_data_path, "stitching_params.txt")
return in_file


@pytest.fixture
def host_data(data_file):
return np.copy(data_file["data"])
Expand Down
2 changes: 0 additions & 2 deletions tests/test_data/stitching_params.txt

This file was deleted.

18 changes: 11 additions & 7 deletions tests/test_misc/test_blend.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@

def test_seam_blend_stitched_data(data_stitched):

result = seam_blend_stitched_data(data_stitched, seam_index=151, blending_width=30)
result = seam_blend_stitched_data(
data_stitched, overlap=20, seam_index=151, shift_seam_index=None
)

assert result.flags.c_contiguous
assert result.dtype == np.float32
assert result.shape == (300, 4, 240)
assert result.dtype == np.uint16
assert result.shape == (300, 4, 280)
np.testing.assert_array_almost_equal(int(np.mean(result)), 11520)


def test_seam_blend_stitched_data_txt(data_stitched, data_stitched_txt):
def test_seam_blend_stitched_data_shift(data_stitched):

result = seam_blend_stitched_data(
data_stitched, path_to_stitched_params_file=data_stitched_txt
data_stitched, overlap=20, seam_index=151, shift_seam_index=10
)

assert result.flags.c_contiguous
assert result.dtype == np.float32
assert result.shape == (300, 4, 240)
assert result.dtype == np.uint16
assert result.shape == (300, 4, 280)
np.testing.assert_array_almost_equal(int(np.mean(result)), 11506)
Loading