You already did it. By inverting the Canny output, you labelled the holes in the image instead of the edges. To label the edges correctly, you would need to label with connectivity=2. This would give you a non-rainbowy coloring of the canny output. (Only two colors, the inner and the outer ring.)
On 9 Jan 2018, 1:31 PM +1100, Randy Heiland <randy.heil...@gmail.com>, wrote: > Sorry to be dense, but could you elaborate on "labeling the holes rather than > edges"? What lines would I tweak in my script? > > > On Mon, Jan 8, 2018 at 9:20 PM, Juan Nunez-Iglesias <jni.s...@gmail.com> > > wrote: > > > Ah, your issue with the thickening was that label by default does not > > > consider diagonally-adjancent pixels as adjacent. You need to pass > > > connectivity=2 for this to be the case. But actually labelling the holes > > > rather than the edges is a rather better option. =) The final image looks > > > very pretty and could make a nice company logo. =P > > > > > > On 9 Jan 2018, 1:03 PM +1100, Randy Heiland <randy.heil...@gmail.com>, > > > wrote: > > > > Argh. Nevermind... need to flip black/white on canny edges: 1-(edges*1) > > > > > > > > > > > > > > > > > On Mon, Jan 8, 2018 at 8:55 PM, Randy Heiland > > > > > <randy.heil...@gmail.com> wrote: > > > > > > Thanks Juan. I understand better what the ndi.measurements.label > > > > > > can do for me now. I've tweaked my previous script and attached the > > > > > > resulting output. Does it make sense that I need to "thicken" the > > > > > > contours in order to get the desired features/regions, or is there > > > > > > something I'm still missing? > > > > > > > > > > > > ------------ > > > > > > from skimage.morphology import disk > > > > > > from skimage.feature import canny > > > > > > from skimage.filters import rank > > > > > > from scipy import ndimage as ndi > > > > > > import matplotlib.pyplot as plt > > > > > > import numpy as np > > > > > > > > > > > > image = disk(100) > > > > > > for ix in range(200): > > > > > > for iy in range(200): > > > > > > xdel=ix-100 > > > > > > ydel=iy-100 > > > > > > if (xdel*xdel/50 + ydel*ydel/10) < 110: > > > > > > image[iy,ix]=0 > > > > > > elif (xdel*xdel/10 + ydel*ydel/50) < 110: > > > > > > image[iy,ix]=0 > > > > > > > > > > > > edges = canny(image*255.) # canny expect grayscale, i.e. 0-255 ??! > > > > > > > > > > > > thicken = rank.gradient(edges, disk(1)) < 5 > > > > > > bdy = thicken.astype(np.uint8)*255 > > > > > > > > > > > > labeled_array, num_features = ndi.measurements.label(edges*1) > > > > > > print("num_features (edges*1)=",num_features) > > > > > > labeled_array2, num_features2 = ndi.measurements.label(bdy) > > > > > > print("num_features (thick)=",num_features2) > > > > > > > > > > > > fill = ndi.binary_fill_holes(edges) > > > > > > > > > > > > fig, axes = plt.subplots(ncols=2, nrows=2, figsize=(6, 7)) > > > > > > ax = axes.ravel() > > > > > > > > > > > > ax[0].imshow(edges*1, cmap=plt.cm.gray, interpolation='nearest') > > > > > > ax[0].set_title('Canny edges') > > > > > > ax[1].imshow(labeled_array, cmap=plt.cm.spectral, > > > > > > interpolation='nearest') > > > > > > ax[1].set_title('labeled_array') > > > > > > > > > > > > ax[2].imshow(bdy, cmap=plt.cm.gray, interpolation='nearest') > > > > > > ax[2].set_title('bdy') > > > > > > ax[3].imshow(labeled_array2, cmap=plt.cm.spectral, > > > > > > interpolation='nearest') > > > > > > ax[3].set_title('labeled_array2') > > > > > > > > > > > > plt.axis('off') > > > > > > plt.show() > > > > > > > > > > > > --> > > > > > > num_features (edges*1)= 216 > > > > > > num_features (thick)= 6 > > > > > > > > > > > > -Randy > > > > > > > > > > > > > > > > > > > On Sun, Jan 7, 2018 at 11:36 PM, Juan Nunez-Iglesias > > > > > > > <jni.s...@gmail.com> wrote: > > > > > > > > Oh, I see what's happening. So, in your case, both void spaces > > > > > > > > are actually holes from the perspective of the > > > > > > > > binary_fill_holes algorithm, so they both get filled. I suggest > > > > > > > > you > > > > > > > > > > > > > > > > a) label both contours using ndi.label > > > > > > > > b) use binary_fill_holes on each label separately > > > > > > > > c) subtract the filled inner hole from the filled outer hole > > > > > > > > (you can optionally add back in the inner contour if you care > > > > > > > > about that single-pixel precision) > > > > > > > > > > > > > > > > This requires being able to robustly identify the inner and > > > > > > > > outer contours, but I don't think that should be too hard? If > > > > > > > > you only have two, you can certainly find them by finding the > > > > > > > > "larger" of the two bounding boxes. You can use > > > > > > > > skimage.measure.regionprops for this. > > > > > > > > > > > > > > > > I hope that helps! > > > > > > > > > > > > > > > > Juan. > > > > > > > > > > > > > > > > On 8 Jan 2018, 12:21 PM +1100, Randy Heiland > > > > > > > > <randy.heil...@gmail.com>, wrote: > > > > > > > > > Sure - thanks. > > > > > > > > > > > > > > > > > > from skimage.morphology import disk > > > > > > > > > from skimage.feature import canny > > > > > > > > > from scipy import ndimage as ndi > > > > > > > > > import matplotlib.pyplot as plt > > > > > > > > > > > > > > > > > > image = disk(100) > > > > > > > > > for ix in range(200): > > > > > > > > > for iy in range(200): > > > > > > > > > xdel=ix-100 > > > > > > > > > ydel=iy-100 > > > > > > > > > if (xdel*xdel/50 + ydel*ydel/10) < 110: > > > > > > > > > image[iy,ix]=0 > > > > > > > > > elif (xdel*xdel/10 + ydel*ydel/50) < 110: > > > > > > > > > image[iy,ix]=0 > > > > > > > > > > > > > > > > > > edges = canny(image*255.) # canny expect grayscale, i.e. > > > > > > > > > 0-255 ??! > > > > > > > > > > > > > > > > > > fill = ndi.binary_fill_holes(edges) # I don't understand > > > > > > > > > the params; can I seed a region to fill? > > > > > > > > > > > > > > > > > > fig, axes = plt.subplots(ncols=3, figsize=(9, 3)) > > > > > > > > > ax = axes.ravel() > > > > > > > > > > > > > > > > > > ax[0].imshow(image, cmap=plt.cm.gray, interpolation='nearest') > > > > > > > > > #ax[0].imshow(invert_img, cmap=plt.cm.gray) > > > > > > > > > #ax[0].set_title('Inverted image') > > > > > > > > > ax[0].set_title('Original image') > > > > > > > > > > > > > > > > > > ax[1].imshow(edges*1, cmap=plt.cm.gray, > > > > > > > > > interpolation='nearest') > > > > > > > > > ax[1].set_title('Canny edges') > > > > > > > > > > > > > > > > > > ax[2].imshow(fill, cmap=plt.cm.spectral, > > > > > > > > > interpolation='nearest') > > > > > > > > > ax[2].set_title('Fill') > > > > > > > > > > > > > > > > > > plt.show() > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Sun, Jan 7, 2018 at 6:57 PM, Juan Nunez-Iglesias > > > > > > > > > > <jni.s...@gmail.com> wrote: > > > > > > > > > > > Hi Randy, I was going to suggest binary fill holes. Do > > > > > > > > > > > you mind posting your image and the code you’ve tried so > > > > > > > > > > > we can troubleshoot? > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > > > Juan. > > > > > > > > > > > > > > > > > > > > > > On 8 Jan 2018, 9:48 AM +1100, Randy Heiland > > > > > > > > > > > <randy.heil...@gmail.com>, wrote: > > > > > > > > > > > > If I have a binary image with, say, just a contour > > > > > > > > > > > > boundary (simple example: a white background with a > > > > > > > > > > > > black circle, i.e. an "o"), how can I fill the inside > > > > > > > > > > > > of the contour? I've played with both the watershed > > > > > > > > > > > > segmentation and the scipy.ndimage.binary_fill_holes, > > > > > > > > > > > > without success. > > > > > > > > > > > > > > > > > > > > > > > > thanks, Randy > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > > > scikit-image mailing list > > > > > > > > > > > > scikit-image@python.org > > > > > > > > > > > > https://mail.python.org/mailman/listinfo/scikit-image > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > > scikit-image mailing list > > > > > > > > > > > scikit-image@python.org > > > > > > > > > > > https://mail.python.org/mailman/listinfo/scikit-image > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > scikit-image mailing list > > > > > > > > > scikit-image@python.org > > > > > > > > > https://mail.python.org/mailman/listinfo/scikit-image > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > scikit-image mailing list > > > > > > > > scikit-image@python.org > > > > > > > > https://mail.python.org/mailman/listinfo/scikit-image > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > scikit-image mailing list > > > > scikit-image@python.org > > > > https://mail.python.org/mailman/listinfo/scikit-image > > > > > > _______________________________________________ > > > scikit-image mailing list > > > scikit-image@python.org > > > https://mail.python.org/mailman/listinfo/scikit-image > > > > > _______________________________________________ > scikit-image mailing list > scikit-image@python.org > https://mail.python.org/mailman/listinfo/scikit-image
_______________________________________________ scikit-image mailing list scikit-image@python.org https://mail.python.org/mailman/listinfo/scikit-image