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

The image is (png, 8bit):

enter image description here

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?

enter image description here


2 Answers 2


This seems to work as well:

img = Import["https://i.sstatic.net/Epzrz.png"];
highlighted = ColorReplace[img, White -> Yellow, $MachineEpsilon]

Mathematica graphics

  • $\begingroup$ A very elegant solution. Thank you. How would you highlight with this code e.g. all intensities between 0.4 and 0.8? $\endgroup$
    – mrz
    Dec 20, 2018 at 10:09
  • 1
    $\begingroup$ @mrz I would think that is what ColorReplace[img, 0.6 -> Yellow, 0.2] does. $\endgroup$
    – C. E.
    Dec 21, 2018 at 4:36
  • $\begingroup$ Thank you for the solution. Why is in the replacement $MachineEpsilon required? In the 8 bit images white is always exactly 1., or not? $\endgroup$
    – mrz
    Dec 25, 2018 at 1:12
  • $\begingroup$ 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. $\endgroup$
    – mrz
    Dec 25, 2018 at 1:36
  • 1
    $\begingroup$ @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. $\endgroup$ 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, 

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]

enter image description here

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]

enter image description here

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]]

enter image description here

  • $\begingroup$ 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? $\endgroup$
    – mrz
    Dec 20, 2018 at 10:11
  • 1
    $\begingroup$ @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. $\endgroup$ Dec 21, 2018 at 9:17
  • $\begingroup$ Merry Christmas Niki. Thank you for your help. Please see my last comment to the answer of C. E. $\endgroup$
    – mrz
    Dec 25, 2018 at 1:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.