# Trainable WEKA segmentation of images

Is there a Mathematica equivalent of Trainable WEKA Segmentation as implemented in Fiji, the image processing software? A Google search did not return any relevant links.

I attach the original image and the image after WEKA segmentation using Fiji. I would like to generate similar results in Mathematica. The closest result I was able to get was when using the approach detailed here (see bottom image). The particles are not completely black, and the region in-between particles are not fully white.

Original image

Trainable WEKA Segmentation from FIJI

Mathematica result using this method

## Edit

The use of two median filters is the bottleneck of my method, and you indicated in a comment on nikie's answer that speed might be of importance to you.

You can replace MedianFilter[] by TotalVariationFilter for essentially the same results, but a 10x speed-up, as below.

For images where the background is less variable, or the noise is less, you might get away with a single filter, rather than worrying about subtracting the background first.

img = ImageAdjust@
ImageCrop[
Import["http://i.stack.imgur.com/GzLZh.jpg"], {223, 223}];

AbsoluteTiming[
tvFilteredImg =
TotalVariationFilter[img, 0.7, Method -> "Poisson"],
TotalVariationFilter[img, 10, Method -> "Poisson"]
];
morphImg = MorphologicalTransform[Binarize[tvFilteredImg], "Commonest"];
closingImg = Closing[morphImg, DiskMatrix[10]];
result = Colorize[MorphologicalComponents[ColorNegate@closingImg]];
]
(* 0.12 seconds, compared to 1.1 seconds for the MedianFilter[] version *)


## Original

Ouch that's a noisy image! Here goes...a method that isn't WEKA filtering, but seems to work well.

First, I had to crop out the white bands at the top/bottom of your image.

img = ImageAdjust@ImageCrop[Import["http://i.stack.imgur.com/GzLZh.jpg"], {223, 223}];


Next, I applied two differently-sized median filters and subtracted one from the other to make the image a bit easier to work with in terms of both noise and the varying background.

GraphicsRow[{
ImageSubtract[MedianFilter[img, 3], MedianFilter[img, 20]]},
ImageSize -> Full]

ImageSubtract[MedianFilter[img, 3], MedianFilter[img, 20]];


Next I binarized the image, applied a morphological transform to smooth out the result, and finally deleted the small components that weren't part of the desired result.

morphImg = MorphologicalTransform[
Binarize[medFilteredImg, Method -> "Cluster"], "Commonest"]
finalImg = DeleteSmallComponents[morphImg, 20]


Finally, one can apply a Closing to the image to fill in some of those gaps.

Closing[finalImg, DiskMatrix[10]]
MorphologicalComponents[ColorNegate@%] // Colorize


The results are pretty nice - with a bit of tweaking to the various parameters (especially the MedianFilter[]) then this works well.

• Indeed your new code is much faster. But there seems to be issues with other images similar to the one I posted and at higher magnification. I guess the parameters need to be optimized for each image. But that's a drawback for my application, and one of the main reason I wanted to work with Mathematica rather than Fiji so I can process a batch of images. Also, in your new iteration, you got rid off (* DeleteSmallComponents[morphImg, 20] *)...not sure why? How do I send a new pic that showed issues? Jul 2, 2015 at 19:13
• I removed the DeleteSmallComponents[morphImg, 20] because I don't think the TV filter needed it. Jul 2, 2015 at 19:15
• As for optimizing the parameters I'm not sure. Can't FIJI process batches anyway? Jul 2, 2015 at 19:15
• Fiji can certainly process batches, but the Training Weka segmentation requires to set the classifiers "manually" ...i.e select boundary areas and particle areas. I have to process about 50 images on a regular basis, and was hoping to have a code in mathematica that woudl allow that and still provide the same quality results as Fiji. Jul 2, 2015 at 19:52

If you're looking for a "machine learning" solution, could you describe how the "weka segmentation" works - Mathematica has some machine learning functionality (though not nearly as extensive as WEKA), maybe it's possible to get similar results with Classify.

If you're looking for a "classic" fixed filter based approach, you could start with a RidgeFilter, to find the "cell walls" between the particles:

img = ColorConvert[Import["http://i.stack.imgur.com/GzLZh.jpg"],
"Grayscale"];


(where 5 is an estimate of the thickness of the cell borders)

Simply binarizing the result with default thresholds seems to find the right borders:

HighlightImage[img, MorphologicalBinarize[RidgeFilter[img, 5]]]


And the negative image can be used for connected component analysis

Colorize[MorphologicalComponents[
ColorNegate[MorphologicalBinarize[RidgeFilter[img, 5]]]]]


If you want to smooth the original image, you could use some total variation based filter (because the result you want is - more or less - piecewise constant), or a CurvatureFlowFilter (because you want smoothing along edges, not across edges):

deconvolve=ImageDeconvolve[img, GaussianMatrix[5],
Method -> {"TotalVariation", "Regularization" -> 2}]


You can then use ClusteringComponents to group together particles and boundaries in different clusters (Binarize doesn't work well here, because the image has more than two dominant brightness values):

Colorize[ClusteringComponents[deconvolve]]


• Thank you Nikie, Your approach seems to compute faster than the first response on my laptop. However, the RidgeFilter actually affects the size of the particles. By setting an aribtrary boundary thickness, the size of the particles would be affected , and in the extreme case that the particles are touching in the original image, they would appeared disconnected on the image after processing. What could be an alternative to RidgeFilter Jul 1, 2015 at 21:22
• @JMarc if speed is an issue for you, is the updated method in my answer any better? Jul 2, 2015 at 6:51