GenerateMask_.java
package com.github.celldynamics.quimp.plugin.generatemask;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import javax.swing.JOptionPane;
import com.github.celldynamics.quimp.BOAState;
import com.github.celldynamics.quimp.Nest;
import com.github.celldynamics.quimp.QParamsQconf;
import com.github.celldynamics.quimp.QuimP;
import com.github.celldynamics.quimp.QuimpException;
import com.github.celldynamics.quimp.QuimpException.MessageSinkTypes;
import com.github.celldynamics.quimp.Snake;
import com.github.celldynamics.quimp.SnakeHandler;
import com.github.celldynamics.quimp.filesystem.FileExtensions;
import com.github.celldynamics.quimp.plugin.AbstractPluginQconf;
import com.github.celldynamics.quimp.plugin.QuimpPluginException;
import com.github.celldynamics.quimp.utils.QuimpToolsCollection;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.gui.NewImage;
import ij.gui.Roi;
import ij.process.ImageConverter;
import ij.process.ImageProcessor;
import ij.process.StackConverter;
/**
* Convert QCONF files to BW masks.
*
* <p>Use Snake data produced by BOA and stored in QCONF file. If run from macro it shows image and
* save it to folder where QCONF resides. If run as API it does not do any of these two actions, use
* {@link #getRes()} to obtain image.
*
* @author p.baniukiewicz
*
*/
public class GenerateMask_ extends AbstractPluginQconf {
private static String thisPluginName = "Generate mask";
/**
* Resulting image. (Not saved or shown if apiCall==true)
*/
private ImagePlus res;
/**
* Executed if plugin is run from IJ. Set apiCall to false and redirect exception to IJ.
*/
public GenerateMask_() {
super(new GenerateMaskOptions(), thisPluginName);
}
/**
* Constructor that allows to provide own parameters.
*
* @param paramString it can be null to ask user for file or it can be parameters string like that
* passed in macro.
* @throws QuimpPluginException on any error
*/
public GenerateMask_(String paramString) throws QuimpPluginException {
super(paramString, new GenerateMaskOptions(), thisPluginName); // will parse and fill options
}
/*
* (non-Javadoc)
*
* @see com.github.celldynamics.quimp.plugin.PluginTemplate#run(java.lang.String)
*/
@Override
public void run(String arg) {
super.run(arg);
}
/*
* (non-Javadoc)
*
* @see com.github.celldynamics.quimp.plugin.IQuimpPlugin#about()
*/
@Override
public String about() {
return "Generate mask plugin.\n" + "Author: Piotr Baniukiewicz\n"
+ "mail: p.baniukiewicz@warwick.ac.uk";
}
/*
* (non-Javadoc)
*
* @see com.github.celldynamics.quimp.plugin.PluginTemplate#runFromQCONF()
*/
@Override
protected void runFromQconf() throws QuimpException {
GenerateMaskOptions opts = (GenerateMaskOptions) options;
BOAState bs = qconfLoader.getBOA();
Nest nest = bs.nest;
int currentColor;
// create output image
res = NewImage.createShortImage("test", bs.boap.getWidth(), bs.boap.getHeight(),
bs.boap.getFrames(), NewImage.FILL_BLACK);
// get stacks reference
ImageStack contourStack = res.getStack();
res.setSlice(1); // set for first
int frame; // frames counter (from 1)
Snake snake;
ImageProcessor contourIp; // processor taken from stack (ref)
for (frame = 1; frame <= bs.boap.getFrames(); frame++) { // iterate over frames
List<Integer> snakes = nest.getSnakesforFrame(frame); // find all SnakeHandlers on frame
contourIp = contourStack.getProcessor(frame); // get processor from stack for frame
currentColor = 1;
for (Integer snakeID : snakes) { // iterate over SnakeHandlers
SnakeHandler snakeH = nest.getHandlerofId(snakeID); // get SH of snakeID
if (snakeH != null) {
snake = snakeH.getStoredSnake(frame); // get snake from this handler and current frame
Roi roi = snake.asFloatRoi(); // convert to ROI
contourIp.setColor(currentColor++);
contourIp.fill(roi); // plot on current slice
}
}
}
if (opts.binary) {
for (int i = 1; i <= res.getImageStackSize(); i++) {
res.getStack().getProcessor(i).threshold(0);
}
ImageConverter.setDoScaling(false);
new StackConverter(res).convertToGray8();
}
if (!apiCall) { // do not show nor save if called from api
res.show();
// save in QCONF folder
QParamsQconf qp = (QParamsQconf) qconfLoader.getQp();
Path filename = Paths.get(qp.getPath(), qp.getFileName() + FileExtensions.generateMaskSuffix);
IJ.saveAsTiff(res, filename.toString());
IJ.log("Saved in: " + filename.toString());
if (errorSink == MessageSinkTypes.GUI) { // run form IJ not from macro
JOptionPane.showMessageDialog(
IJ.getInstance(), QuimpToolsCollection
.stringWrap("Image saved! (" + filename.toString() + ")", QuimP.LINE_WRAP),
"Saved!", JOptionPane.INFORMATION_MESSAGE);
} else {
IJ.log("Mask generated!");
}
}
}
/**
* Return image generated by plugin. Use with API calls.
*
* <p>Return 16bit image if {@link GenerateMaskOptions#binary} is set to false with grayscale
* indexed objects.
*
* @return the res Mask image generated from loaded Qconf.
*/
public ImagePlus getRes() {
return res;
}
@Override
protected void runFromPaqp() throws QuimpException {
throw new QuimpException("Old file format is not supported");
}
/*
* (non-Javadoc)
*
* @see com.github.celldynamics.quimp.plugin.PluginTemplate#showUi(boolean)
*/
@Override
public void showUi(boolean val) throws Exception {
// this method is called when no options were provided to run, paramFile is empty or null
loadFile(options.paramFile); // if no options (run from menu) let qconfloader show file selector
// fill this for macro recorder
options.paramFile = qconfLoader.getQp().getParamFile().getAbsolutePath();
}
}