I have this image:
I would like to separate qualitatively 4 different regions into approximately such an image:
The colors or gray shadings of the regions do not matter.
How can this be achieved with Mathematica?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI will rely on the assumption that the noise will blend into different intensities for each desired component.
A Kuwahara filter is good at removing uniform noise from an image while preserving edges. Here the noise is 'locally uniform' and the edges we seek are the boundaries where the noise noticeably changes. So a Kuwahara filter can help, but admittedly might not be the best choice of filter for this task:
im = ColorConvert[RemoveAlphaChannel[Import["https://i.stack.imgur.com/OWfLp.png"]], "Grayscale"];
kuw = KuwaharaFilter[im, 10]
This filter uses a square kernel and therefore looks splotchy. We can do our best to smooth it:
smooth = ImageAdjust[CurvatureFlowFilter[MeanFilter[kuw, 10], 50]];
Before and after:
{im, smooth}
From here we can cluster, but note that my attempt is hand wavy and misses the 4th component:
cov = DominantColors[smooth, Automatic, "CoverageImage"];
HighlightImage[im,
MapIndexed[{ColorData[111] @@ #2,
DeleteSmallComponents[FillingTransform[#]]} &, cov]]
As an option
image = Import["https://i.stack.imgur.com/OWfLp.png"];
im = ImageData[image];
d = ImageDimensions[image];
f = Interpolation[
Flatten[Table[{i, j, First[im[[i, j]]]}, {i, 1, d[[2]]}, {j, 1,
d[[1]]}], 1]];
ImageReflect[
DensityPlot[f[x, y], {y, d[[1]], 1}, {x, 1, d[[2]]},
ColorFunction -> "Rainbow", AspectRatio -> Automatic,
PlotPoints -> 200, Frame -> False]]
Can also be used
t = Flatten[
Table[{i, j, First[im[[i, j]]]}, {i, 1, d[[2]]}, {j, 1, d[[1]]}],
1];
ListDensityPlot[t, Frame -> False, ColorFunction -> "Rainbow",
AspectRatio -> Automatic]
Clustering gives a less clear result.
ClusteringComponents[image, 6] // Colorize
ImageFilter[ Module[{m = Mean@Flatten@#}, If[m < .25, .25, If[.5 > m >= .25, .5, If[.75 > m >= .5, .75, If[ m >= .75, 1]]]] ] &, ImageAdjust@i, 10]
, and changing the tolerances, although I'm sure there are better ways to write that code. $\endgroup$ClusteringComponents
could help, but it has a ton of options and knobs requiring a lot of experimentation. Something likeimage=Import["https://i.stack.imgur.com/OWfLp.png"]; Colorize@ClusteringComponents[image, Method -> {"Spectral", "NeighborhoodRadius" -> 0.2}]
but with better parameters and more post-processing. $\endgroup$