def find_spinal_cord(y): y_spine = get_mask_full_spine(y) # зальем "по y" y_ = apply_along_axes(fill_line, y_spine, axes=(1, 2)).astype(bool) # возьмем неплотное внутри y_n = (y < 100) & y_ # свернем с цилиндром 5 default mask = np.stack([disk(5) for i in range(20)]) y__ = convolve(y_n.astype(int), mask) / mask.sum() y_f = get_greatest_component(y__ > 0.85) return y_f
def limits_to_mask(limits, threshold=.3, width_ratio=.7): mask = limits >= threshold mask = get_greatest_component(mask) # take convex hull line by line in order to fill "holes" inside the brain limits_mask = apply_along_axes( lambda s: convex_hull_image(s[None])[0] if s.any() else s, mask, -1) widths = mask.sum(0) # drop the lines that are too thin - these are just outliers start, stop = mask2bounding_box( widths >= width_ratio * widths.max()).flatten() limits_mask[:, :start] = 0 return limits_mask.astype(bool)
def test_apply(self): x = np.random.rand(3, 10, 10) * 2 + 3 np.testing.assert_array_almost_equal( apply_along_axes(normalize, x, axes=(1, 2), percentiles=20), normalize(x, percentiles=20, axes=0) ) axes = (0, 2) y = apply_along_axes(min_max_scale, x, axes) np.testing.assert_array_almost_equal(y.max(axes), 1) np.testing.assert_array_almost_equal(y.min(axes), 0) np.testing.assert_array_almost_equal(apply_along_axes(identity, x, 1), x) np.testing.assert_array_almost_equal(apply_along_axes(identity, x, -1), x) np.testing.assert_array_almost_equal(apply_along_axes(identity, x, (0, 1)), x) np.testing.assert_array_almost_equal(apply_along_axes(identity, x, (0, 2)), x)
def remove_background(x): # otsu -> greatest connected component -> convex hull mask = get_greatest_component(x > threshold_otsu(x)) mask = apply_along_axes(lambda s: convex_hull_image(s) if s.any() else s, mask, (0, 1)) return x * mask