Convert mask image to unique ROIs

Hi all,

I was wondering is there a way to convert a mask image, where each mask has a unique value (see attached file) to separate ROIs?

For example, the attached file is a cell mask for some yeast cells. Is there a way to make each mask (and therefore each cell) an individual ROI?

Sorry if this doesn’t make sense.

Chris

Original tiff file: download

2 Likes

I use this groovy script:

I’m happy to learn about other options.

3 Likes

Thank you so much, that is perfect! :slight_smile:

Thanks very much for the code! It works almost perfectly for me, except that it also detects the background (which has the label = 0) as a ROI. I am trying to use this in a macro. If the roi id corresponding to the background was always ID=0, I could just delete afterwards with the commands
roiManager(“Select”, 0);
roiManager(“Delete”);
But somehow, in some images the background has ID=0, in others =1, 2, etc.
Since I practically don’t know anything about Groovy code, I was wondering if anybody knows any way to exclude the background from being passed on to a ROI. Thanks!!

Here I think I managed to solve it. I modified the original script in two ways:

  1. I modified the call for this function from false to true:
putRoisToRoiManager(rois,true);
  1. I inserted an if statement in lines 55-57:
if (rois.get(i).getName() != "0"){
            	roiManager.addRoi(rois.get(i));
        	}

Now the background with label id = 0 is not added to ROI manager.

Below is the complete code, in case someone finds it useful:
Cheers

#@ImagePlus imp

import ij.ImagePlus;
import ij.gui.Roi;
import java.util.HashSet;
import ij.process.ImageProcessor;
import ij.plugin.filter.ThresholdToSelection;
import ij.plugin.frame.RoiManager;
import ij.process.FloatProcessor


rois = labelImageToRoiArray(imp)
putRoisToRoiManager(rois,true);


	//------------- HELPERS

	public ArrayList<Roi> labelImageToRoiArray(ImagePlus imp) {
		ArrayList<Roi> roiArray = new ArrayList<>();
		ImageProcessor ip = imp.getProcessor();
		float[][] pixels = ip.getFloatArray();
		
		HashSet<Float> existingPixelValues = new HashSet<>();

		for (int x=0;x<ip.getWidth();x++) {
			for (int y=0;y<ip.getHeight();y++) {
				existingPixelValues.add((pixels[x][y]));
			}
		}

		// Converts data in case thats a RGB Image	
		fp = new FloatProcessor(ip.getWidth(), ip.getHeight())	
		fp.setFloatArray(pixels)
		imgFloatCopy = new ImagePlus("FloatLabel",fp)

		existingPixelValues.each { v ->
			fp.setThreshold( v,v,ImageProcessor.NO_LUT_UPDATE);
			Roi roi = ThresholdToSelection.run(imgFloatCopy);
			roi.setName(Integer.toString((int) (double) v));
			roiArray.add(roi);
		}
		return roiArray;
	}

    public static void putRoisToRoiManager(ArrayList<Roi> rois, boolean keepROISName) {
        RoiManager roiManager = RoiManager.getRoiManager();
        if (roiManager==null) {
            roiManager = new RoiManager();
        }
		    roiManager.reset();
        for (int i = 0; i < rois.size(); i++) {
        	if (!keepROISName) {
        		rois.get(i).setName(""+i);
        	}
        	if (rois.get(i).getName() != "0"){ // included this if statement so that the background with label ID=0 is not included in the ROI manager
            	roiManager.addRoi(rois.get(i));
        	}
        }
        roiManager.runCommand("Show All");
    }

You can also add the if statement earlier, to skip adding the ROI with a pixel value of 0 completely:

	existingPixelValues.each { v ->
		fp.setThreshold( v,v,ImageProcessor.NO_LUT_UPDATE);
		Roi roi = ThresholdToSelection.run(imgFloatCopy);
		roi.setName(Integer.toString((int) (double) v));
		if (v!==0){
			roiArray.add(roi);
		}
	}
1 Like