Skip to content

Instantly share code, notes, and snippets.

@romainGuiet
Created January 14, 2020 10:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romainGuiet/28b1c9f9299dc2247d95e4c8583b852e to your computer and use it in GitHub Desktop.
Save romainGuiet/28b1c9f9299dc2247d95e4c8583b852e to your computer and use it in GitHub Desktop.
Add ROIs to ImageJ roiManager from an image with labels.
// adapted from https://gist.github.com/NicoKiaru/ae00117cd6d33fea500d2867a5e669d9
//
// = CODE DESCRIPTION =
// Add ROIs to ImageJ roiManager from an image with labels.
//
// == INPUTS ==
// A label image, grey or RGB.
//
// == OUTPUTS ==
// Rois in ImageJ roiManager.
//
// = DEPENDENCIES =
// FIJI 1.52p
//
// = INSTALLATION =
// Open the Script in QuPath, Run (work with Run for Project)
//
// = AUTHOR INFORMATION =
// Code written by Nico Chiarutinni, Olivier Burri, Romain Guiet, EPFL - SV -PTECH - BIOP
// 2020
//
// = COPYRIGHT =
// © All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP), 2020
//
// Licensed under the BSD-3-Clause License:
// Redistribution and use in source and binary forms, with or without modification, are permitted provided
// that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// TO DO : improvement would be to : don't get the ImagePlus nor open it to get the ROIs
#@ImagePlus imp
#@Boolean(label="split objects with same labels value", value = true) splitObjects
#@Boolean(label="exclude on edges", value = true) excludeOnEdges
import ij.*
import ij.IJ.*
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
import ij.measure.ResultsTable
import ij.plugin.filter.ParticleAnalyzer
import ij.plugin.frame.RoiManager
// reset RoiManager
def rm = new RoiManager()
rm = rm.getRoiManager()
rm.reset()
if ( splitObjects ) labelsImageToRois( imp , excludeOnEdges )
else {
rois = labelsImageToRoiArray(imp)
putRoisToRoiManager(rois,false);
}
//------------- HELPERS
public void labelsImageToRois(ImagePlus imp, Boolean excludeOnEdges ) {
def bitDepth = imp.getBitDepth()
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)
//imgFloatCopy.show()
// Create a ParticleAnalyzer, with options
int options = ParticleAnalyzer.SHOW_PROGRESS + ParticleAnalyzer.ADD_TO_MANAGER
if (excludeOnEdges) options += ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES
def pa = new ParticleAnalyzer( options, 0 , new ResultsTable(), 0.0, Double.POSITIVE_INFINITY , 0.0, 1.0)
existingPixelValues.each { v ->
if ( v != 0 ){
if ( ( bitDepth == 24) && ( v != -16777216 ) ){// not perfect ,
IJ.setRawThreshold( imgFloatCopy, v, v, "No Update") // "Red", "No Update"
pa.analyze( imgFloatCopy )
}
}
}
}
public ArrayList<Roi> labelsImageToRoiArray(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);
}
roiManager.addRoi(rois.get(i));
}
roiManager.runCommand("Show All");
}
@romainGuiet
Copy link
Author

Consider using : LaRoMe ! It's so much faster!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment