use of ij.gui.ImageRoi in project GDSC-SMLM by aherbert.
the class SpotFinderPreview method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.filter.PlugInFilter#run(ij.process.ImageProcessor)
*/
public void run(ImageProcessor ip) {
Rectangle bounds = ip.getRoi();
MaximaSpotFilter filter = config.createSpotFilter(true);
// Crop to the ROI
FloatProcessor fp = ip.crop().toFloat(0, null);
float[] data = (float[]) fp.getPixels();
int width = fp.getWidth();
int height = fp.getHeight();
Spot[] spots = filter.rank(data, width, height);
data = filter.getPreprocessedData();
fp = new FloatProcessor(width, height, data);
ip = ip.duplicate();
ip.insert(fp, bounds.x, bounds.y);
//ip.resetMinAndMax();
ip.setMinAndMax(fp.getMin(), fp.getMax());
Overlay o = new Overlay();
o.add(new ImageRoi(0, 0, ip));
if (label != null) {
// Get results for frame
Coordinate[] actual = ResultsMatchCalculator.getCoordinates(actualCoordinates, imp.getCurrentSlice());
Coordinate[] predicted = new Coordinate[spots.length];
for (int i = 0; i < spots.length; i++) {
predicted[i] = new BasePoint(spots[i].x + bounds.x, spots[i].y + bounds.y);
}
// Q. Should this use partial scoring with multi-matches allowed.
// If so then this needs to be refactored out of the BenchmarkSpotFilter class.
// TODO - compute AUC and max jaccard and plot
// Compute matches
List<PointPair> matches = new ArrayList<PointPair>(Math.min(actual.length, predicted.length));
List<Coordinate> FP = new ArrayList<Coordinate>(predicted.length);
MatchResult result = MatchCalculator.analyseResults2D(actual, predicted, distance * fitConfig.getInitialPeakStdDev0(), null, FP, null, matches);
// Show scores
setLabel(String.format("P=%s, R=%s, J=%s", Utils.rounded(result.getPrecision()), Utils.rounded(result.getRecall()), Utils.rounded(result.getJaccard())));
// Create Rois for TP and FP
if (showTP) {
float[] x = new float[matches.size()];
float[] y = new float[x.length];
int n = 0;
for (PointPair pair : matches) {
BasePoint p = (BasePoint) pair.getPoint2();
x[n] = p.getX() + 0.5f;
y[n] = p.getY() + 0.5f;
n++;
}
addRoi(0, o, x, y, n, Color.green);
}
if (showFP) {
float[] x = new float[predicted.length - matches.size()];
float[] y = new float[x.length];
int n = 0;
for (Coordinate c : FP) {
BasePoint p = (BasePoint) c;
x[n] = p.getX() + 0.5f;
y[n] = p.getY() + 0.5f;
n++;
}
addRoi(0, o, x, y, n, Color.red);
}
} else {
float[] x = new float[spots.length];
float[] y = new float[x.length];
for (int i = 0; i < spots.length; i++) {
x[i] = spots[i].x + bounds.x + 0.5f;
y[i] = spots[i].y + bounds.y + 0.5f;
}
PointRoi roi = new PointRoi(x, y);
// Add options to configure colour and labels
o.add(roi);
}
imp.setOverlay(o);
}
use of ij.gui.ImageRoi in project GDSC-SMLM by aherbert.
the class SpotFinderPreview method run.
private void run(ImageProcessor ip, MaximaSpotFilter filter) {
if (refreshing) {
return;
}
currentSlice = imp.getCurrentSlice();
final Rectangle bounds = ip.getRoi();
// Crop to the ROI
FloatProcessor fp = ip.crop().toFloat(0, null);
float[] data = (float[]) fp.getPixels();
final int width = fp.getWidth();
final int height = fp.getHeight();
// Store the mean bias and gain of the region data.
// This is used to correctly overlay the filtered data on the original image.
double bias = 0;
double gain = 1;
boolean adjust = false;
// Set weights
final CameraModel cameraModel = fitConfig.getCameraModel();
if (!(cameraModel instanceof FakePerPixelCameraModel)) {
// This should be done on the normalised data
final float[] w = cameraModel.getNormalisedWeights(bounds);
filter.setWeights(w, width, height);
data = data.clone();
if (data.length < ip.getPixelCount()) {
adjust = true;
bias = MathUtils.sum(cameraModel.getBias(bounds)) / data.length;
gain = MathUtils.sum(cameraModel.getGain(bounds)) / data.length;
}
cameraModel.removeBiasAndGain(bounds, data);
}
final Spot[] spots = filter.rank(data, width, height);
data = filter.getPreprocessedData();
final int size = spots.length;
if (topNScrollBar != null) {
topNScrollBar.setMaximum(size);
selectScrollBar.setMaximum(size);
}
fp = new FloatProcessor(width, height, data);
final FloatProcessor out = new FloatProcessor(ip.getWidth(), ip.getHeight());
out.copyBits(ip, 0, 0, Blitter.COPY);
if (adjust) {
fp.multiply(gain);
fp.add(bias);
}
out.insert(fp, bounds.x, bounds.y);
final double min = fp.getMin();
final double max = fp.getMax();
out.setMinAndMax(min, max);
final Overlay o = new Overlay();
o.add(new ImageRoi(0, 0, out));
if (label != null) {
// Get results for frame
final Coordinate[] actual = ResultsMatchCalculator.getCoordinates(actualCoordinates, imp.getCurrentSlice());
final Coordinate[] predicted = new Coordinate[size];
for (int i = 0; i < size; i++) {
predicted[i] = new BasePoint(spots[i].x + bounds.x, spots[i].y + bounds.y);
}
// Compute assignments
final LocalList<FractionalAssignment> fractionalAssignments = new LocalList<>(3 * predicted.length);
final double matchDistance = settings.distance * fitConfig.getInitialPeakStdDev();
final RampedScore score = RampedScore.of(matchDistance, matchDistance * settings.lowerDistance / 100, false);
final double dmin = matchDistance * matchDistance;
final int nActual = actual.length;
final int nPredicted = predicted.length;
for (int j = 0; j < nPredicted; j++) {
// Centre in the middle of the pixel
final float x = predicted[j].getX() + 0.5f;
final float y = predicted[j].getY() + 0.5f;
// Any spots that match
for (int i = 0; i < nActual; i++) {
final double dx = (x - actual[i].getX());
final double dy = (y - actual[i].getY());
final double d2 = dx * dx + dy * dy;
if (d2 <= dmin) {
final double d = Math.sqrt(d2);
final double s = score.score(d);
if (s == 0) {
continue;
}
double distance = 1 - s;
if (distance == 0) {
// In the case of a match below the distance thresholds
// the distance will be 0. To distinguish between candidates all below
// the thresholds just take the closest.
// We know d2 is below dmin so we subtract the delta.
distance -= (dmin - d2);
}
// Store the match
fractionalAssignments.add(new ImmutableFractionalAssignment(i, j, distance, s));
}
}
}
final FractionalAssignment[] assignments = fractionalAssignments.toArray(new FractionalAssignment[0]);
// Compute matches
final RankedScoreCalculator calc = RankedScoreCalculator.create(assignments, nActual - 1, nPredicted - 1);
final boolean save = settings.showTP || settings.showFP;
final double[] calcScore = calc.score(nPredicted, settings.multipleMatches, save);
final ClassificationResult result = RankedScoreCalculator.toClassificationResult(calcScore, nActual);
// Compute AUC and max jaccard (and plot)
final double[][] curve = RankedScoreCalculator.getPrecisionRecallCurve(assignments, nActual, nPredicted);
final double[] precision = curve[0];
final double[] recall = curve[1];
final double[] jaccard = curve[2];
final double auc = AucCalculator.auc(precision, recall);
// Show scores
final String scoreLabel = String.format("Slice=%d, AUC=%s, R=%s, Max J=%s", imp.getCurrentSlice(), MathUtils.rounded(auc), MathUtils.rounded(result.getRecall()), MathUtils.rounded(MathUtils.maxDefault(0, jaccard)));
setLabel(scoreLabel);
// Plot
String title = TITLE + " Performance";
Plot plot = new Plot(title, "Spot Rank", "");
final double[] rank = SimpleArrayUtils.newArray(precision.length, 0, 1.0);
plot.setLimits(0, nPredicted, 0, 1.05);
plot.setColor(Color.blue);
plot.addPoints(rank, precision, Plot.LINE);
plot.setColor(Color.red);
plot.addPoints(rank, recall, Plot.LINE);
plot.setColor(Color.black);
plot.addPoints(rank, jaccard, Plot.LINE);
plot.setColor(Color.black);
plot.addLabel(0, 0, scoreLabel);
final WindowOrganiser windowOrganiser = new WindowOrganiser();
ImageJUtils.display(title, plot, 0, windowOrganiser);
title = TITLE + " Precision-Recall";
plot = new Plot(title, "Recall", "Precision");
plot.setLimits(0, 1, 0, 1.05);
plot.setColor(Color.red);
plot.addPoints(recall, precision, Plot.LINE);
plot.drawLine(recall[recall.length - 1], precision[recall.length - 1], recall[recall.length - 1], 0);
plot.setColor(Color.black);
plot.addLabel(0, 0, scoreLabel);
ImageJUtils.display(title, plot, 0, windowOrganiser);
windowOrganiser.tile();
// Create Rois for TP and FP
if (save) {
final double[] matchScore = RankedScoreCalculator.getMatchScore(calc.getScoredAssignments(), nPredicted);
int matches = 0;
for (int i = 0; i < matchScore.length; i++) {
if (matchScore[i] != 0) {
matches++;
}
}
if (settings.showTP) {
final float[] x = new float[matches];
final float[] y = new float[x.length];
int count = 0;
for (int i = 0; i < matchScore.length; i++) {
if (matchScore[i] != 0) {
final BasePoint p = (BasePoint) predicted[i];
x[count] = p.getX() + 0.5f;
y[count] = p.getY() + 0.5f;
count++;
}
}
addRoi(0, o, x, y, count, Color.green);
}
if (settings.showFP) {
final float[] x = new float[nPredicted - matches];
final float[] y = new float[x.length];
int count = 0;
for (int i = 0; i < matchScore.length; i++) {
if (matchScore[i] == 0) {
final BasePoint p = (BasePoint) predicted[i];
x[count] = p.getX() + 0.5f;
y[count] = p.getY() + 0.5f;
count++;
}
}
addRoi(0, o, x, y, count, Color.red);
}
}
} else {
final WindowOrganiser wo = new WindowOrganiser();
// Option to show the number of neighbours within a set pixel box radius
final int[] count = spotFilterHelper.countNeighbours(spots, width, height, settings.neighbourRadius);
// Show as histogram the totals...
new HistogramPlotBuilder(TITLE, StoredData.create(count), "Neighbours").setIntegerBins(true).setPlotLabel("Radius = " + settings.neighbourRadius).show(wo);
// TODO - Draw n=0, n=1 on the image overlay
final LUT lut = LutHelper.createLut(LutColour.FIRE_LIGHT);
// These are copied by the ROI
final float[] x = new float[1];
final float[] y = new float[1];
// Plot the intensity
final double[] intensity = new double[size];
final double[] rank = SimpleArrayUtils.newArray(size, 1, 1.0);
final int top = (settings.topN > 0) ? settings.topN : size;
final int size_1 = size - 1;
for (int i = 0; i < size; i++) {
intensity[i] = spots[i].intensity;
if (i < top) {
x[0] = spots[i].x + bounds.x + 0.5f;
y[0] = spots[i].y + bounds.y + 0.5f;
final Color c = LutHelper.getColour(lut, size_1 - i, size);
addRoi(0, o, x, y, 1, c, 2, 1);
}
}
final String title = TITLE + " Intensity";
final Plot plot = new Plot(title, "Rank", "Intensity");
plot.setColor(Color.blue);
plot.addPoints(rank, intensity, Plot.LINE);
if (settings.topN > 0 && settings.topN < size) {
plot.setColor(Color.magenta);
plot.drawLine(settings.topN, 0, settings.topN, intensity[settings.topN - 1]);
}
if (settings.select > 0 && settings.select < size) {
plot.setColor(Color.yellow);
final int index = settings.select - 1;
final double in = intensity[index];
plot.drawLine(settings.select, 0, settings.select, in);
x[0] = spots[index].x + bounds.x + 0.5f;
y[0] = spots[index].y + bounds.y + 0.5f;
final Color c = LutHelper.getColour(lut, size_1 - settings.select, size);
addRoi(0, o, x, y, 1, c, 3, 3);
plot.setColor(Color.black);
plot.addLabel(0, 0, "Selected spot intensity = " + MathUtils.rounded(in));
}
ImageJUtils.display(title, plot, 0, wo);
wo.tile();
}
imp.setOverlay(o);
}
use of ij.gui.ImageRoi in project GDSC-SMLM by aherbert.
the class OverlayImage method addImage.
/**
* Adapted from ij.plugins.OverlayCommands#addImage(boolean) with the additional option for setting the zero pixels
* to transparent.
*/
void addImage() {
ImagePlus imp = IJ.getImage();
int[] wList = WindowManager.getIDList();
if (wList == null || wList.length < 2) {
IJ.error("Add Image...", "The command requires at least two open images.");
return;
}
String[] titles = new String[wList.length];
int count = 0;
for (int i = 0; i < wList.length; i++) {
ImagePlus imp2 = WindowManager.getImage(wList[i]);
if (imp2 != null && imp2 != imp && imp.getWidth() >= imp2.getWidth() && imp.getHeight() >= imp2.getHeight())
titles[count++] = imp2.getTitle();
}
if (count < 1) {
IJ.error("Add Image...", "The command requires at least one valid overlay image.");
return;
}
titles = Arrays.copyOf(titles, count);
int x = 0, y = 0;
Roi roi = imp.getRoi();
if (roi != null && roi.isArea()) {
Rectangle r = roi.getBounds();
x = r.x;
y = r.y;
}
GenericDialog gd = new GenericDialog("Add Image...");
gd.addChoice("Image to add:", titles, title);
gd.addNumericField("X location:", x, 0);
gd.addNumericField("Y location:", y, 0);
gd.addNumericField("Opacity (0-100%):", opacity, 0);
gd.addCheckbox("Transparent background", transparent);
gd.addCheckbox("Replace overlay", replace);
gd.showDialog();
if (gd.wasCanceled())
return;
title = gd.getNextChoice();
x = (int) gd.getNextNumber();
y = (int) gd.getNextNumber();
opacity = (int) gd.getNextNumber();
transparent = gd.getNextBoolean();
replace = gd.getNextBoolean();
ImagePlus overlay = WindowManager.getImage(title);
if (overlay == imp) {
IJ.error("Add Image...", "Image to be added cannot be the same as\n\"" + imp.getTitle() + "\".");
return;
}
if (overlay.getWidth() > imp.getWidth() && overlay.getHeight() > imp.getHeight()) {
IJ.error("Add Image...", "Image to be added cannnot be larger than\n\"" + imp.getTitle() + "\".");
return;
}
ImageRoi roi2 = new ImageRoi(x, y, overlay.getProcessor());
roi2.setZeroTransparent(transparent);
roi2.setName(overlay.getShortTitle());
if (opacity != 100)
roi2.setOpacity(opacity / 100.0);
Overlay overlayList = imp.getOverlay();
if (overlayList == null || replace)
overlayList = new Overlay();
overlayList.add(roi2);
imp.setOverlay(overlayList);
Undo.setup(Undo.OVERLAY_ADDITION, imp);
}
use of ij.gui.ImageRoi in project GDSC-SMLM by aherbert.
the class OverlayImage method addImage.
/**
* Adapted from ij.plugins.OverlayCommands#addImage(boolean) with the additional option for
* setting the zero pixels to transparent.
*/
void addImage() {
final ImagePlus imp = IJ.getImage();
final int[] wList = WindowManager.getIDList();
if (wList == null || wList.length < 2) {
IJ.error("Add Image...", "The command requires at least two open images.");
return;
}
String[] titles = new String[wList.length];
int count = 0;
for (int i = 0; i < wList.length; i++) {
final ImagePlus imp2 = WindowManager.getImage(wList[i]);
if (imp2 != null && imp2 != imp && imp.getWidth() >= imp2.getWidth() && imp.getHeight() >= imp2.getHeight()) {
titles[count++] = imp2.getTitle();
}
}
if (count < 1) {
IJ.error("Add Image...", "The command requires at least one valid overlay image.");
return;
}
titles = Arrays.copyOf(titles, count);
int x = 0;
int y = 0;
final Roi roi = imp.getRoi();
if (roi != null && roi.isArea()) {
final Rectangle r = roi.getBounds();
x = r.x;
y = r.y;
}
settings = Settings.load();
final GenericDialog gd = new GenericDialog("Add Image...");
gd.addChoice("Image to add:", titles, settings.title);
gd.addNumericField("X location:", x, 0);
gd.addNumericField("Y location:", y, 0);
gd.addNumericField("Opacity (0-100%):", settings.opacity, 0);
gd.addCheckbox("Transparent background", settings.transparent);
gd.addCheckbox("Replace overlay", settings.replace);
gd.addHelp(HelpUrls.getUrl("overlay-image"));
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
settings.title = gd.getNextChoice();
x = (int) gd.getNextNumber();
y = (int) gd.getNextNumber();
settings.opacity = (int) gd.getNextNumber();
settings.transparent = gd.getNextBoolean();
settings.replace = gd.getNextBoolean();
settings.save();
final ImagePlus overlay = WindowManager.getImage(settings.title);
if (overlay == imp) {
IJ.error("Add Image...", "Image to be added cannot be the same as\n\"" + imp.getTitle() + "\".");
return;
}
if (overlay.getWidth() > imp.getWidth() && overlay.getHeight() > imp.getHeight()) {
IJ.error("Add Image...", "Image to be added cannnot be larger than\n\"" + imp.getTitle() + "\".");
return;
}
final ImageRoi roi2 = new ImageRoi(x, y, overlay.getProcessor());
roi2.setZeroTransparent(settings.transparent);
roi2.setName(overlay.getShortTitle());
if (settings.opacity != 100) {
roi2.setOpacity(settings.opacity / 100.0);
}
Overlay overlayList = imp.getOverlay();
if (overlayList == null || settings.replace) {
overlayList = new Overlay();
}
overlayList.add(roi2);
imp.setOverlay(overlayList);
Undo.setup(Undo.OVERLAY_ADDITION, imp);
}
Aggregations