Search in sources :

Example 1 with Tuple3d

use of org.scijava.vecmath.Tuple3d in project TrakEM2 by trakem2.

the class Compare method transferVectorStrings.

/**
 * Transform all points of all VectorString3D in vs using a Moving Least Squares Transform defined by the pairing of points in source to those in target.
 *  In short, bring source into target.
 */
public static List<VectorString3D> transferVectorStrings(final List<VectorString3D> vs, final List<Tuple3d> source, final List<Tuple3d> target, final Class<AffineModel3D> model_class) throws Exception {
    if (source.size() != target.size()) {
        Utils.log2("Could not generate a MovingLeastSquaresTransform: different number of source and target points.");
        return null;
    }
    if (source.size() < 1 || target.size() < 1) {
        Utils.log2("Cannot transform with less than one point correspondence!");
        return null;
    }
    // 1 - Create the MovingLeastSquaresTransform from the point matches
    final ArrayList<PointMatch> pm = new ArrayList<PointMatch>();
    for (final Iterator<Tuple3d> si = source.iterator(), ti = target.iterator(); si.hasNext(); ) {
        final Tuple3d sp = si.next();
        final Tuple3d tp = ti.next();
        pm.add(new PointMatch(new mpicbg.models.Point(new double[] { sp.x, sp.y, sp.z }), new mpicbg.models.Point(new double[] { tp.x, tp.y, tp.z }), 1));
    }
    final MovingLeastSquaresTransform mls = new MovingLeastSquaresTransform();
    mls.setModel(model_class);
    mls.setMatches(pm);
    final double[] point = new double[3];
    // 1.1 - Test: transfer source points
    /*
		for (final Iterator<Tuple3d> si = source.iterator(), ti = target.iterator(); si.hasNext(); ) {
			Tuple3d sp = si.next();
			point[0] = (double) sp.x;
			point[1] = (double) sp.y;
			point[2] = (double) sp.z;
			mls.applyInPlace(point);

			Tuple3d tp = ti.next();
			Utils.log2("== target: " + (double)tp.x + ", " + (double)tp.y + ", " + (double)tp.z +
				   "\n o source: " + (double)sp.x + ", " + (double)sp.y + ", " + (double)sp.z +

				   "\n   source: " + point[0] + ", " + point[1] + ", " + point[2]);
		}
		*/
    // 2 - Transfer each VectorString3D in vs with mls
    final List<VectorString3D> vt = new ArrayList<VectorString3D>();
    for (final VectorString3D vi : vs) {
        // The points of the VectorString3D:
        final double[] x = vi.getPoints(0);
        final double[] y = vi.getPoints(1);
        final double[] z = vi.getPoints(2);
        // Empty arrays to fill with the points to transfer:
        final double[] tx = new double[x.length];
        final double[] ty = new double[x.length];
        final double[] tz = new double[x.length];
        // Transfer point by point:
        for (int i = 0; i < x.length; i++) {
            point[0] = x[i];
            point[1] = y[i];
            point[2] = z[i];
            mls.applyInPlace(point);
            tx[i] = point[0];
            ty[i] = point[1];
            tz[i] = point[2];
        }
        try {
            vt.add(new VectorString3D(tx, ty, tz, vi.isClosed()));
        } catch (final Exception e) {
        }
    }
    return vt;
}
Also used : ArrayList(java.util.ArrayList) PointMatch(mpicbg.models.PointMatch) MovingLeastSquaresTransform(mpicbg.models.MovingLeastSquaresTransform) VectorString3D(ini.trakem2.vector.VectorString3D) Tuple3d(org.scijava.vecmath.Tuple3d)

Example 2 with Tuple3d

use of org.scijava.vecmath.Tuple3d in project TrakEM2 by trakem2.

the class Compare method extractMatches.

/**
 * Filer both maps, looking for matches, and put them into empty lists so and ta.
 */
