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

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.