final static private ThinPlateR2LogRSplineKernelTransform init( final double[][] p, final double[][] q ) { assert p.length == q.length; final ThinPlateR2LogRSplineKernelTransform tps = new ThinPlateR2LogRSplineKernelTransform( p.length, p, q ); return tps; }
@Override public int numSourceDimensions() { return tps.getNumDims(); }
public void oneIteration( boolean updateError ) { // at this point, we need a target, an estimate, and a derivative matrix computeDirection(); updateEstimate( stepSz ); if ( updateError ) updateError(); }
@Override public void apply( final double[] source, final double[] target ) { tps.apply( source, target ); }
/** * Returns the index of the target landmark closest to the input point as well * as the distance to that landmark. * * @param target the point * @return a pair containing the closest landmark point and its squared * distance to that landmark */ public IndexDistancePair closestTargetLandmarkAndDistance( final double[] target ) { int idx = -1; double distSqr = Double.MAX_VALUE; double thisDist = 0.0; final double[] err = new double[ this.ndims ]; for ( int l = 0; l < this.nLandmarks; l++ ) { tgtPtDisplacement( l, target, err ); thisDist = normSqrd( err ); if ( thisDist < distSqr ) { distSqr = thisDist; idx = l; } } return new IndexDistancePair( idx, distSqr ); }
public ThinPlateR2LogRSplineKernelTransform( final int ndims, final double[][] srcPts, final double[][] tgtPts, boolean computeAffine ) { this.ndims = ndims; this.sourceLandmarks = srcPts; this.computeAffine = computeAffine; if ( sourceLandmarks != null && sourceLandmarks.length > 0 ) nLandmarks = srcPts[ 0 ].length; else nLandmarks = 0; computeW( buildDisplacements( tgtPts ) ); }
/** * Computes the inverse of this transformation. * * @param target the target point * @param result array in which to store the result * @param tolerance the desired precision - must be greater than zero * @param maxIters maximum number of iterations * @return true if the result is within the specified tolerance, false otherwise */ public double inverse( final double[] target, final double[] result, final double tolerance, final int maxIters ) { assert tolerance > 0.0; double[] guess = initialGuessAtInverse( target ); double error = inverseTol( target, guess, tolerance, maxIters ); for ( int d = 0; d < ndims; d++ ) result[ d ] = guess[ d ]; return error; }
public void oneIteration() { oneIteration( true ); }
/** * Computes the inverse of this transformation. Performs a maximum of 100,000 iterations, * returning whatever the estimate is at that point. * * @param target the target point * @param tolerance the desired precision - must be greater than zero * @return the result of applying the inverse transform to the target point */ public double[] inverse( final double[] target, final double tolerance ) { double[] out = new double[ ndims ]; inverse( target, out, tolerance, 100000 ); return out; }
/** * Constructor with weighted point matches * * @param ndims num dimensions * @param srcPts source points * @param tgtPts target points * @param weights point weights */ public ThinPlateR2LogRSplineKernelTransform( final int ndims, final double[][] srcPts, final double[][] tgtPts, final double[] weights ) { this( ndims, srcPts, tgtPts ); setWeights( weights ); }
@Override public void applyInPlace(final double[] location) { tps.applyInPlace(location); }
public static double maxError( double[][] sourcePoints, double[][] targetPoints, ThinPlateR2LogRSplineKernelTransform xfm ) { return maxError( sourcePoints, targetPoints, xfm, false ); }
public void computeG( final double[] pt, final DenseMatrix64F mtx, final double w ) { computeG( pt, mtx ); CommonOps.scale( w, mtx ); }
public void setEstimateXfm( double[] est ) { this.estimateXfm = new DenseMatrix64F( ndims, 1 ); estimateXfm.setData( est ); updateError(); }
/** * Transform pt in place. * * @param pt the point */ public void applyInPlace( final double[] pt ) { final double[] tmp = new double[ ndims ]; apply( pt, tmp ); for ( int i = 0; i < ndims; ++i ) { pt[ i ] = tmp[ i ]; } }
@Override public int numTargetDimensions() { return tps.getNumDims(); }
public void apply( final double[] pt, final double[] result ) { apply( pt, result, false ); }
private void initializeInverse() { int ndims = tps.getNumDims(); dir = new DenseMatrix64F( ndims, 1 ); errorV = new DenseMatrix64F( ndims, 1 ); directionalDeriv = new DenseMatrix64F( ndims, 1 ); descentDirectionMag = new DenseMatrix64F( 1, 1 ); }
/** * Transforms the input point according to the thin plate spline stored by * this object. * * @param pt the point to be transformed * @return the transformed point */ public double[] apply( final double[] pt ) { final double[] result = new double[ ndims ]; apply( pt, result ); return result; }
public void printXfmBacks2d( final int maxx, final int maxy, final int delx, final int dely ) { final double[] pt = new double[ 2 ]; final double[] result = new double[ 2 ]; for ( int x = 0; x < maxx; x += delx ) for ( int y = 0; y < maxy; y += dely ) { pt[ 0 ] = x; pt[ 1 ] = y; this.apply( pt, result ); System.out.println( "( " + x + ", " + y + " ) -> ( " + result[ 0 ] + ", " + result[ 0 ] + " )" ); } }