def label_unions_and_duplicates(rois, overlap_threshold): '''Detect unions and duplicates and label ROIs.''' masks = create_roi_mask_array(rois) valid_masks = np.ones(masks.shape[0]).astype(bool) ms = mask_set.MaskSet(masks=masks) # detect and label duplicates duplicates = ms.detect_duplicates(overlap_threshold) for duplicate in duplicates: index = duplicate[0] if "duplicate" not in rois[index].labels: rois[index].labels.append("duplicate") valid_masks[index] = False # detect and label unions only for remaining valid masks valid_idxs = np.where(valid_masks) ms = mask_set.MaskSet(masks=masks[valid_idxs].astype(bool)) unions = ms.detect_unions() if unions: union_idxs = list(unions.keys()) idxs = valid_idxs[0][union_idxs] for idx in idxs: if "union" not in rois[idx].labels: rois[idx].labels.append("union") return rois
def identify_valid_masks(mask_array): ms = mask_set.MaskSet(masks=mask_array.astype(bool)) valid_masks = np.ones(mask_array.shape[0]).astype(bool) # detect duplicates duplicates = ms.detect_duplicates(overlap_threshold=0.9) if len(duplicates) > 0: valid_masks[duplicates.keys()] = False # detect unions, only for remaining valid masks valid_idxs = np.where(valid_masks) ms = mask_set.MaskSet(masks=mask_array[valid_idxs].astype(bool)) unions = ms.detect_unions() if len(unions) > 0: un_idxs = unions.keys() valid_masks[valid_idxs[0][un_idxs]] = False return valid_masks
def label_unions_and_duplicates(roi_objs, masks=None, duplicate_threshold=0.9, union_threshold=0.7, max_dist=10, set_size=2): """ Modified from allensdk.internal.brain_observatory.roi_filter.py Returns ROI objects with unions and duplicates labelled. Required args: - roi_objs (ROI objects): ROI objects Optional args: - masks (3D array) : ROI mask arrays. If None provided, they are recreated from the ROI objects default: None - duplicate_threshold (float): threshold for identifying ROI duplicated (only the first of each set is labelled a duplicate) default: 0.9 - union_threshold (float) : threshold for identifying ROIs that are unions of several ROIs default: 0.7 - set_size (int) : number of ROIs forming sets to be checked for possibly being unions default: 2 - max_dist (num) : max distance between ROIs to be checked for possibly being unions default: 10 Returns: - roi_objs (ROI objects): ROI objects labelled for union, duplicate, empty and border overlapping mask conditions """ roi_objs = copy.deepcopy(roi_objs) if masks is None: masks = roi_masks.create_roi_mask_array(roi_objs) # get indices for non empty ROIs non_empty_mask = np.asarray([ roi_obj.mask is not None for roi_obj in roi_objs]).astype(bool) non_empty_idx = np.where(non_empty_mask)[0] # label empty ROIs for idx in np.where(~non_empty_mask)[0]: roi_objs[idx].labels.append("empty") ms = mask_set.MaskSet(masks=masks[non_empty_idx]) # detect and label duplicates duplicates = ms.detect_duplicates(duplicate_threshold) for duplicate in duplicates: orig_idx = non_empty_idx[duplicate[0]] if "duplicate" not in roi_objs[orig_idx].labels: roi_objs[orig_idx].labels.append("duplicate") # detect and label unions unions = ms.detect_unions(set_size, max_dist, union_threshold) if unions: union_idxs = list(unions.keys()) for idx in union_idxs: orig_idx = non_empty_idx[idx] if "union" not in roi_objs[orig_idx].labels: roi_objs[orig_idx].labels.append("union") return roi_objs