Skip to content

Commit

Permalink
Implement smoothing as option
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathis Rasmussen committed Jun 15, 2023
1 parent 12c3ba7 commit cafdfe0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
1 change: 1 addition & 0 deletions rt_utils/image_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def find_mask_contours(mask: np.ndarray, approximate_contours: bool, scaling_fac
contours
) # Open-CV updated contours to be a tuple so we convert it back into a list here

# Coordinates are rescaled to image grid by dividing with scaling factor
for i, contour in enumerate(contours):
contours[i] = [[(contour[i][0][0] / scaling_factor), (contour[i][0][1] / scaling_factor)] for i in
range(0, len(contour))]
Expand Down
55 changes: 31 additions & 24 deletions rt_utils/smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
import logging

# A set of parameters that is know to work well
default_smoothing_parameters = {
"iterations": 2,
default_smoothing_parameters_2d = {
"scaling_iterations": 2,
"filter_iterations": 1,
"crop_margins": [20, 20, 1],
"np_kron": {"scaling_factor": 3},
"ndimage_gaussian_filter": {"sigma": 2,
"radius": 3},
"threshold": {"threshold": 0.4},
}
# A set of parameters that is know to work well
default_smoothing_parameters_2 = {
"iterations": 3,
default_smoothing_parameters_2d_2 = {
"scaling_iterations": 3,
"crop_margins": [20, 20, 1],
"np_kron": {"scaling_factor": 2},
"ndimage_gaussian_filter": {"sigma": 2,
Expand Down Expand Up @@ -87,28 +88,30 @@ def restore_mask_dimensions(cropped_mask: np.ndarray, new_shape, bbox):
new_mask[bbox[0]: bbox[1], bbox[2]: bbox[3], bbox[4]: bbox[5]] = cropped_mask
return new_mask.astype(bool)

def iteration_2d(mask: np.ndarray, np_kron, ndimage_gaussian_filter, threshold):
def iteration_2d(mask: np.ndarray, np_kron, ndimage_gaussian_filter, threshold, filter_iterations):
"""
This is the actual set of filters. Applied iterative over z direction
"""
cropped_mask = kron_upscale(mask=mask, params=np_kron)

for z_idx in range(cropped_mask.shape[2]):
slice = cropped_mask[:, :, z_idx]
slice = gaussian_blur(mask=slice, params=ndimage_gaussian_filter)
slice = binary_threshold(mask=slice, params=threshold)
for filter_iteration in range(filter_iterations):
for z_idx in range(cropped_mask.shape[2]):
slice = cropped_mask[:, :, z_idx]
slice = gaussian_blur(mask=slice, params=ndimage_gaussian_filter)
slice = binary_threshold(mask=slice, params=threshold)

cropped_mask[:, :, z_idx] = slice
cropped_mask[:, :, z_idx] = slice

return cropped_mask

def iteration_3d(mask: np.ndarray, np_kron, ndimage_gaussian_filter, threshold):
def iteration_3d(mask: np.ndarray, np_kron, ndimage_gaussian_filter, threshold, filter_iterations):
"""
This is the actual filters applied iteratively in 3d.
"""
cropped_mask = kron_upscale(mask=mask, params=np_kron)
cropped_mask = gaussian_blur(mask=cropped_mask, params=ndimage_gaussian_filter)
cropped_mask = binary_threshold(mask=cropped_mask, params=threshold)
for filter_iteration in range(filter_iterations):
cropped_mask = kron_upscale(mask=mask, params=np_kron)
cropped_mask = gaussian_blur(mask=cropped_mask, params=ndimage_gaussian_filter)
cropped_mask = binary_threshold(mask=cropped_mask, params=threshold)

return cropped_mask

Expand All @@ -119,9 +122,11 @@ def pipeline(mask: np.ndarray,
This is the entrypoint for smoothing a mask.
"""
if not smoothing_parameters:
smoothing_parameters = default_smoothing_parameters
smoothing_parameters = default_smoothing_parameters_2d

scaling_iterations = smoothing_parameters["scaling_iterations"]
filter_iterations = smoothing_parameters["filter_iterations"]

iterations = smoothing_parameters["iterations"]
crop_margins = np.array(smoothing_parameters["crop_margins"])
np_kron = smoothing_parameters["np_kron"]
ndimage_gaussian_filter = smoothing_parameters["ndimage_gaussian_filter"]
Expand All @@ -132,22 +137,24 @@ def pipeline(mask: np.ndarray,
cropped_mask, bbox = crop_mask(mask, crop_margins=crop_margins)
final_shape, final_bbox = get_final_mask_shape_and_bbox(mask=mask,
scaling_factor=np_kron["scaling_factor"],
iterations=iterations,
scaling_iterations=scaling_iterations,
bbox=bbox)
logging.info(f"Final scaling with factor of {np_kron['scaling_factor']} for {iterations} iterations")
for i in range(iterations):
logging.info(f"Iteration {i+1} out of {iterations}")
logging.info(f"Final scaling with factor of {np_kron['scaling_factor']} for {scaling_iterations} scaling_iterations")
for i in range(scaling_iterations):
logging.info(f"Iteration {i+1} out of {scaling_iterations}")
logging.info(f"Applying filters")
if apply_smoothing == "2d":
cropped_mask = iteration_2d(cropped_mask,
np_kron=np_kron,
ndimage_gaussian_filter=ndimage_gaussian_filter,
threshold=threshold)
threshold=threshold,
filter_iterations=filter_iterations)
elif apply_smoothing == "3d":
cropped_mask = iteration_3d(cropped_mask,
np_kron=np_kron,
ndimage_gaussian_filter=ndimage_gaussian_filter,
threshold=threshold)
threshold=threshold,
filter_iterations=filter_iterations)
else:
raise Exception("Wrong dimension parameter. Use '2d' or '3d'.")

Expand All @@ -156,12 +163,12 @@ def pipeline(mask: np.ndarray,
mask = restore_mask_dimensions(cropped_mask, final_shape, final_bbox)
return mask

def get_final_mask_shape_and_bbox(mask, bbox, scaling_factor, iterations):
def get_final_mask_shape_and_bbox(mask, bbox, scaling_factor, scaling_iterations):
"""
This function scales image shape and the bounding box which should be used for the final mask
"""

final_scaling_factor = pow(scaling_factor, iterations)
final_scaling_factor = pow(scaling_factor, scaling_iterations)

final_shape = np.array(mask.shape)
final_shape[:2] *= final_scaling_factor
Expand Down

0 comments on commit cafdfe0

Please sign in to comment.