private static boolean extractMatches(final Map<String, Tuple3d> source, final Map<String, Tuple3d> target, final List<Tuple3d> so, final List<Tuple3d> ta) {
    if (null == source || null == target || null == so || null == ta)
        return false;
    so.clear();
    ta.clear();
    for (final Map.Entry<String, Tuple3d> e : target.entrySet()) {
        final Tuple3d point = source.get(e.getKey());
        if (null != point) {
            so.add(point);
            ta.add(e.getValue());
        }
    }
    if (0 == so.size()) {
        Utils.log2("No points in common!");
        return false;
    }
    return true;
}
Also used : Tuple3d(org.scijava.vecmath.Tuple3d) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 3 with Tuple3d

use of org.scijava.vecmath.Tuple3d in project TrakEM2 by trakem2.

the class Compare method gatherChains.

/**
 * Gather chains for all projects considering the cp.regex, and transforms all relative to the reference Project p[0].
 *  Will ignore any for which a match exists in @param ignore.
 */
public static final Object[] gatherChains(final Project[] p, final CATAParameters cp, final String[] ignore) throws Exception {
    String regex_exclude = null;
    if (null != ignore) {
        final StringBuilder sb = new StringBuilder();
        for (final String ig : ignore) {
            sb.append("(.*").append(ig).append(".*)|");
        }
        sb.setLength(sb.length() - 1);
        regex_exclude = sb.toString();
    }
    Utils.logAll("Compare/gatherChains: using ignore string: " + regex_exclude);
    Utils.logAll("Compare/gatherChains: using regex: " + cp.regex);
    // gather all chains
    // to keep track of each project's chains
    final ArrayList[] p_chains = new ArrayList[p.length];
    final ArrayList<Chain> chains = new ArrayList<Chain>();
    for (int i = 0; i < p.length; i++) {
        // for each project:
        if (null == cp.regex) {
            p_chains[i] = createPipeChains(p[i].getRootProjectThing(), p[i].getRootLayerSet(), regex_exclude);
        } else {
            // Search (shallow) for cp.regex matches
            for (final ProjectThing pt : p[i].getRootProjectThing().findChildren(cp.regex, regex_exclude, true)) {
                final ArrayList<Chain> ac = createPipeChains(pt, p[i].getRootLayerSet(), regex_exclude);
                if (null == p_chains[i])
                    p_chains[i] = ac;
                else
                    p_chains[i].addAll(ac);
            }
            // empty
            if (null == p_chains[i])
                p_chains[i] = new ArrayList<Chain>();
        }
        chains.addAll(p_chains[i]);
        // calibrate
        final Calibration cal = p[i].getRootLayerSet().getCalibrationCopy();
        for (final Chain chain : (ArrayList<Chain>) p_chains[i]) chain.vs.calibrate(cal);
    }
    final int n_chains = chains.size();
    // register all, or relative
    if (4 == cp.transform_type) {
        // compute global average delta
        if (0 == cp.delta) {
            for (final Chain chain : chains) {
                cp.delta += (chain.vs.getAverageDelta() / n_chains);
            }
        }
        Utils.log2("Using delta: " + cp.delta);
        for (final Chain chain : chains) {
            // BEFORE making it relative
            chain.vs.resample(cp.delta, cp.with_source);
            chain.vs.relative();
        }
    } else {
        if (3 == cp.transform_type) {
            // '3' means moving least squares computed from 3D landmarks
            Utils.log2("Moving Least Squares Registration based on common fiducial points");
            // Find fiducial points, if any
            final HashMap<Project, Map<String, Tuple3d>> fiducials = new HashMap<Project, Map<String, Tuple3d>>();
            for (final Project pr : p) {
                final Set<ProjectThing> fids = pr.getRootProjectThing().findChildrenOfTypeR("fiducial_points");
                if (null == fids || 0 == fids.size()) {
                    Utils.log("No fiducial points found in project: " + pr);
                } else {
                    // the first fiducial group
                    fiducials.put(pr, Compare.extractPoints(fids.iterator().next()));
                }
            }
            if (!fiducials.isEmpty()) {
                // Register all VectorString3D relative to the first project:
                final List<VectorString3D> lvs = new ArrayList<VectorString3D>();
                final Calibration cal2 = p[0].getRootLayerSet().getCalibrationCopy();
                for (final Chain chain : chains) {
                    final Project pr = chain.pipes.get(0).getProject();
                    // first project is reference, no need to transform.
                    if (pr == p[0])
                        continue;
                    lvs.clear();
                    lvs.add(chain.vs);
                    chain.vs = transferVectorStrings(lvs, fiducials.get(pr), fiducials.get(p[0])).get(0);
                    // Set (but do not apply!) the calibration of the reference project
                    chain.vs.setCalibration(cal2);
                }
            }
        } else if (cp.transform_type < 3) {
            // '0', '1' and '2' involve a 3D affine computed from the 3 axes
            // no need //VectorString3D[][] vs_axes = new VectorString3D[p.length][];
            Vector3d[][] o = new Vector3d[p.length][];
            for (int i = 0; i < p.length; i++) {
                // 1 - find pipes to work as axes for each project
                final ArrayList<ZDisplayable> pipes = p[i].getRootLayerSet().getZDisplayables(Line3D.class, true);
                final String[] pipe_names = new String[pipes.size()];
                for (int k = 0; k < pipes.size(); k++) {
                    pipe_names[k] = p[i].getMeaningfulTitle(pipes.get(k));
                }
                final int[] s = findFirstXYZAxes(cp.preset, pipes, pipe_names);
                // if axes are -1, forget it: not found
                if (-1 == s[0] || -1 == s[1] || -1 == s[2]) {
                    Utils.log("Can't find axes for project " + p[i]);
                    o = null;
                    return null;
                }
                // obtain axes and origin
                final Object[] pack = obtainOrigin(new Line3D[] { (Line3D) pipes.get(s[0]), (Line3D) pipes.get(s[1]), (Line3D) pipes.get(s[2]) }, cp.transform_type, // will be null for the first, which will then be non-null and act as the reference for the others.
                o[0]);
                // no need //vs_axes[i] = (VectorString3D[])pack[0];
                o[i] = (Vector3d[]) pack[1];
            }
            /* // OLD WAY
				// match the scales to make the largest be 1.0
				final double scaling_factor = VectorString3D.matchOrigins(o, transform_type);
				Utils.log2("matchOrigins scaling factor: " + scaling_factor + " for transform_type " + transform_type);
				*/
            // transform all except the first (which acts as reference)
            final Transform3D M_ref = Compare.createTransform(o[0]);
            for (int i = 1; i < p.length; i++) {
                final Vector3d trans = new Vector3d(-o[i][3].x, -o[i][3].y, -o[i][3].z);
                final Transform3D M_query = Compare.createTransform(o[i]);
                // The transfer T transform: from query space to reference space.
                final Transform3D T = new Transform3D(M_ref);
                T.mulInverse(M_query);
                for (final Chain chain : (ArrayList<Chain>) p_chains[i]) {
                    // in place
                    chain.vs.transform(T);
                }
            }
        }
        // compute global average delta, after correcting calibration and transformation
        if (0 == cp.delta) {
            for (final Chain chain : chains) {
                cp.delta += (chain.vs.getAverageDelta() / n_chains);
            }
        }
        Utils.log2("Using delta: " + cp.delta);
        // After calibration and transformation, resample all to the same delta
        for (final Chain chain : chains) chain.vs.resample(cp.delta, cp.with_source);
    }
    return new Object[] { chains, p_chains };
}
Also used : HashMap(java.util.HashMap) Transform3D(org.scijava.java3d.Transform3D) ArrayList(java.util.ArrayList) Calibration(ij.measure.Calibration) Line3D(ini.trakem2.display.Line3D) Project(ini.trakem2.Project) VectorString3D(ini.trakem2.vector.VectorString3D) Vector3d(org.scijava.vecmath.Vector3d) Tuple3d(org.scijava.vecmath.Tuple3d) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) ProjectThing(ini.trakem2.tree.ProjectThing)

Example 4 with Tuple3d

use of org.scijava.vecmath.Tuple3d in project TrakEM2 by trakem2.

the class Compare method extractPoints.

/**
 * Extracts the list of fiduciary points from the fiducial parent and, if their name is different than "ball", adds their title as key and their first ball as a fiduciary point value of the returned map. The map is never null but could be empty.
 * The values are calibrated.
 */
public static Map<String, Tuple3d> extractPoints(final ProjectThing fiducial) {
    if (!fiducial.getType().equals("fiducial_points")) {
        Utils.log("Can only extract points from 'fiducial_points' type.");
        return null;
    }
    final ArrayList<ProjectThing> fiducials = fiducial.getChildren();
    if (null == fiducials || 0 == fiducials.size()) {
        Utils.log("No fiducial points can be extracted from " + fiducial);
        return null;
    }
    final Map<String, Tuple3d> fide = new HashMap<String, Tuple3d>();
    for (final ProjectThing child : fiducials) {
        final Ball ball;
        final String title;
        if (child.getType().equals("ball")) {
            // Method 1: use the ball title as the fiducial type
            ball = (Ball) child.getObject();
            title = ball.getTitle();
        } else {
            // Method 2: use the ball's parent type as the fiducial type
            final ArrayList<ProjectThing> balls = child.findChildrenOfType("ball");
            if (null == balls || 0 == balls.size()) {
                Utils.log2("Ignoring empty fiducial " + child);
                continue;
            }
            // pick the first one only
            ball = (Ball) balls.get(0).getObject();
            title = child.getType();
        }
        // calibrated
        final double[][] b = ball.getWorldBalls();
        if (b.length > 0) {
            // get the first one only
            fide.put(title.toLowerCase(), new Point3d(b[0][0], b[0][1], b[0][2]));
            Utils.log2("Found fiducial point " + title.toLowerCase());
        }
    }
    return fide;
}
Also used : Ball(ini.trakem2.display.Ball) HashMap(java.util.HashMap) Tuple3d(org.scijava.vecmath.Tuple3d) Point3d(org.scijava.vecmath.Point3d) ProjectThing(ini.trakem2.tree.ProjectThing)

Example 5 with Tuple3d

use of org.scijava.vecmath.Tuple3d in project TrakEM2 by trakem2.

the class Compare method transferVectorStrings.

/**
 * Transfer vs via a moving least squares transform by matching source named points into equally named target named points.
 *  If no points in common, returns null.
 */
public static List<VectorString3D> transferVectorStrings(final List<VectorString3D> vs, final Map<String, Tuple3d> source, final Map<String, Tuple3d> target) throws Exception {
    if (null == source || null == target)
        return null;
    final List<Tuple3d> so = new ArrayList<Tuple3d>();
    final List<Tuple3d> ta = new ArrayList<Tuple3d>();
    for (final Map.Entry<String, Tuple3d> e : target.entrySet()) {
        final Tuple3d point = source.get(e.getKey());
        if (null != point) {
            so.add(point);
            ta.add(e.getValue());
        }
    }
    if (0 == so.size()) {
        Utils.log2("No points in common!");
        return null;
    }
    Utils.log2("Found points in common: " + so.size());
    return transferVectorStrings(vs, so, ta, AffineModel3D.class);
}
Also used : Tuple3d(org.scijava.vecmath.Tuple3d) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Aggregations

Tuple3d (org.scijava.vecmath.Tuple3d)5 HashMap (java.util.HashMap)4 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 ProjectThing (ini.trakem2.tree.ProjectThing)2 VectorString3D (ini.trakem2.vector.VectorString3D)2 Calibration (ij.measure.Calibration)1 Project (ini.trakem2.Project)1 Ball (ini.trakem2.display.Ball)1 Line3D (ini.trakem2.display.Line3D)1 MovingLeastSquaresTransform (mpicbg.models.MovingLeastSquaresTransform)1 PointMatch (mpicbg.models.PointMatch)1 Transform3D (org.scijava.java3d.Transform3D)1 Point3d (org.scijava.vecmath.Point3d)1 Vector3d (org.scijava.vecmath.Vector3d)1