I have this image:

enter image description here

I would like to separate qualitatively 4 different regions into approximately such an image:

enter image description here

The colors or gray shadings of the regions do not matter.

How can this be achieved with Mathematica?

  • 1
    $\begingroup$ Also, you should provide proper unmodified example data. The image in the post is upscaled. It looks like a screenshot. $\endgroup$
    – Szabolcs
    Mar 12, 2019 at 11:38
  • 1
    $\begingroup$ Another option is something like 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$
    – Carl Lange
    Mar 12, 2019 at 11:47
  • 2
    $\begingroup$ You might want to try this Fiji plugin (it's not Mathematica though): imagej.net/Labkit $\endgroup$
    – Szabolcs
    Mar 12, 2019 at 12:56
  • 2
    $\begingroup$ If it's from a publication, then you could open the PDF in Acrobat and do an "Export All Images" to get raw image data to upload. $\endgroup$
    – Roman
    Mar 12, 2019 at 14:53
  • 1
    $\begingroup$ ClusteringComponents could help, but it has a ton of options and knobs requiring a lot of experimentation. Something like image=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$
    – Roman
    Mar 12, 2019 at 15:43

2 Answers 2


I 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]

enter image description here

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}

enter image description here

From here we can cluster, but note that my attempt is hand wavy and misses the 4th component:

cov = DominantColors[smooth, Automatic, "CoverageImage"];

 MapIndexed[{ColorData[111] @@ #2, 
    DeleteSmallComponents[FillingTransform[#]]} &, cov]]

enter image description here


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]];

 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]]}], 

ListDensityPlot[t, Frame -> False, ColorFunction -> "Rainbow", 
 AspectRatio -> Automatic]

Clustering gives a less clear result.

ClusteringComponents[image, 6] // Colorize


  • 1
    $\begingroup$ I don't see how this answers the OP's question. You did not segment the image into the four requested regions. $\endgroup$
    – Szabolcs
    Mar 12, 2019 at 15:47
  • 1
    $\begingroup$ @Szabolcs I hope that OP understands the criterion by which he identified 4 areas. He himself did not offer any code. $\endgroup$ Mar 12, 2019 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.