API for Masks

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

API for Masks

Greg
Hello,

I try to programmatically set a threshold and generate a binary mask (binary
processor) from it.
I have:

ip = orig.getProcessor().duplicate() # copy the original processor
ip.setAutoThreshold('Huang', True, 0)

imp = ImagePlus('mask',ip)
IJ.run(imp,"Convert to Mask", "") # calling the plugin

It is the last two lines that bother me, is there a more straightforward way
to generate the binary mask after thresholding directly from the
ImageProcessor (without resorting to IJ.run(...))?

Thanks,
Gregor



--
Sent from: http://imagej.1557.x6.nabble.com/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: API for Masks

Michael Schmid-3
Hi Gregor,

you can have a look at the ImageJ source code:
Searching for the "Convert to mask" code with "Find Commands" (ctrl-L)
you see that this is done by ij.plugin.Thresholder.

There in line 183 you see that it is also done via the ImagePlus unless
it is an 8-bit image.

An alternative would be creating a new ByteProcessor and having a loop
over all pixels that sets the ByteProcessor pixel to 255 if the pixel of
the original ip is in the thresholded range.

If you have a FloatProcessor (e.g. because you have a PlugInFilter with
CONVERT_TO_FLOAT), it is rather simple:

             float minThreshold = (float)ip.getMinThreshold();

             float maxThreshold = (float)ip.getMaxThreshold();

             float[] pixels = (float[])ip.getPixels();

             ByteProcessor thrMask = new ByteProcessor(width, height);

             byte[] thrPixels = (byte[])thrMask.getPixels();

             for (int p=0; p<pixels.length; p++)

                 if (pixels[p] >= minThreshold && pixels[p] <= maxThreshold)
                     thrPixels[p] = (byte)255;


If you need it for different types of ImageProcessors, it is not so simple.
RGB images are not supported by this approach at all.
For 8-bit images and 16-bit images, you can't use getPixelValue()
because it converts the pixels to calibrated values, but the threshold
values inside the ImageProcessor are uncalibrated. So one would need the
code at least twice, once for float and once with getPixel for
ByteProcessor and ShortProcessor.

I think it would be nice to have a method for this in ImageJ at
ImageProcessor level. It would be also nice to have
   ip.isThresholded(x, y)
The only problem is that thresholding ColorProcessors (RGB images) is
currently not at ImageProcessor level at all, so it won't work for
ColorProcessors.

Michael
________________________________________________________________
On 08/06/2018 14:59, Greg wrote:

> Hello,
>
> I try to programmatically set a threshold and generate a binary mask (binary
> processor) from it.
> I have:
>
> ip = orig.getProcessor().duplicate() # copy the original processor
> ip.setAutoThreshold('Huang', True, 0)
>
> imp = ImagePlus('mask',ip)
> IJ.run(imp,"Convert to Mask", "") # calling the plugin
>
> It is the last two lines that bother me, is there a more straightforward way
> to generate the binary mask after thresholding directly from the
> ImageProcessor (without resorting to IJ.run(...))?
>
> Thanks,
> Gregor

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: API for Masks

Wayne Rasband-2
In reply to this post by Greg
> On Jun 8, 2018, at 8:59 AM, Greg <[hidden email]> wrote:
>
> Hello,
>
> I try to programmatically set a threshold and generate a binary mask (binary
> processor) from it.
> I have:
>
> ip = orig.getProcessor().duplicate() # copy the original processor
> ip.setAutoThreshold('Huang', True, 0)
>
> imp = ImagePlus('mask',ip)
> IJ.run(imp,"Convert to Mask", "") # calling the plugin
>
> It is the last two lines that bother me, is there a more straightforward way
> to generate the binary mask after thresholding directly from the
> ImageProcessor (without resorting to IJ.run(...))?

The latest ImageJ daily build (1.52d25) adds a createMask() method to the ImageProcessor class. Here is a JavaScript example:

  img = IJ.openImage("http://wsr.imagej.net/images/m51.zip");
  ip = img.getProcessor();
  ip.setAutoThreshold('Huang', true, 0);
  mask = ip.createMask();
  img2 = new ImagePlus('mask',mask)
  img2.show();

This new method returns null if the image is not thresholded or it is an RGB image.

-wayne

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html