Cleaning ImageMorphology boundary data

Hi all, this is my first post on discourse so apologies in advance if I haven’t formatted things correctly. I have read the “Please read: make it easier to help you” discussion.

I have a matrix of float values representing probabilities as matrix saved in JLD2, see here. I am trying to find the contour line corresponding to a given chance value. Currently I am using creating a “safe region” matrix of bits where true values correspond to values of the probabilities matrix that are below the chance value, then using the isboundary function I find the boundary of this region. Here is my code so far:

using CairoMakie, Images, ImageMorphology, JLD2, Statistics

# Load probability data (50x50 matrix of floats)
A = load("probability.jld2", "data");

# Find probability contour
chance_threshold = 0.9
safeRegion = falses(size(A)) # Find regions where the probability is below the threshold
safeRegion[findall(x->x<chance_threshold, A)] .= true
B = isboundary(safeRegion) # Find the boundary of the region i.e. contour of A with value `chance_threshold`

# Cleaning contour data by removing small objects
labels = label_components(B, strel_box((3, 3)))
counts = component_lengths(labels)
C = area_opening(B; min_area=quantile(counts.parent,0.95), connectivity=2)

# Plot heatmap of the probability data and the contour
fig = Figure(size=(1000, 500))
ax = CairoMakie.Axis(fig[1, 1], title="Probability Heatmap w/ Raw Contour")
ax2 = CairoMakie.Axis(fig[1, 2], title="Probability Heatmap w/ Cleaned Contour")

heatmap!(ax, A)
heatmap!(ax, B, colormap=[(:white, 0.0), (:red, 1.0)])

heatmap!(ax2, A)
heatmap!(ax2, C, colormap=[(:white, 0.0), (:red, 1.0)])

fig

Which produces

On the right I have cleaned some of the data by selecting only the 95% length connected components. I was wondering if anyone had advice on further cleaning this data, and possibly how to extend this to higher dimensions, where the probabilities matrix is greater than 2D. Thanks in advance

1 Like

Can you please share an image with the expected result? You can draw the result with any drawing tool and paste it here.

Yes I should have specified, my bad, I am hoping for it to look similar to this:

It doesn’t have to be exactly one pixel thick line, there can be a little noise, but i’d like to have a general way of removing the more intracate geometries seen around x=15, y=30. I am unsure if this helps but I only really care about boundary points that are “path reachable” from say the blue point near x=40,y=30

I believe this result can be achieved with a geostatistical clustering method. You can ask for 2 clusters before or after binarization of the continuous probability values. The parameters of the method will dictate the final clusters. Given the final clusters it is easy to extract the boundary.

Try some of these clustering methods to see if they produce decent results:

Clustering · GeoStats.jl Clustering · GeoStats.jl

1 Like

Alternatively you could consider smoothing the continuous map with a window filter (see ImageFiltering.jl) and then applying other algorithms to split the image into two parts.

1 Like

Thanks for your response, @juliohm, I’ve tried applying some of the clustering methods in GeoStats, and I see that the boundary between the two regions of can be extracted in this case. However I’d like to if possible in general, find probability contours for any given chance value. I am not overly familar with the library so may have missed something, but I don’t believe there is a way to obtain clusters with specific average values?
This works for the data in the above case because the contour bisects the 2 “main” regions, and the geo clusters can identify the split between 2 regions, so they happen to coincide. I think I have come up with a way just using image morphology, but it is not perfect as it ignores some potentially important qualities such as a smaller but still significant boundary disconnected from the “main” boundary.

  1. Take the complement of the boundary, find all its connected components
  2. Find the connected region containing a “point of interest”
  3. Find the boundary of that connected region

This is the idea applied to original problem posed, with results from the GeoStats clustering:


The distinct connected components in Morphology Cleaning (1/3) are highlighted in different colours, and the gold X marks the point of interest.

Here is the same idea applied to some other data with a less simple geometry and a contour at 45%:

Thanks again for taking the time to give my problem some thought, and if you think I misunderstood anything you’ve said please let me know!

From your response, I believe you are just interested in the Indicator transform followed by a ModeFilter? It can segment the image into intervals of probability that you can extract by index.

Are you referring to the Indicator Transform listed in TableTransforms.jl? If so once I’ve applied that to the data I get nearly identical results to the raw output for the morphology boundary


I haven’t been able to find a ModeFilter in the GeoStats or TableTransforms documention. I think I have the result I need by algorithm detailed in my previous response so I’ll set the post as solved. I’m open to any suggestions if you think differently. If not, thanks for responding :grinning_face_with_smiling_eyes:

The ModeFilter is exported by GeoStatsTransforms.jl as part of the GeoStats.jl stack. So it should be available upon loading GeoStats.jl. It takes the output shared above and smooths it out.