imagej-ops icon indicating copy to clipboard operation
imagej-ops copied to clipboard

Yen threshold differs from IJ1

Open hinerm opened this issue 3 years ago • 4 comments

Sample Data

When using Image > Adjust > Threshold... and selecting Yen to get the ImageJ 1.x threshold on a test image, we get: image

Running a simple groovy script to threshold with ops

#@ OpService ops
#@ ImgPlus inputData

return ops.threshold().yen(inputData)

on the same image produces a much more aggressively thresholded image: image

I don't think this is just a different in image type because if I convert the image to 8-bit and run the IJ1 auto threshold it's actually even more generous:

image

However I can produce a similar image in the IJ1 auto threshold by operating on the 16-bit image and turning up the minValue cutoff: image

It looks like the issue is that Ops is computing the min/max for the histogram off the 16-bit input but then always converts the output to 8-bit, resulting in a too-high threshold.

First converting the test image to 8-bit and then running the above script results in a reasonable output: image

hinerm avatar Mar 03 '21 14:03 hinerm

Note however that performing the conversion with ops produces yet a different result:

#@ OpService ops
#@ ImgPlus inputData

converted = ops.convert().int8(inputData)
return ops.threshold().yen(converted)

image

hinerm avatar Mar 03 '21 15:03 hinerm

You should convert to unsigned 8-bit when converting with ops, no?

converted = ops.convert().uint8(inputData)

imagejan avatar Mar 04 '21 08:03 imagejan

You should convert to unsigned 8-bit when converting with ops, no?

@imagejan honestly I don't know. Here's uint8 version - it just looked even farther from the IJ1 version:

image

hinerm avatar Mar 04 '21 12:03 hinerm

Ah yes, that's because convert doesn't scale the intensity values at all, and high values simply "wrap around" the 8-bit limit.

imagejan avatar Mar 04 '21 13:03 imagejan