# Labeling detected objects in image with number of overexposed pixels

I have the following image:

In here I want do detect all objects and label them according to their number of overexposed pixels.

Here is my code:

image = Import["https://i.stack.imgur.com/mKlS2.png"];
imageData = ImageData[image, "Byte"];

(*background image*)
background = ImageConvolve[image, GaussianMatrix[25]];
imageDataBackground = ImageData[background, "Byte"];

(* image - background image *)
diffData = imageData - imageDataBackground;

(* replacing negative values with 0 = black *)
correctedData = diffData /. value_ /; value < 0 -> 0;

(* Binarize image according to threshold value *)
binImg = Binarize[Image[correctedData], threshold = 5];

(* remove all particles which cosist of \[LessEqual] nPixels *)
cleanedImg = DeleteSmallComponents[binImg, nPixels = 7];

(* resulting image for using ComponentMeasurements *)
resultingImage = ImageMultiply[image, cleanedImg];

(* detected positions and pixel intensities of all objects *)
objectData =
Values@ComponentMeasurements[
resultingImage, {"IntensityCentroid", "IntensityData"}];

(* number of objects *)
numObjects = Length@objectData;

(* number of overexposed pixels per object *)
overexposedPixelsPerObject =
Table[Count[Flatten@objectData[[n, 2]], u_ /; u == 1], {n, 1,
numObjects}];

(* produce labels for objects that have overexposed poxels *)
labels = Style[Text[#], FontFamily -> "Calibri", 15] & /@
overexposedPixelsPerObject;

Show[
image,
Graphics[{Red, Table[Inset[labels[[i]], objectData[[i, 1]]], {i, 1, numObjects}]}]
]


My questions:

1. How can I label objects that have >0 overexposed pixel (the zeros should not be seen)

2. Can you propose a better solution for labeling, may be using LabelingFuntionor PlotLabels? I look for some solution where the labels are set close the objects and may be automatically (where Mathematica optimazes the position).

3. How can I replace the use of Table?

Here's an example with Callout:

counts = overexposedPixelsPerObject;
coords = Pick[objectData[[All, 1]], Unitize[counts], 1];
labels = Pick[counts, Unitize[counts], 1];

labelsGraphics = ListPlot[
Axes -> False,
PlotStyle -> Transparent
];

Show[ColorNegate@image, labelsGraphics]


I think that Callout may drop labels from very crowded areas, I don't know if it affects this plot but it's something to be aware of. (I don't have time to look at the documentation now. Please also see the documentation for styling etc.)

• Thanks a lot for the solution. – mrz Dec 23 '18 at 23:55
• How can I use PlotStyle to adjust font type, font size, different colors of labels and strokes? – mrz Dec 26 '18 at 12:18
• @mrz Have you read the documentation for Callout? This question is a bit too general to answer better than what's in the documentation. – C. E. Dec 28 '18 at 13:10

There is a typo in the code.

(* number of objects *)
numObjects = Length@particleData;


Should be

(* number of objects *)
numObjects = Length@objectData;


How can I label objects that have >0 overexposed pixel (the zeros should not be seen)

labels = If[# > 0, Style[Text[#], FontFamily -> "Calibri", 15], ""] & /@ overexposedPixelsPerObject;


Can you propose a better solution for labeling, may be using LabelingFuntion or PlotLabels?

What is wrong with the existing solution? Are you looking for a different way to label, e.g. change the color of overexposed and have a tooltip that shows number of pixels?

How can I replace the use of Table?

overexposedPixelsPerObject = Map[Count[#, u_ /; u == 1] &, objectData[[All, 2]]]


The second Table can also be replaced by Map. Table is best used to generate a list. If you already have a list that you need to operate on, Map is a better option.

• Thank you. Ich have corrected the typo. Concerning the labeling: I look for some solution where the labels are set close the objects and may be automatically (where Mathematica optimazes the position). I will use your solution for the replacement of the Tables. – mrz Dec 25 '18 at 1:16