Add correct subpixel boundary estimation.

This commit is contained in:
Juan Nunez-Iglesias
2015-01-22 11:38:36 +11:00
parent 9c78fce4cd
commit fb893c277d
+41 -11
View File
@@ -1,10 +1,49 @@
import numpy as np
from scipy import ndimage as nd
from ..morphology import dilation, erosion, square
from ..util import img_as_float
from ..util import img_as_float, view_as_windows, pad
from ..color import gray2rgb
def _find_boundaries_subpixel(label_img):
"""See ``find_boundaries(..., mode='subpixel')``.
Notes
-----
This function puts in an empty row and column between each *actual*
row and column of the image, for a corresponding shape of $2s - 1$
for every image dimension of size $s$. These "interstitial" rows
and columns are filled as ``True`` if they separate two labels in
`label_img`, ``False`` otherwise.
I used ``view_as_windows`` to get the neighborhood of each pixel.
Then I check whether there are two labels or more in that
neighborhood.
"""
ndim = label_img.ndim
max_label = np.iinfo(label_img.dtype).max
label_img_expanded = np.zeros([(2 * s - 1) for s in label_img.shape],
label_img.dtype)
pixels = [slice(None, None, 2)] * ndim
label_img_expanded[pixels] = label_img
edges = np.ones(label_img_expanded.shape, dtype=bool)
edges[pixels] = False
label_img_expanded[edges] = max_label
windows = view_as_windows(pad(label_img_expanded, 1,
mode='constant', constant_values=0),
(3,) * ndim)
boundaries = np.zeros_like(edges)
for index in np.ndindex(label_img_expanded.shape):
if edges[index]:
values = np.unique(windows[index].ravel())
if len(values) > 2: # single value and max_label
boundaries[index] = True
return boundaries
def find_boundaries(label_img, connectivity=1, mode='thick', background=0):
"""Return bool array where boundaries between labeled regions are True.
@@ -124,16 +163,7 @@ def find_boundaries(label_img, connectivity=1, mode='thick', background=0):
boundaries &= (background_image | adjacent_objects)
return boundaries
else:
label_img_expanded = np.zeros([(2 * s - 1) for s in label_img.shape],
label_img.dtype)
pixels = [slice(None, None, 2)] * ndim
selem = nd.generate_binary_structure(ndim, ndim)
label_img_expanded[pixels] = label_img
max_label = np.iinfo(label_img.dtype).max
label_img_edge_inverted = np.array(label_img_expanded, copy=True)
label_img_edge_inverted[label_img_expanded == 0] = max_label
boundaries = (dilation(label_img_expanded, selem) !=
erosion(label_img_edge_inverted, selem))
boundaries = _find_boundaries_subpixel(label_img)
return boundaries