Import mask from a 16-bit PNG file

import ij.plugin.filter.ThresholdToSelection
import ij.process.ByteProcessor;
import ij.process.ImageProcessor;
import javax.imageio.ImageIO

//Works for 8-bit PNG
def img = ImageIO.read(new File('C:\\masks\\image-8bit-mask.png'))
def bp = new ByteProcessor(img)
bp.setThreshold(20, 20,ImageProcessor.NO_LUT_UPDATE)
def roiIJ = new ThresholdToSelection().convert(bp)

//Doesn't work for 16-bit PNG, error I get is "Type!=TYPE_BYTE_GRAYY"
def img2 = ImageIO.read(new File('C:\\masks\\image-16bit-mask.png'))
def bp2 = new ByteProcessor(img2)
bp2.setThreshold(20, 20,ImageProcessor.NO_LUT_UPDATE)
def roiIJ2 = new ThresholdToSelection().convert(bp2)

How do I adapt the method setThreshold for a 16-bit image ? I want to threshold using specific pixel values.

I have a 16bit PNG image with masks created by cellpose, each cell identified have a unique pixel values. In the above example I want to create an object for a cell whose pixels values=20.

It works when the image is 8-bit, but when I try on a 16-bit image i get Type!=TYPE_BYTE_GRAYY error

Found the FloatProcessor :slight_smile:

import ij.plugin.filter.ThresholdToSelection
import ij.process.ByteProcessor;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import javax.imageio.ImageIO

//For 16-bit PNG
def img = ImageIO.read(new File('C:\\masks\\image-16bit-mask.png'))
    int w = img.getWidth();
    int h = img.getHeight();
    int band = 0
    float[] pixels = new float[w * h];
    img.getRaster().getSamples(0, 0, w, h, band, pixels);
    var fp = new FloatProcessor(w, h, pixels);
    fp.setThreshold(1, 200,ImageProcessor.NO_LUT_UPDATE)
    def roiIJ = new ThresholdToSelection().convert(fp)

It’s really an ImageJ question – you can’t use new ByteProcessor(img2) since a ByteProcessor is 8-bit.

You could read an ImageProcessor using

def ip = ij.IJ.openImage(path).getProcessor()

in which case ImageJ will figure out which kind to return.

2 Likes

Thank you, That is much better than what I was going for.

1 Like