Otsu's thresholding upper bounds are not respected


I’ve been using global two class Otsu’s in IdentifyPrimaryObjects to quantify the area of DAB-staining. However, for some reason the program ignores the upper bounds that I set for the intensity. When I manually check the intensity in test mode in the output window, I can see that the pixel intensities are above my thresholds, but they still count as positive.

Any ideas?

Unfortunately, I user very high resolution pictures so I won’t be able to upload them here.

Thanks in advance.

I have not checked my numbers and won’t have a chance to today, but I am working on figuring out the correct thresholds (I think best suited for 2 class Otsu) with DAB-staining but am having trouble. Is it possible that this is a bug (I’m using CP version 3.0) and not related to a specific project?

Hi Nikolce,

Do I understand correctly that, you set the Lower-Upper bound for intensity as 0-0.5, and you still see the signals brighter than 0.5 being capture? If so, I guess it’s not surprising, since the threshold will “walk” from the lower end toward the higher end, it’ll capture whatever it see first, no?

Would you mind uploading the image and pipeline into google drive or dropbox and share the link here if they’re large.


Ah, I think there’s a misunderstanding here; the bounds on the threshold is a bound on what values the threshold could be set to; every pixel with an intensity higher than the set threshold that will end up “called”.

If you want to only capture pixels between a certain range (ie 0.25-0.75, leaving the ones that are too high or too low out), you should first use (Apply)Threshold or IdentifyPrimaryObjects to find the pixels that are too bright (>0.75 in this example), then MaskImage with “Invert the mask” set to “Yes” to exclude those too-bright regions. You can then use IdentifyPrimaryObjects on the masked image to find your middle-intensity-class objects.

Does that help?

That worked fairly well. The problem I’m having is that I have some slides which contain precipitated DAB that I wan’t to exclude from analysis. I’m using customised DAB-absorbance in UnmixColors, buut it still picks up the black precipitate as DAB.

See below for an example image:

When you say “that” worked fairly well, can you say specifically what you tried? If it’s the masking procedure I mentioned before, did you examine what got masked out at that step to make sure you got all of the precipitated stuff that you meant to?

I went with IdentifyPrimaryObjects --> MaskImage (objects from previous IdentifyPrimaryObjects) --> IdentifyPrimaryObjects (DAB). I got most if away, although the edges around the precipitate remained. However, some regions with more intense DAB-staining were also removed.

You can try to avoid the edge issues around the precipitate by doing an “ExpandOrShrinkObjects” module after your first IPO to expand the DAB spots 2 or 3 pixels before masking; this should help with the “not quite clearing all of it” part of the issue.

As for the “losing real staining” issue, since the precipitated DAB looks pretty different (at least to my eye in the picture you showed) than the true staining, you could try to do an UnmixColors step JUST to pull out that precipitated DAB. Not sure it would work but worth a try.

Thank, I’ll try that and report back.

EDIT: I tried using a a separate UnmixColors with a custom absorbance value (cut out bits of the image with precipitate and used that as the input image for customised absorbance values) for the precipitate. Unfortunately, it still picks up some of the stronger DAB as positive staining.

EDIT 2: Setting the absorbance values to 1:1:1 improved the result somewhat. It is then possible to use IdentifyPrimaryObjects with a manual threshold, set to a relatively high value (>0.8).

1 Like