Suggested option for thresholding


#1

First of all, thanks for the great work on CellProfiler. Since our lab switched to using it, we haven’t looked back.

I would like to suggest that the calculation of a threshold include an option to take the log of the image prior to thresholding. I believe this would be particularly helpful in identifying objects.

My fluorescence images often have a background of relatively low variance and a foreground (often the nuclei) of considerably higher variance. Without a log transform, the threshold (regardless of the method used) tends to be too high, and dim nuclei are missed, even if they are clearly brighter than the true background. I have found the calculation of the threshold to be significantly improved by a log transform, which narrows the distribution of the foreground pixels. I would imagine this is a common scenario, and that the log transform would be useful to many people. Such an option would probably save people from having to fiddle around with the threshold correction factor.

At the moment, in my IdentifyPrimaryObjects module, I’ve resorted to setting a maximum value for the threshold based on manual inspection of the images, but this is the definition of a hack.


#2

I started looking at the code, to see if I could add the option to take the log transform myself. Consequently, I discovered that a log transform is already implemented in the code for the Ridler-Calvard threshold, but it is not documented. Unfortunately, even with the log transform, the resulting threshold from Ridler-Calvard is still too high in my images.

Upon reading the documentation more carefully, I found that the Kapur algorithm also does a log transform. In my images, in which most of the image is background and the background pixels have a much narrower intensity distribution than the foreground pixels, Kapur gives a better threshold.


#3

Hi,

Indeed, glad you found that some of the thresholding methods have a built-in log transform that you need. Let us know if you have any specific suggestions on whether we should clarify the specific transformations in segmentation methods that we normally leave “under-the-hood” (but you always have our source code, as you know).

Also, please note that you can use the module ImageMath to apply a ‘log transform (base 2)’ on any image, so you could do this explicitly upstream of other Identify modules’ thresholding methods which might not use a log-transform.

Cheers,
David


#4

[quote=“davidlogan”]Hi,

Indeed, glad you found that some of the thresholding methods have a built-in log transform that you need. Let us know if you have any specific suggestions on whether we should clarify the specific transformations in segmentation methods that we normally leave “under-the-hood” (but you always have our source code, as you know).
[/quote]

Although I don’t feel too strongly about it, I think the documentation should be consistent. Right now, the CP manual mentions the log transform in the Kapur algorithm, but doesn’t mention it for Ridler-Calvard. Most people are not going to track down the function in the source code.

Thanks for that suggestion, I hadn’t thought of that.

I should say that even using the Kapur algorithm, the threshold was still a little high in my images, and some nuclei were being missed. Sick of manually setting a threshold, I came up with a very simple way to calculate the threshold, which has worked nicely for me. The calculation works best if most pixels are background and the background is approximately gaussian (or log-gaussian). I’ll just paste it inline. If you guys try it and it works well, I’d love to see it in CP.

import numpy as np

def simpleThresh(img, stdFactor1=3, stdFactor2=3, logTransform=True, average=np.median):
	if logTransform:
		img = np.log(img)
	idx = np.absolute(img - average(img)) < stdFactor1 * np.std(img)
	level = average(img[idx]) + stdFactor2 * np.std(img[idx])
	if logTransform:
		level = np.exp(level)
	return level

#5

Hi , may i know how to implement kapur threshold ? i have trouble implement it , it requires more input arguments and i don’t know what input should i insert . please help . Thank you