# Overplot overexposed pixels on image

I have an image and want to mark each pixel which has a brightness of 1 with yellow color.

The image is (png, 8bit):

My code to find and mark overexposed pixels:

imageData = ImageData[image];

overexposedPositions = Position[imageData, n_ /; n == 1];

x = overexposedPositions[[All, 1]];
y = overexposedPositions[[All, 2]];

data = Transpose[{y, dimImage[[2]] - x}];

Show[image, Graphics[{Yellow, Point[#] & /@ data}]]

When I compare these two images I can see that pixels are marked yellow but are not overexposed?! So there must be an error in my code.

How would you solve this problem?

This seems to work as well:

img = Import["https://i.sstatic.net/Epzrz.png"];
highlighted = ColorReplace[img, White -> Yellow, $MachineEpsilon] • A very elegant solution. Thank you. How would you highlight with this code e.g. all intensities between 0.4 and 0.8? – mrz Commented Dec 20, 2018 at 10:09 • @mrz I would think that is what ColorReplace[img, 0.6 -> Yellow, 0.2] does. Commented Dec 21, 2018 at 4:36 • Thank you for the solution. Why is in the replacement$MachineEpsilon required? In the 8 bit images white is always exactly 1., or not?
– mrz
Commented Dec 25, 2018 at 1:12
• I compared the solution of @Niki Estner with your solution (which is much shorter). In his enlarged example area 5 pixels are overexposed. When I check the same region with ColorReplace I see exactly the same result as Niki finds, i.imgur.com/VOOyb2K.png, but only when I use $MachineEpsilon. – mrz Commented Dec 25, 2018 at 1:36 • @mrz: If you read the docs for ColorReplace, you'll find: ColorReplace[image,color] is equivalent to ColorReplace[image,color,0.1].. So without$MachineEpsilon it would replace anything above .9 to color. Commented Dec 25, 2018 at 8:07

I'll take a small part of your image, so we can look at individual pixels:

image = ImageTake[Import["https://i.sstatic.net/Epzrz.png"], 100,
100]

The easiest way to get the positions of all pixels with a certain value is using ImageValuePositions:

overexposed = ImageValuePositions[image, 1];
Show[image, Graphics[{Red, Point[overexposed]}], ImageSize -> 600]

It looks as if the overexposed pixels are all marked, and the markers are in the middle of the pixels, at least at this scale. But Points can be smaller or larger than pixels, so I'd prefer overlaying a binary mask over the image:

HighlightImage[image, UnitStep[image - 1], ImageSize -> 600]

Sadly, HighlightImage is a bit broken in current versions of MMA ("Boundary" thickness in HighlightImage), so if you want only the overexposed pixels marked, without a border, you'll have to do it manually:

With[{notOverexposed = 1 - UnitStep[image - 1]},
Image[ColorCombine[{image, notOverexposed*image,
notOverexposed*image}], ImageSize -> 600]]

• Thank you for your solution. This is very interesting what you say about HighlightImage. What I cannot see: how would you for example get a yellow color for highlighting?
– mrz
Commented Dec 20, 2018 at 10:11
• @mrz: in the last code example? It's just basic arithmetic. Yellow is a mixture of green + red. So you have to set the green channel to the same value as the red channel. Then the blue channel is 0 for overexposed pixels -> and they're yellow. Commented Dec 21, 2018 at 9:17
• Merry Christmas Niki. Thank you for your help. Please see my last comment to the answer of C. E.
– mrz
Commented Dec 25, 2018 at 1:40