I would like to develop a routine that associates a size with images such as that below. My idea is to find the radius of the circle (centered at the origin) that contains (say) 95% of the total density. How can I achieve this? Also, are there better image processing techniques for associating a size to this region?

Date file: https://www.dropbox.com/s/1vkv7ic3o1e3fnk/data3.dat?dl=0

enter image description here

  • $\begingroup$ This site is about the software Wolfram Mathematica and not image processing. You might want to consider asking this somewhere else. $\endgroup$
    – halirutan
    Commented Feb 16, 2018 at 13:21

2 Answers 2


If img is your image, you can use Binarize to find a fixed fraction of black pixels:

img = Import["https://i.sstatic.net/T76kp.png"];
bin = Binarize[img, Method -> {"BlackFraction", .1}]

enter image description here

Then you can use ComponentMeasurements to find the centroid and radius:

comp = ComponentMeasurements[
   ColorNegate@bin, {"Centroid", "EquivalentDiskRadius", 
    "Circularity"}, #Circularity > 0.5 &];

HighlightImage[img, {comp /. (index_ -> {c_, r_, __}) :> 
    Circle[c, r]}]

enter image description here

Response to comment:

@anderstood asked why ComponentMeasurements finds two components. We can use the Mask measurement to get a binary mask for each component:

HighlightImage[img, Image[#]] & /@ 
 ComponentMeasurements[ColorNegate@bin, "Mask"][[All, 2]]

enter image description here

and see that the first component is the black border around the image.

  • $\begingroup$ That was blisteringly fast. Thanks! I'll have a play :) $\endgroup$
    – Tom
    Commented Feb 16, 2018 at 13:39
  • $\begingroup$ Why did you use ColorNegate? Also, would you know why ComponentMeasurements[bin, {"Centroid", "EquivalentDiskRadius"}] returns two circles (also with ColorNegate@bin instead of bin)? $\endgroup$
    – anderstood
    Commented Feb 16, 2018 at 13:45
  • $\begingroup$ @anderstood: I used ColorNegate because ComponentMeasurements searches for white objects on a black background - and the source image is the opposite. The second object is the black border around the image. $\endgroup$ Commented Feb 16, 2018 at 15:47

Let's look at your data in more detail. The image has a black frame around it which is taken into account! This means, that binarizing using "BlackFraction" as Niki did will lead to an incorrect result.

In fact, if you take this into account, then the frame alone contains more than 5% of your total density. Let's calculate the amount of density we want:

img = RemoveAlphaChannel[
data = ImageData[ColorNegate[img], "Real"];
thresh = .95*Total[Flatten[data]]

(* 5539.33 *)

By removing only the frame, we are well below this threshold

Total[Flatten[ArrayPad[data, -10]]]
(* 4972.88 *)

Let us remove this and calculate the 95% boundary correctly

data = ArrayPad[data, -10];
thresh = .95*Total[Flatten[data]]
(* 4724.23 *)

To create a centered disk that we can use as a mask, we can use DiskMatrix. This can be used with varying radii until we find the correct one that meets the wanted threshold:

densityDifference[r_?NumericQ] := 
 Total[Flatten[data*DiskMatrix[r, Dimensions[data]]]] - thresh
FindRoot[densityDifference[r], {r, 50, 100}, Method -> "Secant"]
(* about 69 *)

 Image@DiskMatrix[69, Reverse@ImageDimensions[img]]

Mathematica graphics


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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