# Segmentation of different components from a relatively low contrast image

I have a digital image from X-ray tomography as below:

There are three different ingredients/components to be segmented:

1. the continuous phase, mastics;
2. the discrete phase I, aggregates;
3. the discrete phase II, voids

which are all visually legible though the contrast is low:

I tried several approaches for segmentation, and the currently best result is only like this:

1.voids:

img=Import["http://i.stack.imgur.com/9q5QX.png"];

cellEdges=GradientFilter[ImageAdjust[img], 2]//ImageAdjust//Binarize;

voids = Closing[cellEdges, 3]


2.aggregates and mastics,

agg01=ImageFilter[Mean[Flatten[#]]&,LocalAdaptiveBinarize[img, 15],2];
agg02=GeodesicOpening[agg01, 5];
agg03=GeodesicOpening[agg02, 5]


The obtained discrete phase of aggregates looks continuous especially on the edge of the circular region; aggregates should be isolated islands with no black dots expected on them, but the current segmentation does not seem to achieve this.

Such a segmentation differs significantly from its visual inspection. How can I improve it?

## 1 Answer

I'm not sure if this is any improvement at all, but maybe it will at least serve as a hint on other approaches that might work in a desired way.

I'm creating 7 images, so I'll display only the final one here. You might want to look at the intermediate steps as well.

img = ImageCrop @ Import["http://i.stack.imgur.com/9q5QX.png"]
ImageHistogram @ img


Black corresponds to zero, and we see that there are two main peaks at around 0.55 and 0.75. Unfortunately, the overlap is so strong that we cannot simply filter out the low-intensity pixels. Instead

img2 = GaussianFilter[#, 1] &@ImageAdjust@ColorToneMapping[#, 0.5] &@img


which has

ImageHistogram @ img2


from which I choose 0.96 for

img3 = Binarize[img2, 0.96, Method -> "MinimumError"]
img4 = GaussianFilter[#, 3] &@img3
img5 = CommonestFilter[#, 3] &@img4
img6 = KuwaharaFilter[#, 3] &@img5
img7 = Closing[#, 1] & @ LocalAdaptiveBinarize[img6, 20]
img8 = FillingTransform@
DeleteSmallComponents[#, 55, Method -> "Mean"] &@img7


(You can also use DeleteSmallComponents[#, 200] & on img8.)

Certainly not perfect as some features look rather bad (e.g., the big rapezoidal island in the bottom part is destroyed, and the big black stain completely surrounded by white in the upper right part), but several of them are very accurate, and the features near the edges are separated better.

The thing is, that the features in the middle are quite well separated, while those near the edges are tightly clustered. In such a situation maybe the initial img should be divided into two parts - the inner circle and the outer ring - and processed separately, with different parameters of the functions applied, and joined at the end.

• Thank you! Actually, I have got a series of such low contrast digital images of nearly 1000 slicers. That's why I prefer batch segmentation via Mathematica/Python/Matlab scripts. However, it seems there is no simple method to obtain as good results as those by hand. – user6043040 Sep 30 '16 at 5:11