diff --git a/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFaceUtils.java b/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFaceUtils.java index 5e30a6e6fe75196f477ce11b22a456c8814fb37f..c11d21f893592da539e4e4beec2c1cc35eb2a63f 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFaceUtils.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFaceUtils.java @@ -3,12 +3,9 @@ package cz.fidentis.analyst.face; import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.icp.IcpTransformer; import cz.fidentis.analyst.icp.Quaternion; -import cz.fidentis.analyst.procrustes.ProcrustesAnalysisFaceModel; import cz.fidentis.analyst.symmetry.Plane; import cz.fidentis.analyst.visitors.mesh.sampling.PointSampling; import cz.fidentis.analyst.visitors.procrustes.ProcrustesVisitor; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -18,7 +15,6 @@ import javax.vecmath.Matrix4d; import javax.vecmath.Point3d; import javax.vecmath.Tuple3d; import javax.vecmath.Vector3d; -import org.ejml.simple.SimpleMatrix; /** * A utility class for operations (visitors) applied onto the whole human faces. @@ -241,7 +237,7 @@ public class HumanFaceUtils { // get transformation values ProcrustesVisitor pv = new ProcrustesVisitor(firstFace, secondFace, scale); - + // superimpose face towards the static face secondFace.getMeshModel().compute(pv, false); @@ -264,24 +260,24 @@ public class HumanFaceUtils { // secondFace.setFeaturePoints( // new ArrayList<>(pv.getTransformation().getFaceModel().getFeaturePointsMap().values())); - } - // transform symmetry plane: - if (secondFace.hasSymmetryPlane()) { - Vector3d adjustment = pv.getTransformation().getCentroidAdjustment(); - double transformationScaleValue = pv.getTransformation().getScale(); - Quaternion rotation = pv.getTransformation().getMatrixAsQuaternion( - pv.getTransformation().getRotationMatrix()); - secondFace.getFeaturePoints().parallelStream().forEach(fp -> { - secondFace.setSymmetryPlane(transformPlane( - secondFace.getSymmetryPlane(), rotation, adjustment, transformationScaleValue)); - }); - secondFace.getFeaturePoints().parallelStream().forEach(fp -> { - secondFace.setSymmetryPlane(transformPlane( - secondFace.getSymmetryPlane(), - pv.getTransformation().getMatrixAsQuaternion(pv.getTransformation().getIdentityMatrix()), - pv.getTransformation().getSuperImpositionAdjustment(), 1)); - }); - } + } + // transform symmetry plane: + if (secondFace.hasSymmetryPlane()) { + Vector3d adjustment = pv.getTransformation().getCentroidAdjustment(); + double transformationScaleValue = pv.getTransformation().getScale(); + Quaternion rotation = pv.getTransformation().getMatrixAsQuaternion( + pv.getTransformation().getRotationMatrix()); + secondFace.getFeaturePoints().parallelStream().forEach(fp -> { + secondFace.setSymmetryPlane(transformPlane( + secondFace.getSymmetryPlane(), rotation, adjustment, transformationScaleValue)); + }); + secondFace.getFeaturePoints().parallelStream().forEach(fp -> { + secondFace.setSymmetryPlane(transformPlane( + secondFace.getSymmetryPlane(), + pv.getTransformation().getMatrixAsQuaternion(pv.getTransformation().getIdentityMatrix()), + pv.getTransformation().getSuperImpositionAdjustment(), 1)); + }); + } return pv; } @@ -367,16 +363,28 @@ public class HumanFaceUtils { return new Plane(retPlane.getNormal(), dist); } + /** + * 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 secondFace, HashMap<Integer, FeaturePoint> movedFeaturePoints) { secondFace.getFeaturePoints().forEach(fp -> { FeaturePoint movedFp = movedFeaturePoints.get(fp.getFeaturePointType().getType()); - 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(); + 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(); + } }); } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java index 779955c63370245595d66b2eb12960fe4ef160d7..947e8542da289d47f54f68ed7129c9f0ff650030 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java @@ -4,7 +4,6 @@ import cz.fidentis.analyst.Logger; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.api.IPosition; -import cz.fidentis.analyst.mesh.core.MeshPoint; import org.ejml.simple.SimpleMatrix; import org.ejml.simple.SimpleSVD; @@ -19,7 +18,6 @@ import javax.swing.JOptionPane; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; -import cz.fidentis.analyst.procrustes.ProcrustesAnalysisFaceModel; import java.util.Comparator; /** @@ -49,11 +47,12 @@ public class ProcrustesAnalysis { ProcrustesAnalysisFaceModel model1; ProcrustesAnalysisFaceModel model2; + // check if feature points lists of both faces have the same size and same types + // if not, than we will be working with subset or cancel the analysis if (humanFace1.getFeaturePoints().size() != humanFace2.getFeaturePoints().size() || !checkFeaturePointsType( sortListByFeaturePointType(humanFace1.getFeaturePoints()), sortListByFeaturePointType(humanFace1.getFeaturePoints()))) { - // int n = 0; Object[] options = {"Yes", "No"}; int n = JOptionPane.showOptionDialog( @@ -70,7 +69,7 @@ public class ProcrustesAnalysis { model1 = new ProcrustesAnalysisFaceModel(humanFace1, viablePoints); model2 = new ProcrustesAnalysisFaceModel(humanFace2, viablePoints); Logger.print("Yes"); - Logger.print(Integer.valueOf(n).toString()); + Logger.print(Integer.toString(n)); } else { JOptionPane.showMessageDialog(new JFrame("Procrustes cancelled"), "Lists of feature points do not have the same size and work on subset was cancelled"); @@ -81,11 +80,12 @@ public class ProcrustesAnalysis { model2 = new ProcrustesAnalysisFaceModel(humanFace2); } + this.modelCentroid1 = findCentroidOfFeaturePoints(model1.getFeaturePointValues()); + this.modelCentroid2 = findCentroidOfFeaturePoints(model2.getFeaturePointValues()); + this.faceModel1 = model1; this.faceModel2 = model2; - this.modelCentroid1 = findCentroidOfFeaturePoints(model1.getFeaturePointValues()); - this.modelCentroid2 = findCentroidOfFeaturePoints(model2.getFeaturePointValues()); } /** @@ -137,15 +137,13 @@ public class ProcrustesAnalysis { // calculation of rotation matrix transformation.setRotationMatrix(this.rotate()); - // move faces back to so the centroid of vertices is in the origin point + // move face vertices back, so the original place, + // but set feture points map to already superimposed position moveFaceModel(faceModel1, new Vector3d(this.modelCentroid1.x, this.modelCentroid1.y, this.modelCentroid1.z)); -// moveFaceModel(faceModel2, new Vector3d(this.modelCentroid2.x, this.modelCentroid2.y, this.modelCentroid2.z)); - moveFaceModel(faceModel2, new Vector3d(this.modelCentroid2.x, this.modelCentroid2.y, this.modelCentroid2.z), new Vector3d(this.modelCentroid1.x, this.modelCentroid1.y, this.modelCentroid1.z)); - // move featurepoints stored in map to superimposed true position -// moveFeaturePoints(faceModel2, new Vector3d(this.modelCentroid1.x, this.modelCentroid1.y, this.modelCentroid1.z)); + transformation.setFaceModel(faceModel2); } else { @@ -154,12 +152,12 @@ public class ProcrustesAnalysis { return transformation; } - private Vector3d getPointDistance(Point3d point1, Point3d point2) { - if (point1 == null || point2 == null) { - return null; - } - return new Vector3d((point2.x - point1.x), (point2.y - point1.y), (point2.z - point1.z)); - } +// private Vector3d getPointDistance(Point3d point1, Point3d point2) { +// if (point1 == null || point2 == null) { +// return null; +// } +// return new Vector3d((point2.x - point1.x), (point2.y - point1.y), (point2.z - point1.z)); +// } /** * Moves all vertices and feature points of a face by given vector value @@ -168,12 +166,12 @@ public class ProcrustesAnalysis { * @param vector vector its values are used to move a face */ private void moveFaceModel(ProcrustesAnalysisFaceModel faceModel, Vector3d vector) { - for (FeaturePoint fp : faceModel.getFeaturePointsMap().values()) { + faceModel.getFeaturePointsMap().values().forEach(fp -> { movePoint(fp, vector); - } - for (MeshPoint v : faceModel.getVertices()) { + }); + faceModel.getVertices().forEach(v -> { movePoint(v, vector); - } + }); } /** @@ -187,16 +185,16 @@ public class ProcrustesAnalysis { * @param featurePointVector feature points adjustment */ private void moveFaceModel(ProcrustesAnalysisFaceModel faceModel, Vector3d vertexVector, Vector3d featurePointVector) { - for (FeaturePoint fp : faceModel.getFeaturePointsMap().values()) { + faceModel.getFeaturePointsMap().values().forEach(fp -> { movePoint(fp, featurePointVector); - } - for (MeshPoint v : faceModel.getVertices()) { + }); + faceModel.getVertices().forEach(v -> { movePoint(v, vertexVector); - } + }); } /** - * Moves point by given vector value + * Moves point by given vector value. * * @param <T> * @param point @@ -209,7 +207,7 @@ public class ProcrustesAnalysis { } /** - * By rotation of matrices solves orthogonal procrustes problem + * By rotation of matrices solves orthogonal procrustes problem. */ private SimpleMatrix rotate() { SimpleMatrix primaryMatrix = createMatrixFromList(this.faceModel2.getFeaturePointValues()); @@ -276,10 +274,10 @@ public class ProcrustesAnalysis { * @param faceModel * @param scaleFactor */ - private void scaleFace(ProcrustesAnalysisFaceModel faceModel, double scaleFactor) { - calculateScaledList(faceModel.getVertices(), scaleFactor); - calculateScaledList(faceModel.getFeaturePointValues(), scaleFactor); - } +// private void scaleFace(ProcrustesAnalysisFaceModel faceModel, double scaleFactor) { +// calculateScaledList(faceModel.getVertices(), scaleFactor); +// calculateScaledList(faceModel.getFeaturePointValues(), scaleFactor); +// } /** * Scales each given point from list by multiplying its position coordinates @@ -306,13 +304,13 @@ public class ProcrustesAnalysis { */ // if rotated vertices are drawn immediately it is better to set them after rotating them all // so it would be drawn just once - private void rotateVertices(List<MeshPoint> vertices, SimpleMatrix matrix) { - if (vertices != null) { - for (int i = 0; i < vertices.size(); i++) { - rotateVertex(vertices.get(i), matrix); - } - } - } +// private void rotateVertices(List<MeshPoint> vertices, SimpleMatrix matrix) { +// if (vertices != null) { +// for (int i = 0; i < vertices.size(); i++) { +// rotateVertex(vertices.get(i), matrix); +// } +// } +// } /** * Rotates vertex v by simulating matrix multiplication with given matrix @@ -320,20 +318,20 @@ public class ProcrustesAnalysis { * @param v * @param matrix */ - private static void rotateVertex(MeshPoint v, SimpleMatrix matrix) { - double x = ((v.getX() * matrix.get(0, 0)) - + (v.getY() * matrix.get(1, 0)) - + (v.getZ() * matrix.get(2, 0))); - double y = ((v.getX() * matrix.get(0, 1)) - + (v.getY() * matrix.get(1, 1)) - + (v.getZ() * matrix.get(2, 1))); - double z = ((v.getX() * matrix.get(0, 2)) - + (v.getY() * matrix.get(1, 2)) - + (v.getZ() * matrix.get(2, 2))); - v.getPosition().x = x; - v.getPosition().y = y; - v.getPosition().z = z; - } +// private static void rotateVertex(MeshPoint v, SimpleMatrix matrix) { +// double x = ((v.getX() * matrix.get(0, 0)) +// + (v.getY() * matrix.get(1, 0)) +// + (v.getZ() * matrix.get(2, 0))); +// double y = ((v.getX() * matrix.get(0, 1)) +// + (v.getY() * matrix.get(1, 1)) +// + (v.getZ() * matrix.get(2, 1))); +// double z = ((v.getX() * matrix.get(0, 2)) +// + (v.getY() * matrix.get(1, 2)) +// + (v.getZ() * matrix.get(2, 2))); +// v.getPosition().x = x; +// v.getPosition().y = y; +// v.getPosition().z = z; +// } /** * Scales position of given point by multiplying its coordinates with given diff --git a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java index 74f90f3949ced5660cd5f2ba50db0a0b9c5a54c8..856af56888aa4ca4a16561704d3abfc2c6f1ec53 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java @@ -20,7 +20,7 @@ public class ProcrustesAnalysisFaceModel { private final HumanFace humanFace; private HashMap<Integer, FeaturePoint> featurePointsMap; // sorted by feature point type private List<MeshPoint> vertices; - private MeshModel meshModel; + private final MeshModel meshModel; private final HashMap<Integer, Integer> featurePointTypeCorrespondence; /** @@ -57,7 +57,7 @@ public class ProcrustesAnalysisFaceModel { List<FeaturePoint> modifiableFeaturePointList = getSelectionOfFeaturePoints(face.getFeaturePoints(), viablePoints); // Currently set feature points is not working as inteded because gui doesn't repaint them after changing values - face.setFeaturePoints(modifiableFeaturePointList); +// face.setFeaturePoints(modifiableFeaturePointList); // To be able to move vertices we have to make a copy of them because getFacets() returns unmodifiable List List<MeshPoint> modifiableVertices = new ArrayList<>(face.getMeshModel().getFacets().get(0).getVertices()); @@ -70,15 +70,43 @@ public class ProcrustesAnalysisFaceModel { } /** - * sets feature points map and also sets feature point on human face for - * visualisation + * Use this constructor instead of the + * {@link #ProcrustesAnalysisFaceModel(cz.fidentis.analyst.face.HumanFace, java.util.List)} + * until the + * {@link cz.fidentis.analyst.face.HumanFace#setFeaturePoints(java.util.List)} + * is fixed and fires event to render in GUI a new set of feature points. + * + * Feature points that are not used in subset are moved to position of + * modelCentroid. + * + * @param humanFace1 + * @param viablePoints + * @param modelCentroid1 + */ +// ProcrustesAnalysisFaceModel(HumanFace face, ArrayList<Integer> viablePoints, Point3d modelCentroid) { +// this.humanFace = face; +// // getFeaturePoints() returns unmodifiable List. To sort it we need to make copy first +// List<FeaturePoint> modifiableFeaturePointList = getSelectionOfFeaturePoints(face.getFeaturePoints(), viablePoints); +// +// // To be able to move vertices we have to make a copy of them because getFacets() returns unmodifiable List +// List<MeshPoint> modifiableVertices = new ArrayList<>(face.getMeshModel().getFacets().get(0).getVertices()); +// +// this.vertices = modifiableVertices; +// this.meshModel = face.getMeshModel(); +// this.featurePointsMap = createFeaturePointMap( +// sortListByFeaturePointType(modifiableFeaturePointList)); +// this.featurePointTypeCorrespondence = createFeaturePointTypeCorrespondence(face.getFeaturePoints()); +// } + + /** + * Sets feature points map and also sets feature point on human face for + * visualisation. * * @param featurePointsMap */ public void setFeaturePointsMap(HashMap<Integer, FeaturePoint> featurePointsMap) { this.featurePointsMap = featurePointsMap; readjustFeaturePoints(featurePointsMap); - // this.humanFace.setFeaturePoints(getFeaturePointValues()); } @@ -106,6 +134,15 @@ public class ProcrustesAnalysisFaceModel { return featurePointTypeCorrespondence; } + /** + * Creates a subset of selected feature points that can be used for + * procrustes analysis. Each of the feature point types contained in the + * subset is contained in both faces. + * + * @param featurePoints + * @param viablePoints + * @return + */ private List<FeaturePoint> getSelectionOfFeaturePoints(List<FeaturePoint> featurePoints, List<Integer> viablePoints) { ArrayList<FeaturePoint> selection = new ArrayList<>(); featurePoints.forEach(fp -> { @@ -116,6 +153,30 @@ public class ProcrustesAnalysisFaceModel { return selection; } + /** + * {@link #getSelectionOfFeaturePoints(java.util.List, java.util.List)} + * Feature points that are not in subset are moved to position of + * modelCentroid. + * + * @param featurePoints + * @param viablePoints + * @param modelCentroid + * @return + */ +// private List<FeaturePoint> getSelectionOfFeaturePoints(List<FeaturePoint> featurePoints, ArrayList<Integer> viablePoints, Point3d modelCentroid) { +// ArrayList<FeaturePoint> selection = new ArrayList<>(); +// featurePoints.forEach(fp -> { +// if (viablePoints.contains(fp.getFeaturePointType().getType())) { +// selection.add(fp); +// } else { +// fp.getPosition().x = modelCentroid.x; +// fp.getPosition().y = modelCentroid.y; +// fp.getPosition().z = modelCentroid.z; +// } +// }); +// return selection; +// } + /** * Creates corresponding key value pair of matrix row index and a feature * point type value. It is used so we can get back type of feature point @@ -163,28 +224,9 @@ public class ProcrustesAnalysisFaceModel { } private void readjustFeaturePoints(HashMap<Integer, FeaturePoint> featurePointsMap) { - if (featurePointsMap.size() != this.humanFace.getFeaturePoints().size()) { - readjustSelection(featurePointsMap); - } else { - this.humanFace.getFeaturePoints().forEach(fp -> { - FeaturePoint movedFp = featurePointsMap.get(fp.getFeaturePointType().getType()); - 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(); - }); - } - } - - /** - * Moves subset of feature points to their new position. If point doesn't belong to subset it is moved to (0,0,0) instead. - * - * @param featurePointsMap - */ - private void readjustSelection(HashMap<Integer, FeaturePoint> featurePointsMap) { +// if (featurePointsMap.size() != this.humanFace.getFeaturePoints().size()) { +// readjustSelection(featurePointsMap); +// } else { this.humanFace.getFeaturePoints().forEach(fp -> { FeaturePoint movedFp = featurePointsMap.get(fp.getFeaturePointType().getType()); if (movedFp != null) { @@ -195,12 +237,34 @@ public class ProcrustesAnalysisFaceModel { fp.getPosition().x = movedFp.getX(); fp.getPosition().y = movedFp.getY(); fp.getPosition().z = movedFp.getZ(); - } else { - fp.getPosition().x = 0; - fp.getPosition().y = 0; - fp.getPosition().z = 0; } }); +// } } +// /** +// * Moves subset of feature points to their new position. If point doesn't +// * belong to subset it is moved to (0,0,0) instead. +// * +// * @param featurePointsMap +// */ +// private void readjustSelection(HashMap<Integer, FeaturePoint> featurePointsMap) { +// this.humanFace.getFeaturePoints().forEach(fp -> { +// FeaturePoint movedFp = featurePointsMap.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(); +// } else { +// fp.getPosition().x = 0; +// fp.getPosition().y = 0; +// fp.getPosition().z = 0; +// } +// }); +// } + } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesTransformation.java b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesTransformation.java index 10a123bd9f4ce913e0ff27e1607c73f7fb7cfade..d496e061b919dd97b6e59c381ea1ecdf34eaca44 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesTransformation.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesTransformation.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package cz.fidentis.analyst.procrustes; import cz.fidentis.analyst.icp.Quaternion; @@ -11,7 +6,7 @@ import org.ejml.simple.SimpleMatrix; /** * Class used to store information about transformation that needs to be applied - * to a second face when computing procrustes analysis + * to a second face when computing procrustes analysis. * * @author Jakub Kolman */ diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/procrustes/ProcrustesVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/procrustes/ProcrustesVisitor.java index edf67f47a98f56489865deb0ee77bf3a95491673..207feedefbc6a0ba405057ddd472fa048097c643 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/procrustes/ProcrustesVisitor.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/procrustes/ProcrustesVisitor.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package cz.fidentis.analyst.visitors.procrustes; import cz.fidentis.analyst.face.HumanFace; diff --git a/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModelTest.java b/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModelTest.java index 3804d4d11799e5823f72aeba82a56fe8b0ffce88..485a8666bd079fd9aacd9f0a8e0ac23f6e118c10 100644 --- a/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModelTest.java +++ b/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModelTest.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package cz.fidentis.analyst.procrustes; import cz.fidentis.analyst.face.HumanFace; @@ -20,8 +15,13 @@ import cz.fidentis.analyst.feature.utils.FileResourcesUtils; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import cz.fidentis.analyst.feature.services.FeaturePointCsvLoader; +import cz.fidentis.analyst.feature.services.FeaturePointImportService; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.zip.DataFormatException; +import org.junit.jupiter.api.Assertions; /** * @@ -36,7 +36,14 @@ public class ProcrustesAnalysisFaceModelTest { "src", "test", "resources", "cz", "fidentis", "analyst"); private static final String SORTED_FILE = "landmarksSorted.csv"; private static final String NOT_SORTED_FILE = "landmarksNotSorted.csv"; + private static final String FP_HEAD_01 = "0002_01_landmarks.csv"; + private static final String FP_HEAD_01_SUBSET = "0002_01_subset_landmarks.csv"; + private static final String HEAD_01 = "0002_01_ECA.obj"; + /** + * Test for sorting feature points list by their type. + * @throws IOException + */ @DisplayName("Test sorting utility sortByFeaturePointType") @Test void sortByTypeTest() throws IOException { @@ -47,7 +54,7 @@ public class ProcrustesAnalysisFaceModelTest { HumanFace face = factory.getFace(faceId); List<FeaturePoint> featurePointsSortedList = FeaturePointCsvLoader.loadFeaturePoints( TEST_FILE_DIRECTORY.toString(), SORTED_FILE); - List<FeaturePoint> featurePointsNotSortedList = FeaturePointCsvLoader.loadFeaturePoints( + List<FeaturePoint> featurePointsNotSortedList = FeaturePointCsvLoader.loadFeaturePoints( TEST_FILE_DIRECTORY.toString(), NOT_SORTED_FILE); face.setFeaturePoints(featurePointsNotSortedList); ProcrustesAnalysisFaceModel faceModel = new ProcrustesAnalysisFaceModel(face); @@ -59,5 +66,55 @@ public class ProcrustesAnalysisFaceModelTest { assertTrue(featurePointsSortedList.equals(sortedListByType)); } + /** + * Test for creating model with subset of feature points. + * + * @throws DataFormatException + * @throws IOException + */ + @Test + void subsetOfFpanalysis() throws DataFormatException, IOException { + FileResourcesUtils fru = new FileResourcesUtils(); + HumanFaceFactory factory = new HumanFaceFactory(); + FeaturePointImportService featurePointImportService = new FeaturePointImportService(); + + List<FeaturePoint> fpSubsetList = featurePointImportService.importFeaturePoints( + TEST_FILE_DIRECTORY.toString(), FP_HEAD_01_SUBSET); + List<FeaturePoint> fpList = featurePointImportService.importFeaturePoints( + TEST_FILE_DIRECTORY.toString(), FP_HEAD_01); + + HumanFace face = factory.getFace(factory.loadFace( + fru.getFile(TEST_FILE_DIRECTORY.toString(), HEAD_01))); + + face.setFeaturePoints(fpSubsetList); + + ProcrustesAnalysisFaceModel faceModel = new ProcrustesAnalysisFaceModel(face, getSubsetOfFeaturePoints(fpList, fpSubsetList)); + + Assertions.assertEquals(8, faceModel.getFeaturePointValues().size()); + Assertions.assertEquals(8, faceModel.getFeaturePointsMap().size()); + Assertions.assertEquals(8, faceModel.getFeaturePointTypeCorrespondence().size()); + } + + /** + * Method to create a subset from list of feature points. + * + * @param featurePoints1 + * @param featurePoints2 + * @return + */ + private ArrayList<Integer> getSubsetOfFeaturePoints(List<FeaturePoint> featurePoints1, List<FeaturePoint> featurePoints2) { + HashMap<Integer, FeaturePoint> fpMap = new HashMap<>(); + for (FeaturePoint fp : featurePoints1) { + fpMap.put(fp.getFeaturePointType().getType(), fp); + } + + ArrayList<Integer> vaiablePoints = new ArrayList<>(); + featurePoints2.forEach(fp -> { + if (fpMap.get(fp.getFeaturePointType().getType()) != null) { + vaiablePoints.add(Integer.valueOf(fp.getFeaturePointType().getType())); + } + }); + return vaiablePoints; + } } diff --git a/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisTest.java b/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisTest.java index 9d89587782a616d5b7c4e9d4f9a8a8880f577cc7..e4752655006d16e0ad770c7d0f865879d76a8037 100644 --- a/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisTest.java +++ b/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisTest.java @@ -5,8 +5,6 @@ import cz.fidentis.analyst.face.HumanFaceFactory; import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.services.FeaturePointImportService; import cz.fidentis.analyst.feature.utils.FileResourcesUtils; -import cz.fidentis.analyst.mesh.core.MeshPoint; -import cz.fidentis.analyst.visitors.procrustes.ProcrustesVisitor; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -25,6 +23,7 @@ public class ProcrustesAnalysisTest { "src", "test", "resources", "cz", "fidentis", "analyst", "comparison", "procrustesAnalysis"); private static final String FP_HEAD_01 = "0002_01_landmarks.csv"; + private static final String FP_HEAD_01_SUBSET = "0002_01_subset_landmarks.csv"; private static final String FP_HEAD_02 = "0002_02_landmarks.csv"; private static final String FP_TWOS = "twos_landmarks.csv"; private static final String FP_FOURS = "fours_landmarks.csv"; @@ -36,7 +35,7 @@ public class ProcrustesAnalysisTest { private static final String HEAD_02 = "0002_02_ECA.obj"; private static final String HEAD_03 = "x0002_01_ECA.obj"; -// @Test + @Test void procrustesAnalysisSuperImposeTest() throws URISyntaxException, DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); @@ -74,7 +73,7 @@ public class ProcrustesAnalysisTest { * @throws DataFormatException * @throws IOException */ - //@Test + @Test void calculateScalingValueTest1() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); @@ -114,7 +113,7 @@ public class ProcrustesAnalysisTest { * @throws DataFormatException * @throws IOException */ -// @Test + @Test void calculateScalingValueTest2() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); @@ -153,7 +152,7 @@ public class ProcrustesAnalysisTest { * @throws DataFormatException * @throws IOException */ -// @Test + @Test void calculateRotationTest() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); @@ -173,18 +172,19 @@ public class ProcrustesAnalysisTest { face2.setFeaturePoints(fpListRotated); ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2, true); SimpleMatrix matrix = pa.analyze().getRotationMatrix(); + + // Math.round() function is used, because the numbers are very close to the value, but never preciesly + Assertions.assertEquals(-1, Math.round(matrix.get(0, 0))); + Assertions.assertEquals(0, Math.round(matrix.get(0, 1))); + Assertions.assertEquals(0, Math.round(matrix.get(0, 2))); - Assertions.assertEquals(-1, matrix.get(0, 0)); - Assertions.assertEquals(0, matrix.get(0, 1)); - Assertions.assertEquals(0, matrix.get(0, 2)); + Assertions.assertEquals(0, Math.round(matrix.get(1, 0))); + Assertions.assertEquals(-1, Math.round(matrix.get(1, 1))); + Assertions.assertEquals(0, Math.round(matrix.get(1, 2))); - Assertions.assertEquals(0, matrix.get(1, 0)); - Assertions.assertEquals(1, matrix.get(1, 1)); - Assertions.assertEquals(0, matrix.get(1, 2)); - - Assertions.assertEquals(0, matrix.get(2, 0)); - Assertions.assertEquals(0, matrix.get(2, 1)); - Assertions.assertEquals(1, matrix.get(2, 2)); + Assertions.assertEquals(0, Math.round(matrix.get(2, 0))); + Assertions.assertEquals(0, Math.round(matrix.get(2, 1))); + Assertions.assertEquals(1, Math.round(matrix.get(2, 2))); } @@ -194,7 +194,7 @@ public class ProcrustesAnalysisTest { * @throws DataFormatException * @throws IOException */ - //@Test + @Test void calculateAdjustmentTest3() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); @@ -213,11 +213,15 @@ public class ProcrustesAnalysisTest { face1.setFeaturePoints(fpListTwos); face2.setFeaturePoints(fpListFoursMoved); - ProcrustesAnalysis pa1 = new ProcrustesAnalysis(face1, face2, true); -// Assertions.assertEquals(-4, pa1.analyze().getPreAdjustment().x); -// Assertions.assertEquals(0, pa1.analyze().getPreAdjustment().y); -// Assertions.assertEquals(0, pa1.analyze().getPreAdjustment().z); - + ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2, true); + ProcrustesTransformation transformation = pa.analyze(); + Assertions.assertEquals(4, transformation.getCentroidAdjustment().x, 0); + Assertions.assertEquals(0, transformation.getCentroidAdjustment().y, 0); + Assertions.assertEquals(0, transformation.getCentroidAdjustment().z, 0); + + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().x); + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().y); + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().z); } /** @@ -226,7 +230,7 @@ public class ProcrustesAnalysisTest { * @throws DataFormatException * @throws IOException */ - //@Test + @Test void calculateAdjustmentTest2() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); @@ -245,11 +249,16 @@ public class ProcrustesAnalysisTest { face1.setFeaturePoints(fpListFours); face2.setFeaturePoints(fpListFoursMoved); - ProcrustesAnalysis pa2 = new ProcrustesAnalysis(face1, face2, true); -// Assertions.assertEquals(-4, pa2.analyze().getPreAdjustment().x); -// Assertions.assertEquals(0, pa2.analyze().getPreAdjustment().y); -// Assertions.assertEquals(0, pa2.analyze().getPreAdjustment().z); - + ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2, true); + ProcrustesTransformation transformation = pa.analyze(); + + Assertions.assertEquals(4, transformation.getCentroidAdjustment().x, 0); + Assertions.assertEquals(0, transformation.getCentroidAdjustment().y, 0); + Assertions.assertEquals(0, transformation.getCentroidAdjustment().z, 0); + + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().x); + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().y); + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().z); } /** @@ -258,7 +267,7 @@ public class ProcrustesAnalysisTest { * @throws DataFormatException * @throws IOException */ - //@Test + @Test void calculateAdjustmentTest1() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); @@ -277,59 +286,97 @@ public class ProcrustesAnalysisTest { face1.setFeaturePoints(fpListTwos); face2.setFeaturePoints(fpListFours); - ProcrustesAnalysis pa1 = new ProcrustesAnalysis(face1, face2, true); -// Assertions.assertEquals(0, pa1.analyze().getPreAdjustment().x); -// Assertions.assertEquals(0, pa1.analyze().getPreAdjustment().y); -// Assertions.assertEquals(0, pa1.analyze().getPreAdjustment().z); + ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2, true); + ProcrustesTransformation transformation = pa.analyze(); + + Assertions.assertEquals(0, transformation.getCentroidAdjustment().x, 0); + Assertions.assertEquals(0, transformation.getCentroidAdjustment().y, 0); + Assertions.assertEquals(0, transformation.getCentroidAdjustment().z, 0); + + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().x); + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().y); + Assertions.assertEquals(0, transformation.getSuperImpositionAdjustment().z); } + + /** + * Test for calculating adjustment of superimposition runs with the same set of featurepoints + * + * @throws DataFormatException + * @throws IOException + */ + @Test + void calculateAdjustmentTest4() throws DataFormatException, IOException { + FileResourcesUtils fru = new FileResourcesUtils(); + HumanFaceFactory factory = new HumanFaceFactory(); + FeaturePointImportService featurePointImportService = new FeaturePointImportService(); + + List<FeaturePoint> fpListTwos = featurePointImportService.importFeaturePoints( + TEST_FILE_DIRECTORY.toString(), FP_HEAD_01); + List<FeaturePoint> fpListFours = featurePointImportService.importFeaturePoints( + TEST_FILE_DIRECTORY.toString(), FP_HEAD_01); + + HumanFace face1 = factory.getFace(factory.loadFace( + fru.getFile(TEST_FILE_DIRECTORY.toString(), HEAD_01))); + HumanFace face2 = factory.getFace(factory.loadFace( + fru.getFile(TEST_FILE_DIRECTORY.toString(), HEAD_02))); -// @Test - void procrustesAnalysisAnalyseTest() throws DataFormatException, IOException { + face1.setFeaturePoints(fpListTwos); + face2.setFeaturePoints(fpListFours); + + ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2, true); + ProcrustesTransformation transformation = pa.analyze(); + + transformation.getCentroidAdjustment(); + transformation.getSuperImpositionAdjustment(); + + Assertions.assertEquals(0.7689281702041626, transformation.getCentroidAdjustment().x, 0); + Assertions.assertEquals(-14.009615898132324, transformation.getCentroidAdjustment().y, 0); + Assertions.assertEquals(59.499977111816406, transformation.getCentroidAdjustment().z, 0); + + Assertions.assertEquals(-0.7689281702041626, transformation.getSuperImpositionAdjustment().x); + Assertions.assertEquals(14.009615898132324, transformation.getSuperImpositionAdjustment().y); + Assertions.assertEquals(-59.499977111816406, transformation.getSuperImpositionAdjustment().z); + } + + /** + * Test for calculating adjustment of superimposition + * + * @throws DataFormatException + * @throws IOException + */ + @Test + void calculateAdjustmentTest5() throws DataFormatException, IOException { FileResourcesUtils fru = new FileResourcesUtils(); HumanFaceFactory factory = new HumanFaceFactory(); FeaturePointImportService featurePointImportService = new FeaturePointImportService(); - List<FeaturePoint> fpList01 = featurePointImportService.importFeaturePoints( + List<FeaturePoint> fpListTwos = featurePointImportService.importFeaturePoints( TEST_FILE_DIRECTORY.toString(), FP_HEAD_01); - List<FeaturePoint> fpList02 = featurePointImportService.importFeaturePoints( + List<FeaturePoint> fpListFours = featurePointImportService.importFeaturePoints( TEST_FILE_DIRECTORY.toString(), FP_HEAD_02); + HumanFace face1 = factory.getFace(factory.loadFace( fru.getFile(TEST_FILE_DIRECTORY.toString(), HEAD_01))); HumanFace face2 = factory.getFace(factory.loadFace( fru.getFile(TEST_FILE_DIRECTORY.toString(), HEAD_02))); - face1.setFeaturePoints(fpList01); - face2.setFeaturePoints(fpList02); - - ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2); + face1.setFeaturePoints(fpListTwos); + face2.setFeaturePoints(fpListFours); - ProcrustesVisitor visitor = new ProcrustesVisitor(face1, face2, false); - -// ProcrustesTransformation transformation = pa.analyze(); - face2.getMeshModel().compute(visitor); - - MeshPoint v0 = face2.getMeshModel().getFacets().get(0).getVertices().get(0); - MeshPoint v5 = face2.getMeshModel().getFacets().get(0).getVertices().get(5); - Point3d expectedV0 = new Point3d(3.5674604453564664, -5.024528152075607, 112.59416675280146); - Point3d expectedV5 = new Point3d(4.08419737898887, -3.5408847908259893, 111.87431099579298); - /* - Assertions.assertEquals(expectedV0.x, v0.getX()); - Assertions.assertEquals(expectedV0.y, v0.getY()); - Assertions.assertEquals(expectedV0.z, v0.getZ()); - Assertions.assertEquals(expectedV5.x, v5.getX()); - Assertions.assertEquals(expectedV5.y, v5.getY()); - Assertions.assertEquals(expectedV5.z, v5.getZ()); - */ - - FeaturePoint fp0 = face2.getFeaturePoints().get(0); - Point3d expectedFp0 = new Point3d(-42.71984496683351, 27.159522893612994, 27.40995332843569); - FeaturePoint fp5 = face2.getFeaturePoints().get(5); - Point3d expectedFp5 = new Point3d(35.88895800465637, 30.10663264467767, 34.788164810540685); - Assertions.assertEquals(expectedFp0.x, fp0.getX()); - Assertions.assertEquals(expectedFp0.y, fp0.getY()); - Assertions.assertEquals(expectedFp0.z, fp0.getZ()); - Assertions.assertEquals(expectedFp5.x, fp5.getX()); - Assertions.assertEquals(expectedFp5.y, fp5.getY()); - Assertions.assertEquals(expectedFp5.z, fp5.getZ()); + ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2, true); + ProcrustesTransformation transformation = pa.analyze(); + + transformation.getCentroidAdjustment(); + transformation.getSuperImpositionAdjustment(); + + Assertions.assertEquals(0.040306758135557175, transformation.getCentroidAdjustment().x, 0); + Assertions.assertEquals(-16.00124168395996, transformation.getCentroidAdjustment().y, 0); + Assertions.assertEquals(59.67900848388672, transformation.getCentroidAdjustment().z, 0); + + Assertions.assertEquals(-0.7689281702041626, transformation.getSuperImpositionAdjustment().x); + Assertions.assertEquals(14.009615898132324, transformation.getSuperImpositionAdjustment().y); + Assertions.assertEquals(-59.499977111816406, transformation.getSuperImpositionAdjustment().z); } + + } diff --git a/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesVisitorTest.java b/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesVisitorDebug.java similarity index 91% rename from Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesVisitorTest.java rename to Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesVisitorDebug.java index 16c4d47b8ca8f0270428eb984be4c3b3a1df5798..4526a32c02b4bab510960ca5a287ca01c50e4e25 100644 --- a/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesVisitorTest.java +++ b/Comparison/src/test/java/cz/fidentis/analyst/procrustes/ProcrustesVisitorDebug.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package cz.fidentis.analyst.procrustes; import cz.fidentis.analyst.face.HumanFace; @@ -18,11 +13,11 @@ import cz.fidentis.analyst.feature.services.FeaturePointImportService; import cz.fidentis.analyst.visitors.procrustes.ProcrustesVisitor; /** - * Class used for debugging + * Class used for debugging procrustes analysis. * * @author Jakub Kolman */ -public class ProcrustesVisitorTest { +public class ProcrustesVisitorDebug { private static final Path TEST_FILE_DIRECTORY = Paths.get( "src", "test", "resources", "cz", "fidentis", "analyst", "comparison", "procrustesAnalysis"); diff --git a/Comparison/src/test/resources/cz/fidentis/analyst/comparison/procrustesAnalysis/0002_01_subset_landmarks.csv b/Comparison/src/test/resources/cz/fidentis/analyst/comparison/procrustesAnalysis/0002_01_subset_landmarks.csv new file mode 100644 index 0000000000000000000000000000000000000000..04261c50bbc892c230c5862c2f39c4fc8faf08cb --- /dev/null +++ b/Comparison/src/test/resources/cz/fidentis/analyst/comparison/procrustesAnalysis/0002_01_subset_landmarks.csv @@ -0,0 +1,2 @@ +Scan name,EX_R x,EX_R y,EX_R z,EX_L x,EX_L y,EX_L z,EN_R x,EN_R y,EN_R z,EN_L x,EN_L y,EN_L z,PAS_R x,PAS_R y,PAS_R z,PAS_L x,PAS_L y,PAS_L z,PAI_R x,PAI_R y,PAI_R z,PAI_L x,PAI_L y,PAI_L z +0002_01,-45.0771,38.9071,-34.9649,42.2754,41.6506,-32.1348,-16.9673,37.9997,-30.5843,15.5735,38.2922,-29.2261,-33.1579,42.8983,-25.3859,32.9923,44.5606,-24.9729,-33.1423,33.5105,-28.822,32.6133,34.5931,-27.8028 diff --git a/GUI/src/main/java/cz/fidentis/analyst/tests/ProcrustesVisitorTest.java b/GUI/src/main/java/cz/fidentis/analyst/tests/ProcrustesVisitorTest.java deleted file mode 100644 index 2c4777b736600e784802a74466319e99306d5d3c..0000000000000000000000000000000000000000 --- a/GUI/src/main/java/cz/fidentis/analyst/tests/ProcrustesVisitorTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package cz.fidentis.analyst.tests; - -import cz.fidentis.analyst.batch.Stopwatch; -import cz.fidentis.analyst.face.HumanFace; -import cz.fidentis.analyst.face.HumanFaceFactory; -import cz.fidentis.analyst.face.HumanFaceUtils; -import cz.fidentis.analyst.feature.FeaturePoint; -import cz.fidentis.analyst.feature.services.FeaturePointImportService; -import cz.fidentis.analyst.feature.utils.FileResourcesUtils; -import cz.fidentis.analyst.visitors.mesh.HausdorffDistance; -import cz.fidentis.analyst.visitors.mesh.sampling.CurvatureSampling; -import cz.fidentis.analyst.visitors.mesh.sampling.NoSampling; -import cz.fidentis.analyst.visitors.mesh.sampling.PointSampling; -import cz.fidentis.analyst.visitors.mesh.sampling.RandomSampling; -import cz.fidentis.analyst.visitors.mesh.sampling.UniformSpaceSampling; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.stream.Collectors; - -/** - * - * @author Jakub Kolman - */ -public class ProcrustesVisitorTest { - private static final String DATA_DIR = "./src/test/resources/cz/fidentis/analyst"; - private static final int MAX_SAMPLES = 100; - private static final String FACE_1 = "0002_01_ECA.obj"; - private static final String FACE_2 = "0002_02_ECA.obj"; - private static final String FACE_FP_1 = "0002_01_landmarks.csv"; - private static final String FACE_FP_2 = "0002_02_landmarks.csv"; - private static final String FACE_FP_ROTATION_1 = "rotation_landmarks.csv"; - private static final String FACE_FP_ROTATION_2 = "rotation_180_moved_2_landmarks.csv"; - private static final String FACE_FP_TWOS = "twos_landmarks.csv"; - private static final String FACE_FP_FOURS = "fours_landmarks.csv"; - - /** - * Main method - * @param args Input arguments - * @throws IOException on IO error - */ - public static void main(String[] args) throws IOException, ClassNotFoundException, Exception { - FileResourcesUtils fru = new FileResourcesUtils(); - HumanFaceFactory factory = new HumanFaceFactory(); - FeaturePointImportService featurePointImportService = new FeaturePointImportService(); - - List<FeaturePoint> fpList1 = featurePointImportService.importFeaturePoints( - DATA_DIR.toString(), FACE_FP_ROTATION_1); - List<FeaturePoint> fpList2= featurePointImportService.importFeaturePoints( - DATA_DIR.toString(), FACE_FP_ROTATION_2); - - - HumanFace face1 = factory.getFace(factory.loadFace( - fru.getFile(DATA_DIR.toString(), FACE_1))); - HumanFace face2 = factory.getFace(factory.loadFace( - fru.getFile(DATA_DIR.toString(), FACE_2))); - - face1.setFeaturePoints(fpList1); - face2.setFeaturePoints(fpList2); - - tryProcrustesVisitor(face1, face2); - } - - protected static void tryProcrustesVisitor(HumanFace face1, HumanFace face2) { - HumanFaceUtils.alignFeaturePoints(face1, face2, true, false); -// HumanFaceUtils.alignFeaturePoints(face1, face2, true, false); - } - - -} - -