# import back image
cfthdr=io.imread('filled_contour_THDR.png')
cfthdr = color.rgb2gray(cfthdr) > 0.5
# clean it up with opening
selem17 = disk(17)
opened_thdr = opening(cfthdr, selem17)/255
# plot it
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(1, 1, 1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(opened_thdr,cmap='bone')
plt.show()
# not bad
With remove_small_objects the advantage is that it does not join blobs in the original:cfthdr_inv = ~cfthdr
test=remove_small_objects(cfthdr,10000)
# plot it
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(1, 1, 1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(test,cmap='bone')
plt.show()
# filling holes with morphological reconstruction
seed = np.copy(cfthdr_inv)
seed[1:-1, 1:-1] = cfthdr_inv.max()
mask = cfthdr_inv
filled = reconstruction(seed, mask, method='erosion')
# plot it
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(1, 1, 1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(filled,cmap='bone',vmin=cfthdr_inv.min(), vmax=cfthdr_inv.max())
plt.show()
Hi Matteo,My guess is that even though you are looking at a "black and white" image, the png is actually an RGB png. Just check the output of "print(cfthdr.shape)". Should be straightforward to make it a binary image:from skimage import colorcfthdr = color.rgb2gray(cfthdr) > 0.5Then you should have a binary image. (And inverting should be as simple as "cfthdr_inv = ~cfthdr") We have morphology.binary_fill_holes to do what you want.btw, there's also morphology.remove_small_objects, which does exactly what you did but as a function call. Finally, it looks like you are not using the latest version of scikit-image (0.11), so you might want to upgrade. Hope that helps!Juan.On Thu, Mar 26, 2015 at 8:48 AM, Matteo <matteo....@gmail.com> wrote:
<filled_contours.png>--Issues with morphological filters when trying to remove white holes in black objects in a binary images. Using opening or filling holes on inverted (or complement) of the original binary.Hi thereI have a series of derivatives calculated on geophysical data.
Many of these derivatives have nice continuous maxima, so I treat them as images on which I do some cleanup with morphological filter.
Here's one example of operations that I do routinely, and successfully:
# threshold theta map using Otsu method
thresh_th = threshold_otsu(theta)
binary_th = theta > thresh_th
# clean up small objects
label_objects_th, nb_labels_th = sp.ndimage.label(binary_th)
sizes_th = np.bincount(label_objects_th.
ravel()) mask_sizes_th = sizes_th > 175
mask_sizes_th[0] = 0
binary_cleaned_th = mask_sizes_th[label_objects_
th] # further enhance with morphological closing (dilation followed by an erosion) to remove small dark spots and connect small bright cracks
# followed by an extra erosion
selem = disk(1)
closed_th = closing(binary_cleaned_th, selem)/255
eroded_th = erosion(closed_th, selem)/255
# Finally, extract lienaments using skeletonization
skeleton_th=skeletonize(
binary_th) skeleton_cleaned_th=
skeletonize(binary_cleaned_th) # plot to compare
fig = plt.figure(figsize=(20, 7))
ax = fig.add_subplot(1, 2, 1)
imshow(skeleton_th, cmap='bone_r', interpolation='none')
ax2 = fig.add_subplot(1, 3, 2)
imshow(skeleton_cleaned_th, cmap='bone_r', interpolation='none')
ax.set_xticks([])
ax.set_yticks([])
ax2.set_xticks([])
ax2.set_yticks([])Unfortunately I cannot share the data as it is proprietary, but I will for the next example, which is the one that does not work.There's one derivative that shows lots of detail but not continuous maxima. As a workaround I created filled contours in Matplotlib
exported as an image. The image is attached.
Now I want to import back the image and plot it to test:
# import back image
cfthdr=io.imread('filled_
contour.png') # threshold using using Otsu method
thresh_thdr = threshold_otsu(cfthdr)
binary_thdr = cfthdr > thresh_thdr
# plot it
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(1, 1, 1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(binary_thdr, cmap='bone')
plt.show()
The above works without issues.
Next I want to fill the white holes inside the black blobs. I thought of 2 strategies.
The first would be to use opening; the second to invert the image, and then fill the holes as in here:
http://scikit-image.org/docs/
dev/auto_examples/plot_holes_ and_peaks.html By the way, I found a similar example for opencv here
http://stackoverflow.com/
questions/10316057/filling- holes-inside-a-binary-object Let's start with opening. When I try:selem = disk(1)
opened_thdr = opening(binary_thdr, selem)
or:
selem = disk(1)
opened_thdr = opening(cfthdr, selem)
I get an error message like this:
------------------------------
------------------------------ --------------- ValueError
Traceback (most recent call last) <ipython-input-49-
edc0d01ba327> in <module>() 1 #binary_thdr=img_as_float(
binary_thdr,force_copy=False) ----> 2 opened_thdr = opening(binary_thdr, selem)/255
3
4 # plot it
5 fig = plt.figure(figsize=(5, 5))
C:\...\skimage\morphology\
grey.pyc in opening(image, selem, out) 160 shift_y = True if (h % 2) == 0 else False
161
--> 162 eroded = erosion(image, selem)
163 out = dilation(eroded, selem, out=out, shift_x=shift_x, shift_y=shift_y)
164 return out
C:\...\skimage\morphology\
grey.pyc in erosion(image, selem, out, shift_x, shift_y) 58 selem = img_as_ubyte(selem)
59 return cmorph._erode(image, selem, out=out,
---> 60 shift_x=shift_x, shift_y=shift_y)
61
62
C:\...\skimage\morphology\
cmorph.pyd in skimage.morphology.cmorph._ erode (skimage\morphology\cmorph.c: 2658)() ValueError: Buffer has wrong number of dimensions (expected 2, got 3)
------------------------------
------------------------------ --------------- Any idea of what is going on and how I can fix it?
As for inverting (or finding the complement) and then hole filling, that would be my preferred option.
However, I have not been able to invert the image. I tried numpy.invert, adapting the last example from here:
http://docs.scipy.org/doc/
numpy/reference/generated/ numpy.invert.html I tried something like this:
http://stackoverflow.com/a/
16724700 and this:
http://stackoverflow.com/a/
2498909 But none of these methods worked. Is there a way in scikit.image to do that, and if not, do you have any suggestions?
Thank you,
Matteo
You received this message because you are subscribed to the Google Groups "scikit-image" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image...@googlegroups.com .
For more options, visit https://groups.google.com/d/optout .