package ij.plugin;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.process.*;
import ij.gui.Roi;
import ij.plugin.filter.ThresholdToSelection;
import ij.plugin.frame.RoiManager;
import java.awt.Rectangle;
import java.util.ArrayList;
public class RoiInterpolator implements PlugIn {
int[][] idt;
int w, h;
public void run(String arg) {
RoiManager roiman = RoiManager.getInstance();
if (roiman==null || roiman.getCount()<2){
IJ.error("RoiInterpolator", "Please populate the ROI Manager with at least two ROIs");
return;
}
Roi[] rois = roiman.getRoisAsArray();
int xmax = 0;
int xmin = Integer.MAX_VALUE;
int ymax = 0;
int ymin = Integer.MAX_VALUE;
int zmax = 1;
int zmin = Integer.MAX_VALUE;
ArrayList<Integer> templateSlices = new ArrayList<Integer>();
for (Roi roi : rois){
int slice = roiman.getSliceNumber(roi.getName());
if (!templateSlices.contains(Integer.valueOf(slice)))
templateSlices.add(Integer.valueOf(slice));
if (slice==0) continue;
zmin = Math.min(slice, zmin);
zmax = Math.max(slice, zmax);
Rectangle bounds = roi.getBounds();
xmin = Math.min(xmin, bounds.x);
ymin = Math.min(ymin, bounds.y);
xmax = Math.max(xmax, bounds.x + bounds.width);
ymax = Math.max(ymax, bounds.y + bounds.height);
}
if (templateSlices.size()<2) {
IJ.error("RoiInterpolator", "ROIs are all on the same slice, nothing to interpolate");
return;
}
final int stackW = xmax - xmin + 1;
final int stackH = ymax - ymin + 1;
final int nSlices = zmax - zmin + 1;
ImageStack stack = new ImageStack(stackW, stackH);
for (int s=0; s<nSlices; s++){
ByteProcessor bp = new ByteProcessor(stackW, stackH);
bp.setColor(255);
for (Roi roi : rois){
int slice = roiman.getSliceNumber(roi.getName());
if (slice==zmin+s){
Rectangle bounds = roi.getBounds();
roi.setLocation(bounds.x - xmin, bounds.y - ymin);
bp.setRoi(roi);
if (roi.getType() == Roi.RECTANGLE)
bp.fill();
else
bp.fill(roi);
}
}
stack.addSlice(""+s, bp);
}
BinaryInterpolator bi = new BinaryInterpolator();
bi.run(stack);
ImagePlus binary = new ImagePlus("interpolated", stack);
ThresholdToSelection ts = new ThresholdToSelection();
ts.setup("", binary);
for (int s=0; s<nSlices; s++) {
if (templateSlices.contains(Integer.valueOf(s+zmin)))
continue;
ImageProcessor bp = stack.getProcessor(s+1);
int threshold = 255;
bp.setThreshold(threshold, threshold, ImageProcessor.NO_LUT_UPDATE);
Roi roi = ts.convert(bp);
if (roi==null) {
IJ.error("RoiInterpolator", "Unable to interpolate slice "+(s+1)+". More\nintermediate ROIs needed.");
return;
}
roi.setPosition(s+zmin);
Rectangle bounds = roi.getBounds();
roi.setLocation(bounds.x+xmin, bounds.y+ymin);
roiman.addRoi(roi);
}
for (Roi roi : rois){
Rectangle bounds = roi.getBounds();
roi.setLocation(bounds.x+xmin, bounds.y+ymin);
}
roiman.runCommand("sort");
IJ.showStatus("ROIs interpolated");
}
}