def f(roi, dataset=None): mask = roi.mask[0].todense() poly_pts = np.array(mask2poly(mask)[0].exterior.coords) p = 0 for x in range(len(poly_pts) - 1): p += np.linalg.norm(poly_pts[x] - poly_pts[x + 1]) shape_area = np.count_nonzero(mask) circle_area = old_div(np.square(p), (4 * np.pi)) return old_div(shape_area, circle_area) > circularity_threhold
def _rois_from_cuts_ca1pc(cuts, im_set, circularity_threhold=0.5, min_roi_size=20, min_cut_size=30, channel=0, x_diameter=8, y_diameter=8): """Return ROI structures containing CA1 pyramidal cell somata. Parameters ---------- cuts : list of sima.normcut.CutRegion The segmented regions identified by normalized cuts. circularity_threhold : float ROIs with circularity below threshold are discarded. Default: 0.5. min_roi_size : int, optional ROIs with fewer than min_roi_size pixels are discarded. Default: 20. min_cut_size : int, optional No ROIs are made from cuts with fewer than min_cut_size pixels. Default: 30. channel : int, optional The index of the channel to be used. x_diameter : int, optional The estimated x-diameter of the nuclei in pixels y_diameter : int, optional The estimated y_diameter of the nuclei in pixels Returns ------- sima.ROI.ROIList ROI structures each corresponding to a CA1 pyramidal cell soma. """ processed_im = _processed_image_ca1pc(im_set, channel, x_diameter, y_diameter) shape = processed_im.shape[:2] ROIs = ROIList([]) for cut in cuts: if len(cut.indices) > min_cut_size: # pixel values in the cut vals = processed_im.flat[cut.indices] # indices of those values below the otsu threshold # if all values are identical, continue without adding an ROI try: roi_indices = cut.indices[vals < threshold_otsu(vals)] except ValueError: continue # apply binary opening and closing to the surviving pixels # expand the shape by 1 in all directions to correct for edge # effects of binary opening/closing twoD_indices = [np.unravel_index(x, shape) for x in roi_indices] mask = np.zeros([x + 2 for x in shape]) for indices in twoD_indices: mask[indices[0] + 1, indices[1] + 1] = 1 mask = ndimage.binary_closing(ndimage.binary_opening(mask)) mask = mask[1:-1, 1:-1] roi_indices = np.where(mask.flat)[0] # label blobs in each cut labeled_array, num_features = label(mask) for feat in range(num_features): blob_inds = np.where(labeled_array.flat == feat + 1)[0] # Apply min ROI size threshold if len(blob_inds) > min_roi_size: twoD_indices = [np.unravel_index(x, shape) for x in blob_inds] mask = np.zeros(shape) for x in twoD_indices: mask[x] = 1 # APPLY CIRCULARITY THRESHOLD poly_pts = np.array(mask2poly(mask)[0].exterior.coords) p = 0 for x in range(len(poly_pts) - 1): p += np.linalg.norm(poly_pts[x] - poly_pts[x + 1]) shape_area = len(roi_indices) circle_area = np.square(p) / (4 * np.pi) if shape_area / circle_area > circularity_threhold: ROIs.append(ROI(mask=mask)) return ROIs