Loading Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java +12 −14 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ public class ProcrustesAnalysis { * Using generalized orthogonal procrustes analysis need to be first moved * over each other, then scale and then rotate. * * @return ProcrustesTransformation computed for secondary face * @throws DataFormatException if faces have less than 3 feature points in * which case analysis doesn't make sense */ Loading Loading @@ -136,19 +137,10 @@ public class ProcrustesAnalysis { }); } /** * Moves face model by given vector values. Different vector value is used * for vertices and feature points. This method is used to fit feature * points to already superimposed position over given face1, but move * vertices of face back to original position of face so all the vertex * movement is done by Procrustes visitor. * * @param faceModel on which adjustment will be applied * @param vertexVector vertex adjustment * @param featurePointVector feature points adjustment */ /** * By rotation of matrices solves orthogonal procrustes problem. * * @return rotation matrix */ private SimpleMatrix rotate() { SimpleMatrix primaryMatrix = createMatrixFromList(this.faceModel2.getFeaturePointValues()); Loading Loading @@ -205,7 +197,7 @@ public class ProcrustesAnalysis { /** * Finds centroid from given feature point List * * @param featurePointList * @param featurePointList list of feature points for which we want to find centroid * @return centroid of feature points (Vector3F) */ private Point3d findCentroidOfFeaturePoints(List<FeaturePoint> featurePointList) { Loading Loading @@ -263,8 +255,8 @@ public class ProcrustesAnalysis { * Finds corresponding subset of feature points from both faces so the * procrustes analysis can be applied on the subset. * * @param featurePoints * @param featurePoints0 * @param featurePoints1 * @param featurePoints2 * * @return List of feature point types that are in both sets of feature * points Loading @@ -284,6 +276,12 @@ public class ProcrustesAnalysis { return vaiablePoints; } /** * scales list by recalculating its points position values * * @param list of points to be scaled * @param scaleFactor factor by how much the points should be scaled */ private void scaleFeaturePoints(List<FeaturePoint> list, double scaleFactor) { for (FeaturePoint point : list) { ProcrustesUtils.scalePointDistance(point, scaleFactor); Loading Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java +2 −2 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ public class ProcrustesAnalysisFaceModel { * * @param featurePoints * @param viablePoints * @return * @return list containing subset of feature points defined over a face that are marked as a viable points */ private List<FeaturePoint> getSelectionOfFeaturePoints(List<FeaturePoint> featurePoints, List<Integer> viablePoints) { ArrayList<FeaturePoint> selection = new ArrayList<>(); Loading @@ -87,7 +87,7 @@ public class ProcrustesAnalysisFaceModel { * Map key is feature point type (Integer). Value is feature point itself. * * @param featurePointList * @return * @return hash map of feature points */ private HashMap<Integer, FeaturePoint> createFeaturePointMap(List<FeaturePoint> featurePointList) { HashMap<Integer, FeaturePoint> map = new HashMap<>(); Loading Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesTransformation.java +29 −39 Original line number Diff line number Diff line Loading @@ -19,42 +19,26 @@ public class ProcrustesTransformation { private Vector3d superImpositionAdjustment; private SimpleMatrix rotationMatrix; // /** // * constructor // * // * @param scale determines by how much should be faced enlarged or minimized // * @param adjustment determines how should be face moved to make faces // * superimposed considering feature points // * @param rotationMatrix determines how to rotate face // * @param updatedFaceModel holds information about adjusted face // */ // public ProcrustesTransformation( // double scale, // Vector3d centroidAdjustment, // Vector3d superImpositionAdjustment, // SimpleMatrix rotationMatrix, // HashMap<Integer, FeaturePoint> updatedFeaturePointsMap) { // this.scale = scale; // this.centroidAdjustment = centroidAdjustment; // this.superImpositionAdjustment = superImpositionAdjustment; // this.rotationMatrix = rotationMatrix; // this.featurePointsMap = featurePointsMap; // } // // /** // * Constructor (for more info take a look on // * {@link #ProcrustesTransformation(double, javax.vecmath.Vector3d, org.ejml.simple.SimpleMatrix, cz.fidentis.analyst.procrustes.ProcrustesAnalysisFaceModel) } // * // * @param adjustment // * @param rotationMatrix // */ // public ProcrustesTransformation( // Vector3d centroidAdjustment, // Vector3d superImpositionAdjustment, // SimpleMatrix rotationMatrix, // HashMap<Integer, FeaturePoint> updatedFeaturePointsMap) { // this(1d, centroidAdjustment, superImpositionAdjustment, rotationMatrix, updatedFeaturePointsMap); // } /** * constructor * * @param scale determines by how much should be faced enlarged or minimized * @param centroidAdjustment is vector determining how should be face moved to make (0,0,0) * @param superImpositionAdjustment is vector determining how should be face * moved to be superimposed over primary face * @param rotationMatrix determines how to rotate face */ public ProcrustesTransformation( double scale, Vector3d centroidAdjustment, Vector3d superImpositionAdjustment, SimpleMatrix rotationMatrix) { this.scale = scale; this.centroidAdjustment = centroidAdjustment; this.superImpositionAdjustment = superImpositionAdjustment; this.rotationMatrix = rotationMatrix; } /** * Empty constructor with values that won't transform face. To set values later attribute setters can be used. Loading Loading @@ -104,6 +88,7 @@ public class ProcrustesTransformation { /** * Calculates quaternion from rotation matrix. * * @param matrix * @return quaternion with rotation values */ public Quaternion getMatrixAsQuaternion(SimpleMatrix matrix) { Loading Loading @@ -131,8 +116,13 @@ public class ProcrustesTransformation { this.rotationMatrix = rotationMatrix; } /** * Generates an identity matrix which doesn't cause any transformation and returns it. * * @return identity matrix */ public SimpleMatrix getIdentityMatrix() { SimpleMatrix r = new SimpleMatrix(3, 3); // identity matrix SimpleMatrix r = new SimpleMatrix(3, 3); r.set(0, 0, 1); r.set(0, 1, 0); r.set(0, 2, 0); Loading Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesUtils.java +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ public class ProcrustesUtils { * @param point * @param scaleFactor * @param <T> * @return * @return point with recalculated values */ public static <T extends IPosition> T scalePointDistance(T point, double scaleFactor) { point.getPosition().x = point.getX() * scaleFactor; Loading Comparison/src/main/java/cz/fidentis/analyst/visitors/procrustes/ProcrustesVisitor.java +14 −36 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ import javax.vecmath.Vector3d; import org.ejml.simple.SimpleMatrix; /** * Visitor class for use of Procrustes analysis. * * @author Jakub Kolman */ Loading Loading @@ -48,6 +49,12 @@ public class ProcrustesVisitor extends HumanFaceVisitor { return this.transformations; } /** * Visits secondary face, computes transformation values and readjusts the face * to be superimposed over the primary face. * * @param humanFace */ @Override public void visitHumanFace(HumanFace humanFace) { try { Loading @@ -66,15 +73,14 @@ public class ProcrustesVisitor extends HumanFaceVisitor { /** * Applies transformations computed from procrustes analysis to face. * * @param transformation * @param humanFace * @param transformation computed by procrustes analysis * @param humanFace to which the transformation will be applied to */ private void applyTransformations(ProcrustesTransformation transformation, HumanFace humanFace) { moveFace(humanFace, transformation.getCentroidAdjustment()); scaleFace(humanFace, transformation.getScale()); rotateFace(humanFace, transformation.getRotationMatrix()); moveFace(humanFace, transformation.getSuperImpositionAdjustment()); // moveFeaturePoints(humanFace, transformation.getFeaturePointsMap()); } /** Loading Loading @@ -118,7 +124,7 @@ public class ProcrustesVisitor extends HumanFaceVisitor { * <p> * For more details check out single vertex rotation {@link #rotateVertex}. * * @param vertices * @param humanFace * @param matrix */ private void rotateFace(HumanFace humanFace, SimpleMatrix matrix) { Loading @@ -135,8 +141,8 @@ public class ProcrustesVisitor extends HumanFaceVisitor { /** * Rotates vertex v by simulating matrix multiplication with given matrix * * @param v * @param matrix * @param v is vertex than is going to be rotated * @param matrix is rotation matrix */ private <T extends IPosition> void rotateVertex(T v, SimpleMatrix matrix) { double x = ((v.getX() * matrix.get(0, 0)) Loading @@ -153,32 +159,4 @@ public class ProcrustesVisitor extends HumanFaceVisitor { v.getPosition().z = z; } /** * Moves feature points to calculated new position by computing procrustes * analysis. {@link cz.fidentis.analyst.procrustes.ProcrustesAnalysis}. If * feature point was not used in the analysis, it's position will be kept as * it had in the original list. * * Move of the feature point is done to remove them from user vision first. * * @param secondFace * @param movedFeaturePoints */ /* private static void moveFeaturePoints(HumanFace humanFace, Map<Integer, FeaturePoint> movedFeaturePoints) { humanFace.getFeaturePoints().forEach(fp -> { FeaturePoint movedFp = movedFeaturePoints.get(fp.getFeaturePointType().getType()); if (movedFp != null) { if (fp.getFeaturePointType().getType() != movedFp.getFeaturePointType().getType()) { throw new RuntimeException("Types do not correspond"); } fp.getPosition().x = movedFp.getX(); fp.getPosition().y = movedFp.getY(); fp.getPosition().z = movedFp.getZ(); } }); } */ } Loading
Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java +12 −14 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ public class ProcrustesAnalysis { * Using generalized orthogonal procrustes analysis need to be first moved * over each other, then scale and then rotate. * * @return ProcrustesTransformation computed for secondary face * @throws DataFormatException if faces have less than 3 feature points in * which case analysis doesn't make sense */ Loading Loading @@ -136,19 +137,10 @@ public class ProcrustesAnalysis { }); } /** * Moves face model by given vector values. Different vector value is used * for vertices and feature points. This method is used to fit feature * points to already superimposed position over given face1, but move * vertices of face back to original position of face so all the vertex * movement is done by Procrustes visitor. * * @param faceModel on which adjustment will be applied * @param vertexVector vertex adjustment * @param featurePointVector feature points adjustment */ /** * By rotation of matrices solves orthogonal procrustes problem. * * @return rotation matrix */ private SimpleMatrix rotate() { SimpleMatrix primaryMatrix = createMatrixFromList(this.faceModel2.getFeaturePointValues()); Loading Loading @@ -205,7 +197,7 @@ public class ProcrustesAnalysis { /** * Finds centroid from given feature point List * * @param featurePointList * @param featurePointList list of feature points for which we want to find centroid * @return centroid of feature points (Vector3F) */ private Point3d findCentroidOfFeaturePoints(List<FeaturePoint> featurePointList) { Loading Loading @@ -263,8 +255,8 @@ public class ProcrustesAnalysis { * Finds corresponding subset of feature points from both faces so the * procrustes analysis can be applied on the subset. * * @param featurePoints * @param featurePoints0 * @param featurePoints1 * @param featurePoints2 * * @return List of feature point types that are in both sets of feature * points Loading @@ -284,6 +276,12 @@ public class ProcrustesAnalysis { return vaiablePoints; } /** * scales list by recalculating its points position values * * @param list of points to be scaled * @param scaleFactor factor by how much the points should be scaled */ private void scaleFeaturePoints(List<FeaturePoint> list, double scaleFactor) { for (FeaturePoint point : list) { ProcrustesUtils.scalePointDistance(point, scaleFactor); Loading
Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java +2 −2 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ public class ProcrustesAnalysisFaceModel { * * @param featurePoints * @param viablePoints * @return * @return list containing subset of feature points defined over a face that are marked as a viable points */ private List<FeaturePoint> getSelectionOfFeaturePoints(List<FeaturePoint> featurePoints, List<Integer> viablePoints) { ArrayList<FeaturePoint> selection = new ArrayList<>(); Loading @@ -87,7 +87,7 @@ public class ProcrustesAnalysisFaceModel { * Map key is feature point type (Integer). Value is feature point itself. * * @param featurePointList * @return * @return hash map of feature points */ private HashMap<Integer, FeaturePoint> createFeaturePointMap(List<FeaturePoint> featurePointList) { HashMap<Integer, FeaturePoint> map = new HashMap<>(); Loading
Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesTransformation.java +29 −39 Original line number Diff line number Diff line Loading @@ -19,42 +19,26 @@ public class ProcrustesTransformation { private Vector3d superImpositionAdjustment; private SimpleMatrix rotationMatrix; // /** // * constructor // * // * @param scale determines by how much should be faced enlarged or minimized // * @param adjustment determines how should be face moved to make faces // * superimposed considering feature points // * @param rotationMatrix determines how to rotate face // * @param updatedFaceModel holds information about adjusted face // */ // public ProcrustesTransformation( // double scale, // Vector3d centroidAdjustment, // Vector3d superImpositionAdjustment, // SimpleMatrix rotationMatrix, // HashMap<Integer, FeaturePoint> updatedFeaturePointsMap) { // this.scale = scale; // this.centroidAdjustment = centroidAdjustment; // this.superImpositionAdjustment = superImpositionAdjustment; // this.rotationMatrix = rotationMatrix; // this.featurePointsMap = featurePointsMap; // } // // /** // * Constructor (for more info take a look on // * {@link #ProcrustesTransformation(double, javax.vecmath.Vector3d, org.ejml.simple.SimpleMatrix, cz.fidentis.analyst.procrustes.ProcrustesAnalysisFaceModel) } // * // * @param adjustment // * @param rotationMatrix // */ // public ProcrustesTransformation( // Vector3d centroidAdjustment, // Vector3d superImpositionAdjustment, // SimpleMatrix rotationMatrix, // HashMap<Integer, FeaturePoint> updatedFeaturePointsMap) { // this(1d, centroidAdjustment, superImpositionAdjustment, rotationMatrix, updatedFeaturePointsMap); // } /** * constructor * * @param scale determines by how much should be faced enlarged or minimized * @param centroidAdjustment is vector determining how should be face moved to make (0,0,0) * @param superImpositionAdjustment is vector determining how should be face * moved to be superimposed over primary face * @param rotationMatrix determines how to rotate face */ public ProcrustesTransformation( double scale, Vector3d centroidAdjustment, Vector3d superImpositionAdjustment, SimpleMatrix rotationMatrix) { this.scale = scale; this.centroidAdjustment = centroidAdjustment; this.superImpositionAdjustment = superImpositionAdjustment; this.rotationMatrix = rotationMatrix; } /** * Empty constructor with values that won't transform face. To set values later attribute setters can be used. Loading Loading @@ -104,6 +88,7 @@ public class ProcrustesTransformation { /** * Calculates quaternion from rotation matrix. * * @param matrix * @return quaternion with rotation values */ public Quaternion getMatrixAsQuaternion(SimpleMatrix matrix) { Loading Loading @@ -131,8 +116,13 @@ public class ProcrustesTransformation { this.rotationMatrix = rotationMatrix; } /** * Generates an identity matrix which doesn't cause any transformation and returns it. * * @return identity matrix */ public SimpleMatrix getIdentityMatrix() { SimpleMatrix r = new SimpleMatrix(3, 3); // identity matrix SimpleMatrix r = new SimpleMatrix(3, 3); r.set(0, 0, 1); r.set(0, 1, 0); r.set(0, 2, 0); Loading
Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesUtils.java +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ public class ProcrustesUtils { * @param point * @param scaleFactor * @param <T> * @return * @return point with recalculated values */ public static <T extends IPosition> T scalePointDistance(T point, double scaleFactor) { point.getPosition().x = point.getX() * scaleFactor; Loading
Comparison/src/main/java/cz/fidentis/analyst/visitors/procrustes/ProcrustesVisitor.java +14 −36 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ import javax.vecmath.Vector3d; import org.ejml.simple.SimpleMatrix; /** * Visitor class for use of Procrustes analysis. * * @author Jakub Kolman */ Loading Loading @@ -48,6 +49,12 @@ public class ProcrustesVisitor extends HumanFaceVisitor { return this.transformations; } /** * Visits secondary face, computes transformation values and readjusts the face * to be superimposed over the primary face. * * @param humanFace */ @Override public void visitHumanFace(HumanFace humanFace) { try { Loading @@ -66,15 +73,14 @@ public class ProcrustesVisitor extends HumanFaceVisitor { /** * Applies transformations computed from procrustes analysis to face. * * @param transformation * @param humanFace * @param transformation computed by procrustes analysis * @param humanFace to which the transformation will be applied to */ private void applyTransformations(ProcrustesTransformation transformation, HumanFace humanFace) { moveFace(humanFace, transformation.getCentroidAdjustment()); scaleFace(humanFace, transformation.getScale()); rotateFace(humanFace, transformation.getRotationMatrix()); moveFace(humanFace, transformation.getSuperImpositionAdjustment()); // moveFeaturePoints(humanFace, transformation.getFeaturePointsMap()); } /** Loading Loading @@ -118,7 +124,7 @@ public class ProcrustesVisitor extends HumanFaceVisitor { * <p> * For more details check out single vertex rotation {@link #rotateVertex}. * * @param vertices * @param humanFace * @param matrix */ private void rotateFace(HumanFace humanFace, SimpleMatrix matrix) { Loading @@ -135,8 +141,8 @@ public class ProcrustesVisitor extends HumanFaceVisitor { /** * Rotates vertex v by simulating matrix multiplication with given matrix * * @param v * @param matrix * @param v is vertex than is going to be rotated * @param matrix is rotation matrix */ private <T extends IPosition> void rotateVertex(T v, SimpleMatrix matrix) { double x = ((v.getX() * matrix.get(0, 0)) Loading @@ -153,32 +159,4 @@ public class ProcrustesVisitor extends HumanFaceVisitor { v.getPosition().z = z; } /** * Moves feature points to calculated new position by computing procrustes * analysis. {@link cz.fidentis.analyst.procrustes.ProcrustesAnalysis}. If * feature point was not used in the analysis, it's position will be kept as * it had in the original list. * * Move of the feature point is done to remove them from user vision first. * * @param secondFace * @param movedFeaturePoints */ /* private static void moveFeaturePoints(HumanFace humanFace, Map<Integer, FeaturePoint> movedFeaturePoints) { humanFace.getFeaturePoints().forEach(fp -> { FeaturePoint movedFp = movedFeaturePoints.get(fp.getFeaturePointType().getType()); if (movedFp != null) { if (fp.getFeaturePointType().getType() != movedFp.getFeaturePointType().getType()) { throw new RuntimeException("Types do not correspond"); } fp.getPosition().x = movedFp.getX(); fp.getPosition().y = movedFp.getY(); fp.getPosition().z = movedFp.getZ(); } }); } */ }