use of imagingbook.pub.geometry.basic.Pnt2d in project imagingbook-common by imagingbook.
the class AlgebraicLine method main.
// -------------------------------------------------------------------
public static void main(String[] args) {
Pnt2d p1 = Pnt2d.from(1, 2);
Pnt2d p2 = Pnt2d.from(4, 3);
Pnt2d p3 = Pnt2d.from(9, -7);
AlgebraicLine L1 = AlgebraicLine.from(p1, p2);
AlgebraicLine L2 = AlgebraicLine.from(p3, p2);
{
Pnt2d x = L1.intersect(L2);
System.out.println("x = " + x);
System.out.println("x = p2 ? " + x.equals(p2));
}
{
Pnt2d x = L2.intersect(L1);
System.out.println("x = " + x);
System.out.println("x = p2 ? " + x.equals(p2));
}
// --> null
Pnt2d y = L1.intersect(L1);
System.out.println("y = " + y);
}
use of imagingbook.pub.geometry.basic.Pnt2d in project imagingbook-common by imagingbook.
the class AlgebraicLine method equals.
// -------------------------------------------------------------------
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof AlgebraicLine) {
AlgebraicLine L1 = this;
AlgebraicLine L2 = (AlgebraicLine) other;
double delta = 1E-6;
// get two different points on L1:
Pnt2d xA = L1.getClosestLinePoint(PntDouble.ZERO);
Pnt2d xB = PntDouble.from(xA.getX() - L1.B, xA.getY() + L1.A);
// check if both points are on L2 too:
return (isZero(L2.getDistance(xA), delta) && isZero(L2.getDistance(xB), delta));
} else {
return false;
}
}
use of imagingbook.pub.geometry.basic.Pnt2d in project imagingbook-common by imagingbook.
the class TriangulationGuibas method makePointset.
// -----------------------------------------------------------------------------
/**
* Converts the incoming points (of unknown type but implementing the {@link Pnt2d} interface)
* to instances of the local implementation ({@link Vector2D}).
*
* @param inPoints the input points (must implement {@link Pnt2d})
* @param shuffle if {@code true}, the input point sequence is randomly permuted
* @return the new point sequence
*/
private List<Vector2D> makePointset(Collection<? extends Pnt2d> inPoints, boolean shuffle) {
Vector2D[] outPoints = new Vector2D[inPoints.size()];
int i = 0;
for (Pnt2d ip : inPoints) {
outPoints[i] = new Vector2D(ip);
i++;
}
List<Vector2D> outList = Arrays.asList(outPoints);
if (shuffle) {
// random permutation of pointset (in-place)
Collections.shuffle(outList);
}
return outList;
}
use of imagingbook.pub.geometry.basic.Pnt2d in project imagingbook-common by imagingbook.
the class ProcrustesFit method main.
public static void main(String[] args) {
PrintPrecision.set(6);
int NDIGITS = 1;
boolean allowTranslation = true;
boolean allowScaling = true;
boolean forceRotation = true;
double a = 0.6;
double[][] R0data = { { Math.cos(a), -Math.sin(a) }, { Math.sin(a), Math.cos(a) } };
RealMatrix R0 = MatrixUtils.createRealMatrix(R0data);
double[] t0 = { 4, -3 };
double s = 3.5;
System.out.format("original alpha: a = %.6f\n", a);
System.out.println("original rotation: R = \n" + Matrix.toString(R0.getData()));
System.out.println("original translation: t = " + Matrix.toString(t0));
System.out.format("original scale: s = %.6f\n", s);
System.out.println();
Pnt2d[] P = { PntInt.from(2, 5), PntInt.from(7, 3), PntInt.from(0, 9), PntInt.from(5, 4) };
Pnt2d[] Q = new Pnt2d[P.length];
for (int i = 0; i < P.length; i++) {
Pnt2d q = PntDouble.from(R0.operate(P[i].toDoubleArray()));
// noise!
double qx = roundToDigits(s * q.getX() + t0[0], NDIGITS);
double qy = roundToDigits(s * q.getY() + t0[1], NDIGITS);
Q[i] = Pnt2d.PntDouble.from(qx, qy);
}
// P[0] = Point.create(2, 0); // to provoke a large error
ProcrustesFit pf = new ProcrustesFit(P, Q, allowTranslation, allowScaling, forceRotation);
double[][] R = pf.getR();
System.out.format("estimated alpha: a = %.6f\n", Math.acos(R[0][0]));
System.out.println("estimated rotation: R = \n" + Matrix.toString(R));
double[] T = pf.getT();
System.out.println("estimated translation: t = " + Matrix.toString(T));
System.out.format("estimated scale: s = %.6f\n", pf.getScale());
System.out.println();
System.out.format("RMS fitting error = %.6f\n", pf.getError());
System.out.format("euclidean error (test) = %.6f\n", pf.getEuclideanError(P, Q));
double[][] A = pf.getTransformationMatrix();
System.out.println("transformation matrix: A = \n" + Matrix.toString(A));
}
use of imagingbook.pub.geometry.basic.Pnt2d in project imagingbook-common by imagingbook.
the class LucasKanadeForwardMatcher method iterateOnce.
@Override
public ProjectiveMapping2D iterateOnce(ProjectiveMapping2D Tp) {
if (iteration < 0) {
initializeMatch(Tp);
}
iteration = iteration + 1;
// n x n cumulated Hessian matrix
double[][] H = new double[n][n];
// n-dim vector \delta_p = 0
double[] dp = new double[n];
sqrError = 0;
if (params.showSteepestDescentImages) {
// S[u][v] holds a double vector of length n
S = new double[wR][hR][];
}
// for all positions (u,v) in R do
for (int u = 0; u < wR; u++) {
for (int v = 0; v < hR; v++) {
// position w.r.t. the center of R
Pnt2d x = PntDouble.from(u - xc, v - yc);
// warp x -> x'
Pnt2d xT = Tp.applyTo(x);
// interpolate the gradient at pos. xw
double gx = Ix.getInterpolatedValue(xT.getX(), xT.getY());
double gy = Iy.getInterpolatedValue(xT.getX(), xT.getY());
// interpolated gradient vector
double[] G = new double[] { gx, gy };
// Step 4: Evaluate the Jacobian of the warp W at position x
double[][] J = Tp.getJacobian(x);
// Step 5: compute the steepest descent image:
// I_steepest = gradI(xy) * dW/dp(xy) is a n-dim vector
double[] sx = Matrix.multiply(G, J);
if (params.showSteepestDescentImages && iteration == 1) {
S[u][v] = sx;
}
// Step 6: Update the Hessian matrix
double[][] Hx = Matrix.outerProduct(sx, sx);
H = Matrix.add(H, Hx);
// Step 7: Compute sum_x [gradI*dW/dp]^T (R(x)-I(W(x;p))] = Isteepest^T * Exy]
double d = R.getf(u, v) - I.getInterpolatedValue(xT.getX(), xT.getY());
sqrError = sqrError + d * d;
dp = Matrix.add(dp, Matrix.multiply(d, sx));
}
}
if (params.showHessians && iteration == 1) {
IjUtils.createImage("H", H).show();
IjUtils.createImage("Hi", Matrix.inverse(H)).show();
}
// Step 8: Compute delta_p using Equation 10
// double[][] Hi = Matrix.invert(H);
// if (Hi == null) {
// IJ.log("could not invert Hessian matrix!");
// return null;
// }
// Step 9: update the parameter vector
// double[] dp = Matrix.multiply(Hi, S);
// Step 8/9 (alternative)
double[] qopt = Matrix.solve(H, dp);
if (qopt == null) {
// this should not happen
throw new RuntimeException(this.getClass().getName() + ": Encountered singular Hessian matrix!");
// return null;
}
// double[] p = Matrix.add(Tp.getParameters(), qopt);
double[] p = Matrix.add(getParameters(Tp), qopt);
qmag = Matrix.normL2squared(qopt);
if (params.showSteepestDescentImages && iteration == 1) {
showSteepestDescentImages(S);
}
// return ProjectiveMapping2D.fromParameters(p);
return toProjectiveMap(p);
}
Aggregations