# Image Processing: Concrete test blocks

Background

Concrete is mixture of aggregates and cement. Aggregates are composed of different sizes and colors. Core samples are taken by drilling in order to test the strength of concrete . They are usually in cylindrical form. See the image below. I want to detect the circle of the cylinder and aggregates as well as calculate the areas.

Question

I have many images similar to this one.

May Questions are :

1. How can I remove the background and detect the circle?
2. How can I find the shape of aggregates calculate the areas?

PS: I'm well aware of related Questions on this site but most of them end up with failure.

Edit 1 Thank you shrx for the first part of the Q

Code

img= Import["http://i.stack.imgur.com/tNcYK.jpg"]

circles = SelectComponents[MorphologicalComponents[
LaplacianGaussianFilter[
ColorNegate@DeleteSmallComponents@Closing[EdgeDetect[i, 3], 11],
2], 0.0056],
"Count", # > 600 &];
cm = ComponentMeasurements[circles, "MeanCentroidDistance"]
ct = 1 /. ComponentMeasurements[FillingTransform@i1, "Centroid"];
Show[i, Graphics[{Thick, Red, Circle[ct, cm[[1, 2]]]}]]


-

Here's a possible approach for the aggregates.

I've used a scaled down image (it was faster to experiment with) and adjusted the gamma to try to bring out the colour variations. I've also masked out the background (I estimated the circular region by eye but you could of course use your ComponentMeasurements code)

i = Import["C:\\Users\\Simon\\Desktop\\tNcYK.jpg"];
i2 = ImageResize[i, Scaled[0.3]] ~ImageAdjust~ {0, 0, 1.5};
i2 = Image[ImageData[i2] RotateLeft[DiskMatrix[190, Reverse@ImageDimensions@i2], {0, 3}]]


I used ImageForestingComponents to try to identify the different regions:

Colorize[c = ImageForestingComponents[i2, Automatic, 1]]


I keep only the large components, and apply a CommonestFilter to smooth the edges a bit:

Colorize[c = DeleteSmallComponents[c, 300] ~CommonestFilter~ 1]


Now compute the "Mask" and "Area" of each component (sorted by area)

cm = SortBy[ComponentMeasurements[c, {"Mask", "Area"}][[All, 2]], Last] // Reverse;

Grid[{ImageCrop[i2 ~ImageMultiply~ Image[#1]], #2} & @@@ Rest@cm]


This shows the component outlines superimposed on the image:

ImageSubtract[i2, Image@Total[GradientFilter[#1, 1] & @@@ cm]]


-
Thank you for the nice answer! It was quite OK. I'm now testing with other images... A side note: usually there is no need for deleting small components. It is also useful information for modelling. –  s.s.o Jun 19 '13 at 22:12

Applying

Closing[EdgeDetect[image, 3], 5]


Produces a well defined image:

edit: another option:

Binarize[ImageAdjust[TopHatTransform[image, DiskMatrix[20]]]]


After this, it's the same procedure as in the related examples you've found.

-
One way to approach the segmentation of images like this is to make use of the different colorspace representations. For example, applying the LAB colorspace to the original image allows separating the image into three pieces
ImageAdjust /@ ColorSeparate[img, "LAB"]
`