Commit 474e8a79 authored by gonciarz's avatar gonciarz
Browse files

Fix for PT - selecting trajectories

parent 75180c74
......@@ -7,7 +7,7 @@
<groupId>mosaic</groupId>
<artifactId>MosaicSuite</artifactId>
<packaging>jar</packaging>
<version>1.0.22</version>
<version>1.0.23</version>
<description>Package contains image processing algorithms developed in MOSAIC Group</description>
<url>http://mosaic.mpi-cbg.de/?q=downloads/imageJ</url>
<inceptionYear>2010</inceptionYear>
......
......@@ -307,6 +307,9 @@ public class ResultsWindow extends Frame implements FocusListener, ActionListene
else {
IJ.error(calData.errorMsg);
// error msg is printed by getImageCalibrationData() method
// Image should be visible and active to run "properties..." command
particleTracker3DModular.iInputImage.show();
WindowManager.setCurrentWindow(particleTracker3DModular.iInputImage.getWindow());
IJ.run("Properties...");
return;
......@@ -385,7 +388,7 @@ public class ResultsWindow extends Frame implements FocusListener, ActionListene
if (source == trajectory_focus) {
// user selects trajectory according to serial number (starts with 1)
// but all_traj Vector starts from 0 so (chosen_traj-1)
particleTracker3DModular.generateTrajFocusView(particleTracker3DModular.chosen_traj);
particleTracker3DModular.generateTrajFocusView(particleTracker3DModular.chosen_traj, particleTracker3DModular.iTrajectories.elementAt(particleTracker3DModular.chosen_traj).trajectoryArea);
return;
}
/* display (on the text_panel) info about the selected Trajectory */
......
......@@ -2,9 +2,7 @@ package mosaic.particleTracker;
import java.awt.Color;
import java.awt.event.MouseEvent;
import ij.ImagePlus;
import ij.gui.Roi;
import mosaic.core.detection.Particle;
......@@ -18,12 +16,10 @@ public class Trajectory {
public final Particle[] iParticles;
public int iSerialNumber;
private final ImagePlus original_imp;
public boolean to_display = true; // flag for display filter
public boolean showParticles = true; // draw particle, if false only trajectory line is drawn
public Color color; // the display color of this Trajectory
Roi mouse_selection_area; // The Roi area where a mouse click will select this trajectory
public Roi focus_area; // The Roi for focus display of this trajectory
public Roi trajectoryArea; // The Roi area where a mouse click will select this trajectory
/**
* Constructor. <br>
......@@ -32,12 +28,11 @@ public class Trajectory {
* Sets its <code>Color</code> to default (red)
* @param particles the array containing all the particles defining this Trajectory
*/
public Trajectory(Particle[] particles, int aSerialNum, ImagePlus originalImp) {
original_imp = originalImp;
public Trajectory(Particle[] particles, int aSerialNum) {
iParticles = particles;
iSerialNumber = aSerialNum;
color = Color.red;
setFocusAndSelectionArea();
setTrajectoryArea();
}
public boolean toDisplay() {
......@@ -59,59 +54,29 @@ public class Trajectory {
public int getLength() {
return getStopFrame() - getStartFrame() + 1;
}
/**
* Set the <code>focus_area</code> for this trajectory - it defines the area (ROI) focused
* on when the user selects this trajectory to focus on <br>
* The <code>focus_area</code> is an rectangular ROI that engulfs this trajectory
* with 8 pixels margin from each edge
* Set the <code>mouse_selection_area</code> for this trajectory - it defines the area (ROI)
* on which a mouse click will add this trajectory as a candidate for selection <br>
* When this trajectory is selected with a mouse click this ROI is highlighted for the user
* to see his selection. <br>
* @see TrajectoryStackWindow#mousePressed(MouseEvent)
*/
private void setFocusAndSelectionArea() {
if (original_imp == null) {
return;
}
private void setTrajectoryArea() {
/* find the min and max values of the x and y positions */
float min_x = Float.MAX_VALUE;
float min_y = Float.MAX_VALUE;
float max_x = -Float.MAX_VALUE;
float max_y = -Float.MAX_VALUE;
double min_x = Double.MAX_VALUE;
double min_y = Double.MAX_VALUE;
double max_x = -Double.MAX_VALUE;
double max_y = -Double.MAX_VALUE;
for (Particle p : iParticles) {
min_x = Math.min(p.iX, min_x);
min_y = Math.min(p.iY, min_y);
max_x = Math.max(p.iX, max_x);
max_y = Math.max(p.iY, max_y);
}
min_x = Math.floor(min_x);
max_x = Math.ceil(max_x);
min_y = Math.floor(min_y);
max_y = Math.ceil(max_y);
/*
* set the focus area x, y , height, width to give focus area bigger by 8 pixels
* then minimal rectangle surroundings this trajectory
*/
// X and Y coordinates are not in the usual graph coordinates sense but in the image sense;
// (0,0) is the upper left corner; x is vertical top to bottom, y is horizontal left to right
int focus_x = Math.max((int) min_x - 8, 0);
int focus_y = Math.max((int) min_y - 8, 0);
int focus_height = (int) max_y - focus_y + 8;
int focus_width = (int) max_x - focus_x + 8;
// make sure that the -8 or +8 did not create an ROI with bounds outside of the window
if (focus_x + focus_width > original_imp.getWidth()) {
focus_width = original_imp.getWidth() - focus_x;
}
if (focus_y + focus_height > original_imp.getHeight()) {
focus_height = original_imp.getHeight() - focus_y;
}
focus_area = new Roi(focus_x, focus_y, focus_width, focus_height);
focus_x = (int) min_x - 1;
focus_y = (int) min_y - 1;
focus_height = (int) max_x - focus_x + 1;
focus_width = (int) max_y - focus_y + 1;
mouse_selection_area = new Roi(focus_x, focus_y, focus_height, focus_width);
int focus_x = (int) min_x;
int focus_y = (int) min_y;
int focus_height = (int) (max_y - min_y) + 1;
int focus_width = (int) (max_x - min_x) + 1;
trajectoryArea = new Roi(focus_x, focus_y, focus_width, focus_height);
}
@Override
......
package mosaic.particleTracker;
import java.awt.Button;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
......@@ -17,6 +11,7 @@ import java.util.Vector;
import ij.IJ;
import ij.ImagePlus;
import ij.gui.ImageCanvas;
import ij.gui.Roi;
import ij.gui.StackWindow;
import ij.measure.Calibration;
import mosaic.core.detection.MyFrame;
......@@ -157,6 +152,19 @@ public class TrajectoryStackWin extends StackWindow implements MouseListener {
particleTracker3DModular.generateView(this.imp, this.out);
}
static public Roi getBiggerROI(Roi r, ImagePlus img, int size) {
Rectangle bounds = r.getBounds();
int newX = Math.max(0, bounds.x - size);
int newY = Math.max(0, bounds.y - size);
int newWidth = bounds.width + 2*size;
if (newX + newWidth > img.getWidth()) newWidth = img.getWidth() - newX;
int newHeight = bounds.height + 2*size;
if (newY + newHeight > img.getHeight()) newHeight = img.getHeight() - newY;
return new Roi(newX, newY, newWidth, newHeight);
}
/**
* Defines the action taken upon an <code>MouseEvent</code> triggered by left-clicking the mouse anywhere in this <code>TrajectoryStackWindow</code>
*
......@@ -170,7 +178,8 @@ public class TrajectoryStackWin extends StackWindow implements MouseListener {
final Vector<Trajectory> v = new Vector<Trajectory>();
v.add(particleTracker3DModular.iTrajectories.get(particleTracker3DModular.chosen_traj));
final Calibration cal = particleTracker3DModular.iInputImage.getCalibration();
// If input is taken from csv files then iInputImage might not be there
final Calibration cal = particleTracker3DModular.iInputImage == null ? null : particleTracker3DModular.iInputImage.getCalibration();
MyFrame.updateImage(out, v, cal, DrawType.TRAJECTORY_HISTORY, particleTracker3DModular.getRadius());
......@@ -183,7 +192,6 @@ public class TrajectoryStackWin extends StackWindow implements MouseListener {
/* covert them to offScreen coordinates using the ImageCanvas of this window */
final int offscreenX = this.ic.offScreenX(x);
final int offscreenY = this.ic.offScreenY(y);
boolean trajectory_clicked = false;
final Iterator<Trajectory> iter = particleTracker3DModular.iTrajectories.iterator();
......@@ -207,10 +215,10 @@ public class TrajectoryStackWin extends StackWindow implements MouseListener {
final Vector<Trajectory> v = new Vector<Trajectory>();
v.add(curr_traj);
final Calibration cal = particleTracker3DModular.iInputImage.getCalibration();
// If input is taken from csv files then iInputImage might not be there
final Calibration cal = particleTracker3DModular.iInputImage == null ? null : particleTracker3DModular.iInputImage.getCalibration();
MyFrame.updateImage(out, v, cal, DrawType.TRAJECTORY_HISTORY, particleTracker3DModular.getRadius());
trajectory_clicked = true;
particleTracker3DModular.chosen_traj = ct;
break;
......@@ -229,14 +237,18 @@ public class TrajectoryStackWin extends StackWindow implements MouseListener {
if (e.getClickCount() == 2) {
// "double-click"
// Set the ROI to the trajectory focus_area
IJ.getImage().setRoi((particleTracker3DModular.iTrajectories.elementAt(particleTracker3DModular.chosen_traj)).focus_area);
Roi mouse_selection_area = (particleTracker3DModular.iTrajectories.elementAt(particleTracker3DModular.chosen_traj)).trajectoryArea;
Roi roi = getBiggerROI(mouse_selection_area, imp, 8);
IJ.getImage().setRoi(roi);
// focus on Trajectory (ROI)
particleTracker3DModular.generateTrajFocusView(particleTracker3DModular.chosen_traj);
particleTracker3DModular.generateTrajFocusView(particleTracker3DModular.chosen_traj, roi);
}
else {
// single-click - mark the selected trajectory by setting the ROI to the
// trajectory mouse_selection_area
this.imp.setRoi((particleTracker3DModular.iTrajectories.elementAt(particleTracker3DModular.chosen_traj)).mouse_selection_area);
Trajectory traj = particleTracker3DModular.iTrajectories.elementAt(particleTracker3DModular.chosen_traj);
Roi roi = getBiggerROI(traj.trajectoryArea, imp, 2);
this.imp.setRoi(roi);
}
}
else {
......
......@@ -903,14 +903,14 @@ public class ParticleTracker3DModular_ implements PlugInFilter, PreviewInterface
* @see ImagePlus#getRoi()
* @see StackConverter#convertToRGB()
*/
public void generateTrajFocusView(int trajectory_index) {
public void generateTrajFocusView(int trajectory_index, Roi area) {
int magnification = results_window.magnification_factor;
// create a title
final String new_title = "[Trajectory number " + (trajectory_index + 1) + "]";
// get the trajectory at the given index
final Trajectory traj = (iTrajectories.elementAt(trajectory_index));
final Rectangle r = traj.focus_area.getBounds();
final Rectangle r = area.getBounds();
// Create a cropped rescaled image
final Img<UnsignedByteType> img = ImagePlusAdapter.wrap(iInputImage);
......@@ -936,7 +936,7 @@ public class ParticleTracker3DModular_ implements PlugInFilter, PreviewInterface
final Vector<Trajectory> vt = new Vector<Trajectory>();
vt.add(traj);
final Calibration cal = iInputImage.getCalibration();
MyFrame.updateImage(focus_view, traj.focus_area.getBounds(), traj.getStartFrame(), vt, cal, DrawType.TRAJECTORY_HISTORY, getRadius());
MyFrame.updateImage(focus_view, area.getBounds(), traj.getStartFrame(), vt, cal, DrawType.TRAJECTORY_HISTORY, getRadius());
final ImagePlus imp = ImageJFunctions.show(focus_view);
imp.setTitle(new_title);
......@@ -1336,6 +1336,22 @@ public class ParticleTracker3DModular_ implements PlugInFilter, PreviewInterface
* @return array with [pixelDimensions, timeInterval] - if null there was some error getting cal. data.
*/
public CalibrationData getImageCalibrationData() {
logger.debug("iInputImage = " + iInputImage);
if (iInputImage == null) {
IJ.showStatus("Creating image from particles and trajectories ...");
final Img<ARGBType> iw = createHyperStackFromFrames();
if (iw != null) {
iInputImage = ImageJFunctions.wrap(iw, "Video");
}
else {
return new CalibrationData(0.0, 0.0, "Could not create image from provided particle data! MMS/MSD calculation not possible.");
}
}
logger.debug("iInputImage = " + iInputImage);
// Get all calibration data from image
final double width = iInputImage.getCalibration().pixelWidth;
final double height = iInputImage.getCalibration().pixelHeight;
......@@ -1598,9 +1614,7 @@ public class ParticleTracker3DModular_ implements PlugInFilter, PreviewInterface
}
// Create the current trajectory
iTrajectories.add(new Trajectory(currTrajectory.toArray(new Particle[0]),
iTrajectories.size() + 1, // serial number
iInputImage));
iTrajectories.add(new Trajectory(currTrajectory.toArray(new Particle[0]), iTrajectories.size() + 1));
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment