use of mpicbg.models.PointMatch in project TrakEM2 by trakem2.
the class TransformMesh method applyInverseInPlace.
/**
* Catch non-invertible locations outside of the meshes boundaries and
* transfer them with the affine defined by the `closest' affine (the affine
* whose summed up control points distances to location are smallest).
*/
@Override
public void applyInverseInPlace(final double[] location) throws NoninvertibleModelException {
assert location.length == 2 : "2d transform meshs can be applied to 2d points only.";
final Set<AffineModel2D> s = av.keySet();
for (final AffineModel2D ai : s) {
final ArrayList<PointMatch> pm = av.get(ai);
if (isInConvexTargetPolygon(pm, location)) {
ai.applyInverseInPlace(location);
return;
}
}
/* not in the mesh, find the closest affine */
double dMin = Double.MAX_VALUE;
AffineModel2D closestAffine = new AffineModel2D();
final double x = location[0];
final double y = location[1];
for (final AffineModel2D ai : s) {
final ArrayList<PointMatch> pm = av.get(ai);
double d = 0;
for (final PointMatch p : pm) {
final double[] w = p.getP2().getW();
final double dx = w[0] - x;
final double dy = w[1] - y;
d += Math.sqrt(dx * dx + dy * dy);
}
if (d < dMin) {
dMin = d;
closestAffine = ai;
}
}
closestAffine.applyInverseInPlace(location);
throw new NoninvertibleModelException("Mesh external location ( " + x + ", " + y + " ) transferred to ( " + location[0] + ", " + location[1] + " ) by closest affine.");
}
use of mpicbg.models.PointMatch in project TrakEM2 by trakem2.
the class MovingLeastSquaresTransform method applyInPlace.
@Override
public final void applyInPlace(final double[] location) {
final Collection<PointMatch> weightedMatches = new ArrayList<PointMatch>();
for (final PointMatch m : matches) {
final double[] l = m.getP1().getL();
double s = 0;
for (int i = 0; i < location.length; ++i) {
final double dx = l[i] - location[i];
s += dx * dx;
}
if (s <= 0) {
final double[] w = m.getP2().getW();
for (int i = 0; i < location.length; ++i) location[i] = w[i];
return;
}
final double weight = m.getWeight() * weigh(s);
final PointMatch mw = new PointMatch(m.getP1(), m.getP2(), weight);
weightedMatches.add(mw);
}
try {
synchronized (model) {
model.fit(weightedMatches);
model.applyInPlace(location);
}
} catch (final IllDefinedDataPointsException e) {
} catch (final NotEnoughDataPointsException e) {
}
}
use of mpicbg.models.PointMatch in project TrakEM2 by trakem2.
the class MovingLeastSquaresTransform method init.
@Override
public final void init(final String data) throws NumberFormatException {
matches.clear();
final String[] fields = data.split("\\s+");
if (fields.length > 3) {
final int d = Integer.parseInt(fields[1]);
if ((fields.length - 3) % (2 * d + 1) == 0) {
if (d == 2) {
if (fields[0].equals("translation"))
model = new TranslationModel2D();
else if (fields[0].equals("rigid"))
model = new RigidModel2D();
else if (fields[0].equals("similarity"))
model = new SimilarityModel2D();
else if (fields[0].equals("affine"))
model = new AffineModel2D();
else
throw new NumberFormatException("Inappropriate parameters for " + this.getClass().getCanonicalName());
} else if (d == 3) {
if (fields[0].equals("affine"))
model = new AffineModel3D();
else
throw new NumberFormatException("Inappropriate parameters for " + this.getClass().getCanonicalName());
} else
throw new NumberFormatException("Inappropriate parameters for " + this.getClass().getCanonicalName());
alpha = Double.parseDouble(fields[2]);
int i = 2;
while (i < fields.length - 1) {
final double[] p1 = new double[d];
for (int k = 0; k < d; ++k) p1[k] = Double.parseDouble(fields[++i]);
final double[] p2 = new double[d];
for (int k = 0; k < d; ++k) p2[k] = Double.parseDouble(fields[++i]);
final double weight = Double.parseDouble(fields[++i]);
final PointMatch m = new PointMatch(new Point(p1), new Point(p2), weight);
matches.add(m);
}
} else
throw new NumberFormatException("Inappropriate parameters for " + this.getClass().getCanonicalName());
} else
throw new NumberFormatException("Inappropriate parameters for " + this.getClass().getCanonicalName());
}
use of mpicbg.models.PointMatch in project TrakEM2 by trakem2.
the class StitchingTEM method addMatches.
/**
* dx, dy is the position of t2 relative to the 0,0 of t1.
*/
private static final void addMatches(final AbstractAffineTile2D<?> t1, final AbstractAffineTile2D<?> t2, final double dx, final double dy) {
final Point p1 = new Point(new double[] { 0, 0 });
final Point p2 = new Point(new double[] { dx, dy });
t1.addMatch(new PointMatch(p2, p1, 1.0f));
t2.addMatch(new PointMatch(p1, p2, 1.0f));
t1.addConnectedTile(t2);
t2.addConnectedTile(t1);
}
use of mpicbg.models.PointMatch in project TrakEM2 by trakem2.
the class Distortion_Correction method extractSIFTPointsThreaded.
protected static void extractSIFTPointsThreaded(final int index, final List<Feature>[] siftFeatures, final List<PointMatch>[] inliers, final AbstractAffineModel2D<?>[] models) {
// save all matching candidates
final List<PointMatch>[] candidates = new List[siftFeatures.length - 1];
final Thread[] threads = MultiThreading.newThreads();
// start at second
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ++ithread) {
threads[ithread] = new Thread() {
@Override
public void run() {
setPriority(Thread.NORM_PRIORITY);
for (int j = ai.getAndIncrement(); j < candidates.length; j = ai.getAndIncrement()) {
final int i = (j < index ? j : j + 1);
candidates[j] = FloatArray2DSIFT.createMatches(siftFeatures[index], siftFeatures[i], 1.5f, null, Float.MAX_VALUE, 0.5f);
}
}
};
}
MultiThreading.startAndJoin(threads);
// get rid of the outliers and save the rigid transformations to match
// the inliers
final AtomicInteger ai2 = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ++ithread) {
threads[ithread] = new Thread() {
@Override
public void run() {
setPriority(Thread.NORM_PRIORITY);
for (int i = ai2.getAndIncrement(); i < candidates.length; i = ai2.getAndIncrement()) {
final List<PointMatch> tmpInliers = new ArrayList<PointMatch>();
// RigidModel2D m =
// RigidModel2D.estimateBestModel(candidates.get(i),
// tmpInliers, sp.min_epsilon, sp.max_epsilon,
// sp.min_inlier_ratio);
final AbstractAffineModel2D<?> m;
switch(sp.expectedModelIndex) {
case 0:
m = new TranslationModel2D();
break;
case 1:
m = new RigidModel2D();
break;
case 2:
m = new SimilarityModel2D();
break;
case 3:
m = new AffineModel2D();
break;
default:
return;
}
boolean modelFound = false;
try {
modelFound = m.filterRansac(candidates[i], tmpInliers, 1000, sp.maxEpsilon, sp.minInlierRatio, 10);
} catch (final NotEnoughDataPointsException e) {
modelFound = false;
}
if (modelFound)
IJ.log("Model found:\n " + candidates[i].size() + " candidates\n " + tmpInliers.size() + " inliers\n " + String.format("%.2f", m.getCost()) + "px average displacement");
else
IJ.log("No Model found.");
inliers[index * (sp.numberOfImages - 1) + i] = tmpInliers;
models[index * (sp.numberOfImages - 1) + i] = m;
// System.out.println("**** MODEL ADDED: " +
// (index*(sp.numberOfImages-1)+i));
}
}
};
}
MultiThreading.startAndJoin(threads);
}
Aggregations