/*- * #%L * Fiji distribution of ImageJ for the life sciences. * %% * Copyright (C) 2007 - 2017 Fiji developers. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package mpicbg.pointdescriptor.matcher; import java.util.ArrayList; import spim.vecmath.Matrix3d; import spim.vecmath.Point3d; import spim.vecmath.Quat4d; import spim.vecmath.Vector3d; import mpicbg.models.PointMatch; import mpicbg.models.RigidModel3D; import mpicbg.pointdescriptor.model.TranslationInvariantRigidModel3D; import mpicbg.util.TransformUtils; public class ModelPriorSubsetMatcher extends SubsetMatcher { final RigidModel3D model; final Point3d referenceAxis; final float angle; final Matrix3d referenceMatrix, invertedReferenceMatrix; public ModelPriorSubsetMatcher( final int subsetSize, final int numNeighbors, final RigidModel3D model ) { super( subsetSize, numNeighbors ); this.model = model; this.referenceMatrix = new Matrix3d(); TransformUtils.getTransform3D( model ).get( referenceMatrix ); this.invertedReferenceMatrix = new Matrix3d( this.referenceMatrix ); this.invertedReferenceMatrix.invert(); final Quat4d quaternion = new Quat4d(); quaternion.set( referenceMatrix ); this.angle = (float)Math.toDegrees( Math.acos( quaternion.getW() ) * 2 ); final Vector3d axis = new Vector3d( quaternion.getX(), quaternion.getY(), quaternion.getZ() ); axis.normalize(); this.referenceAxis = new Point3d( axis ); } @Override public double getNormalizationFactor( final ArrayList<PointMatch> matches, final Object fitResult ) { final TranslationInvariantRigidModel3D matchModel = (TranslationInvariantRigidModel3D)fitResult; /* get input matrices and quaternion that we can alter */ final Quat4d quaternion = new Quat4d(); final Matrix3d templateMatrix = new Matrix3d(); matchModel.getMatrix3d( templateMatrix ); /* Compute the rotation angle between the two rigid 3d transformations */ templateMatrix.mul( invertedReferenceMatrix ); quaternion.set( templateMatrix ); final float angle = Math.max( 5, (float)Math.toDegrees( Math.acos( quaternion.getW() ) * 2 ) ) - 5; /* Compute vector difference between the two rotation axes */ //final Vector3f axis = new Vector3f( quaternion.getX(), quaternion.getY(), quaternion.getZ() ); //axis.normalize(); //final Point3f templateAxis = new Point3f( axis ); //final float difference = templateAxis.distance( referenceAxis ); final float weight = ( 1.0f + 0.03f * angle * angle ); return weight; //return Math.pow( 10, difference ); } }