/** Computed and return the affine transform that aligns image to template. */ public AffineTransform align( final RandomAccessibleInterval<T> image, final int maxIterations, final double minParameterChange) { currentTransform.set(new AffineTransform(n)); int i = 0; while (i < maxIterations) { ++i; if (alignStep(image) < minParameterChange) break; } System.out.println("computed " + i + " iterations."); return currentTransform; }
double alignStep(final RandomAccessibleInterval<T> image) { // compute error image = warped image - template computeDifference(Views.extendBorder(image), currentTransform, template, error); // compute transform parameter update final double[] gradient = new double[numParameters]; for (int p = 0; p < numParameters; ++p) { final Cursor<T> err = Views.flatIterable(error).cursor(); for (final T t : Views.flatIterable(Views.hyperSlice(descent, n, p))) gradient[p] += t.getRealDouble() * err.next().getRealDouble(); } final double[] dp = new double[numParameters]; LinAlgHelpers.mult(Hinv, gradient, dp); // udpate transform currentTransform.preConcatenate(warpFunction.getAffine(dp)); // return norm of parameter update vector return LinAlgHelpers.length(dp); }