# Mask outliers in an image

I'm using Binarization/Morphological Operators to detect apples as objects, which has gotten me so far:

I did get the mask using this code

{c, r} = 1 /. ComponentMeasurements[binarizedImg, {"Centroid", "EquivalentDiskRadius"}];
Show[img, Graphics[{Red, Circle[c, r]}]]
{w, h} = ImageDimensions[img];
disk = ColorConvert[ColorNegate@Graphics[{Black, Disk[c, r]}, ImageSize -> {w, h}], "Grayscale"]
dat = disk // ImageData;


What I want to do is: I want to mask the outliners in the image within the mask. Outliners means the pixels which are too bright (not necessarily saturated completely, but just too bright because of the used halogen lamps).

As I got the mask as a disk-image, I know exactly the pixel-indices of the pixels relevant for the outlier detection. I'm currently retrieving the relevant pixels using:

idx = Position[dat, 1.];
maskPx = Extract[img // ImageData, idx]


Now maskPx contains the gray-values of the apple within the mask. I can do the outlier detection, that's not the problem. The problem is: How to get the indices of the pixels which are outliers (and thus need to be removed)? Because I want to map this back and make the mask black at those points/regions. This would yield in this case something like this:

Any ideas? Thanks

EDIT: Sorry for the late reply. @belisarius: The Motivation is: I want to use the grey-values of all the pixels within the red circle (i.e. the pixels that lay behind the white disk-mask) in another algorithm that comes after the masking (thats is a fitting algorithm). But first I want to make sure to detect the outliers correctly and therefore display the mask to the user (just overlaying it with the original image) so that he is able to accept/reject the calculated mask.

Here's one original image:

Here's the code which will get me to the object detection of the apple and the generated disk-mask:

imgneg = ColorNegate[img]
bin = Closing[Binarize[imgneg, Method -> "Cluster"] // ColorNegate // DeleteSmallComponents // FillingTransform, 1]
{c, r} = 1/.ComponentMeasurements[bin, {"Centroid", "EquivalentDiskRadius"}];
Show[img, Graphics[{Red, Circle[c, r]}]]
{w, h} = ImageDimensions[img];
disk = ColorConvert[ColorNegate@Graphics[{Black, Disk[c, r]}, ImageSize -> {w, h}], "Grayscale"]
dat = disk // ImageData;


@nikie: I have NOT implemented it yet because I didn't know how to do it so that I can draw conclusion back onto the pixel-indices. But how I thought to do it was:

idx = Position[dat, 1.]; (* Extract the pixel-positions of the white pixels of the disk-mask *)
maskPx = Extract[img // ImageData, idx] (* get grey-values of the original apple-images for the masked pixels *)


Now maskPx would be a List of grey-values within the region of interest and to remove the outliers I would:

• calculate the mean and the standard deviation of the grey-values within the list
• remove pixels which are too bright, i.e. whose values are too far away from the mean value (i.e. >3*stdev or something like this)

I would receive a cleaned list of greyvalues which I could work with in the following prediction algorithm. The problem is: I only know which greyvalues (the outliers) I'd remove from the original list, but I wouldn't know the position of those outliers within the image to be able to display the mask to the user.

• It's not so difficult, but perhaps it would be better if you explain your motivation. – Dr. belisarius Dec 4 '14 at 12:40
• Also, please include at least one original, unprocessed image for testing. – Dr. belisarius Dec 4 '14 at 12:48
• You wrote "I can do the outliner detection" but you didn't give any details: What's the result of your outlier detection? A list of coordinates? A binary image (or 2d array)? Component data from ComponentMeasurements? Also: working with lists of indices is often much slower than working with a 2d array containing 0's and 1's (because of vectorization). – Niki Estner Dec 4 '14 at 12:58
• @nikie I think the last image is the desired result. I can't understand the motivation, though. – Dr. belisarius Dec 4 '14 at 14:01
• By the way, it's spelt outlier, that is, a data point that lies outside the neighbourhood of the rest of the data. – Rahul Dec 4 '14 at 15:59

You could make a mask like this:

i = Import@"http://i.stack.imgur.com/Gmpar.png";
mask = Closing[SelectComponents[MorphologicalBinarize@i,"Area",# > Times@@ImageDimensions@i/2 &], 2];

(ImageData@gs /. x_ /; x > # -> 0 // Image) & /@ Range[.8, .99, .05]

• Could be, yes, but unfortunately the simple way isn't always simple for a beginner into the new language - no experience how to best combine the different mathematica commands into a working code :( – tim Dec 8 '14 at 15:35
• @tim Binarize[] has a known problem: you need to be sure that the illumination and the reflective properties of the subjects will be highly homogeneous in your experiment. Otherwise YMMV. – Dr. belisarius Dec 9 '14 at 14:42