Commit eae08da8 authored by Joao P C Bertoldo's avatar Joao P C Bertoldo
Browse files

new generate seeds function

parent c25324ed
from pydct.segment.segment3d import grow_seeds_no_iteration_parallel, generate_seeds_binary_threshold, get_seed_region_max, DifSpot, DifSpotDBCompatible
from pydct.segment.segment3d import grow_seeds_no_iteration_parallel, generate_seeds, DifSpot, DifSpotDBCompatible
from enum import Enum
from ipywidgets import RadioButtons
......@@ -12,95 +12,78 @@ _logger = logging.getLogger("pydct")
# min_3dblob_volume = 10
def generate_seeds_binary_threshold(
data: ndarray, threshold: float, min_3dblob_volume: int, return_labels_volume=False
def generate_seeds(
data: ndarray,
threshold: float, min_3dblob_volume: int,
) -> (ndarray, List):
_logger.debug(f"applying threshold \\approx {float(f'{threshold:.4g}'):,.3f}")
# isfinite is necessary because we exclude the direct beam with nan
_logger.debug(f"applying threshold {threshold}")
seeds = (data >= threshold) & np.isfinite(data)
_logger.debug(f"finding connected components")
# each connected region gets its own label (integer)
_logger.debug(f"finding connected components")
labels = skimage.measure.label(seeds)
_logger.debug(f"getting region props")
# a list of volumes of the blobs in the same order as their labels
props = skimage.measure.regionprops(labels, data, cache=False)
if not return_labels_volume:
_logger.debug("getting rid of the labels volume")
del labels
volumes = np.array([p.area for p in props])
_logger.debug(f"{len(props)} found, now filtering them by volume")
# filter the labels of regions with enough volume
selected_labels = volumes > min_3dblob_volume
_logger.debug(f"{np.sum(selected_labels)} left, now making getting a list of the label values left")
selected_labels_values = np.array([p.label for p in props])[selected_labels]
if return_labels_volume:
_logger.debug(f"erasing the discarde labeled regions from the labels volume")
# mask the labels volume filtering those without enough volume
selected_seeds = labels * np.isin(labels, selected_labels_values).astype(np.int32)
_logger.debug(f"now filtering the region props")
selected_props = [p for p in props if p.label in selected_labels_values]
if return_labels_volume:
return selected_seeds, selected_props
return None, selected_props
from typing import List
from pandas import DataFrame
from scipy import ndimage
_logger.debug(f"getting regions")
objects = ndimage.find_objects(labels)
_logger.debug(f"{len(objects)} segmented objects in image")
_logger.debug(f"computing object sizes")
volumes = [
if (o[0].stop - o[0].start) * (o[1].stop - o[1].start) * (o[2].stop - o[2].start) < min_3dblob_volume
np.sum(labels[o[0].start:o[0].stop, o[1].start:o[1].stop, o[2].start:o[2].stop] == i + 1)
for i, o in enumerate(objects)
selected_labels = np.array(volumes) > min_3dblob_volume
_logger.debug(f"{np.sum(selected_labels)} left, now making a list of the label values left")
selected_labels_values = np.where(selected_labels)[0]
def get_seed_region_max(data: ndarray, rp: "RegionProperties"):
#selected_seeds = labels * np.isin(labels, selected_labels_values).astype(np.int32)
selected_bbs = np.array(objects)[selected_labels]
# find max value in the seed blob, then its absolute position and value
# 'absolute position' = in the whole image's frame
# 'relative position' = in the subvolume ("ROI") around the seed's maximum
# at this moment the ROI == BB (bounding box) of the blob
# but later it will not necessarily be
rel_position = np.unravel_index(
np.nanargmax(rp.intensity_image), rp.intensity_image.shape # serial index, not multi-dimensioned
# origin in the blob's referential
abs_bb_origin = rp.bbox[0:3]
abs_max_position = np.array(abs_bb_origin) + np.array(rel_position)
max_value = data[tuple(abs_max_position)]
absolute_max_positions = [
np.array([bb[0].start, bb[1].start, bb[2].start]) + np.array(np.unravel_index(
# nanargmax gives serial index, not multi-dimensioned
np.nanargmax(data[bb[0].start:bb[0].stop, bb[1].start:bb[1].stop, bb[2].start:bb[2].stop]),
((bb[0].stop - bb[0].start), (bb[1].stop - bb[1].start), (bb[2].stop - bb[2].start))
for bb in selected_bbs
ret = [
v=data[pos[0], pos[1], pos[2]],
# todo: verify if this is still used in the seeds grow
# it was used when there were iterations, not sure now...
# these will serve to filter the seeds as we find bad ones
for label, pos in zip(selected_labels_values, absolute_max_positions)
abs_max_position = abs_max_position.tolist()
return dict(
# these will serve to filter the seeds as we find bad ones
if return_labels_volume:
return ret, labels
return ret
from typing import List
from pandas import DataFrame
from dataclasses import dataclass
from typing import Tuple
import os
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment