Skip to content
Snippets Groups Projects
Commit cda9762b authored by Jakub Kolman's avatar Jakub Kolman
Browse files

[#38] refactor: adding documantation and deleting dead code

parent 447b13c8
No related branches found
No related tags found
No related merge requests found
...@@ -27,9 +27,6 @@ public class ProcrustesAnalysis { ...@@ -27,9 +27,6 @@ public class ProcrustesAnalysis {
private Point3d modelCentroid1; private Point3d modelCentroid1;
private Point3d modelCentroid2; private Point3d modelCentroid2;
// based on some example models this is an approximate centroid of feature points
// private Point3d centroid = new Point3d(0, 0, 0);
/** /**
* Constructor * Constructor
* *
...@@ -48,12 +45,8 @@ public class ProcrustesAnalysis { ...@@ -48,12 +45,8 @@ public class ProcrustesAnalysis {
throw new ProcrustesAnalysisException("Lists of feature points do not have the same size"); throw new ProcrustesAnalysisException("Lists of feature points do not have the same size");
} }
// this.orderedFeaturePointList1 = new ArrayList<>(model1.getFeaturePointsMap().values()); if (!ProcrustesAnalysisUtils.checkFeaturePointsType(
// this.orderedFeaturePointList2 = new ArrayList<>(model2.getFeaturePointsMap().values()); model1.getFeaturePointValues(), model2.getFeaturePointValues())) {
if (!featurePointTypesEquivalence(
model1.getFeaturePointValues(),
model2.getFeaturePointValues())) {
throw new ProcrustesAnalysisException("Lists of feature points do not have the same feature point types"); throw new ProcrustesAnalysisException("Lists of feature points do not have the same feature point types");
} }
...@@ -62,85 +55,42 @@ public class ProcrustesAnalysis { ...@@ -62,85 +55,42 @@ public class ProcrustesAnalysis {
this.modelCentroid1 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model1.getFeaturePointValues()); this.modelCentroid1 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model1.getFeaturePointValues());
this.modelCentroid2 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model2.getFeaturePointValues()); this.modelCentroid2 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model2.getFeaturePointValues());
}
public ProcrustesAnalysisFaceModel getFaceModel1() {
return faceModel1;
}
public ProcrustesAnalysisFaceModel getFaceModel2() {
return faceModel2;
} }
/**
* Method called for analysis after creating initial data in constructor. This method causes superimposition
* and rotation of the faces.
*/
public void analyze() { public void analyze() {
List<SimpleMatrix> transformation = new ArrayList<>();
this.superImpose(); this.superImpose();
this.rotate(); this.rotate();
} }
private Point3d computeCentroidsDistance(Point3d centroid1, Point3d centroid2) {
double x = (centroid1.x - centroid2.x);
double y = (centroid1.y - centroid2.y);
double z = (centroid1.z - centroid2.z);
Point3d computedCentroid = new Point3d(x, y, z);
return computedCentroid;
}
/** /**
* Imposes two face models (lists of feature points and vertices) over each other * Imposes two face models (lists of feature points and vertices) over each other
*/ */
private void superImpose() { private void superImpose() {
centerToOrigin(this.faceModel1, this.modelCentroid1);
// moves vertices of face models centerToOrigin(this.faceModel2, this.modelCentroid2);
// moveModelToSameOrigin(this.faceModel2.getVertices(), this.faceModel2.getFeaturePointsMap());
normalize(this.faceModel1, this.modelCentroid1);
normalize(this.faceModel2, this.modelCentroid2);
// moveVertices(this.modelCentroid1, featurePointModel1.getVertices());
// moveModelToPoint(this.modelCentroid1, faceModel1.getVertices(), faceModel1.getFeaturePointsMap());
// moveModelToPoint(this.modelCentroid1, faceModel2.getVertices(), faceModel2.getFeaturePointsMap());
}
private void normalize(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) {
// float size = ProcrustesAnalysisUtils.countSize(centroid, faceModel.getFeaturePointsMap());
centerToOrigin(faceModel, centroid);
} }
/**
* Centers given face model to origin that is given centroid.
* Moves all vertices and feature points by value of difference between vertex/feature point and centroid.
*
* @param faceModel
* @param centroid
*/
private void centerToOrigin(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) { private void centerToOrigin(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) {
for (FeaturePoint fp: faceModel.getFeaturePointsMap().values()) { for (FeaturePoint fp: faceModel.getFeaturePointsMap().values()) {
fp.getPosition().x -= centroid.x; fp.getPosition().x -= centroid.x;
fp.getPosition().y -= centroid.y; fp.getPosition().y -= centroid.y;
fp.getPosition().z -= centroid.z; fp.getPosition().z -= centroid.z;
} }
SimpleMatrix centeredVertices = new SimpleMatrix( for (MeshPoint v : faceModel.getVertices()) {
faceModel.getVerticesMatrix().numRows(), faceModel.getVerticesMatrix().numCols()); v.getPosition().x = v.getX() - centroid.x;
for (int i = 0; i < faceModel.getVerticesMatrix().numRows(); i++) { v.getPosition().y = v.getY() - centroid.y;
centeredVertices.set(i, 0, faceModel.getVerticesMatrix().get(i, 0) - centroid.x); v.getPosition().z = v.getZ() - centroid.z;
centeredVertices.set(i, 1, faceModel.getVerticesMatrix().get(i, 1) - centroid.y);
centeredVertices.set(i, 2, faceModel.getVerticesMatrix().get(i, 2) - centroid.z);
}
faceModel.setVerticesMatrix(centeredVertices);
}
private void moveModelToSameOrigin(List<MeshPoint> vertices, HashMap<Integer, FeaturePoint> featurePointsMap) {
Point3d diff = computeCentroidsDistance(this.modelCentroid1, this.modelCentroid2);
moveModelToPoint(diff, vertices, featurePointsMap);
}
private void moveModelToPoint(Point3d centroid, List<MeshPoint> vertices, HashMap<Integer, FeaturePoint> featurePointsMap) {
moveVertices(centroid, vertices);
moveFeaturePointsToVertices(centroid, featurePointsMap);
}
private void moveFeaturePointsToVertices(Point3d centroid, HashMap<Integer, FeaturePoint> featurePointsMap) {
for (FeaturePoint fp : featurePointsMap.values()) {
fp.getPosition().x = fp.getPosition().x + centroid.x;
fp.getPosition().y = fp.getPosition().y + centroid.y;
fp.getPosition().z = fp.getPosition().z + centroid.z;
} }
} }
...@@ -148,11 +98,6 @@ public class ProcrustesAnalysis { ...@@ -148,11 +98,6 @@ public class ProcrustesAnalysis {
* By rotation of matrices solves orthogonal procrustes problem * By rotation of matrices solves orthogonal procrustes problem
*/ */
private void rotate() { private void rotate() {
// There is no reason trying to rotate less than 3 elements
if (this.getFaceModel1().getFeaturePointsMap().size() < 3) {
throw new ProcrustesAnalysisException("To do procrustes analysis models have to have at least 3 feature points");
}
SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createMatrixFromList(this.faceModel2.getFeaturePointValues()); SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createMatrixFromList(this.faceModel2.getFeaturePointValues());
SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createMatrixFromList( SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createMatrixFromList(
this.faceModel1.getFeaturePointValues()).transpose(); this.faceModel1.getFeaturePointValues()).transpose();
...@@ -160,44 +105,23 @@ public class ProcrustesAnalysis { ...@@ -160,44 +105,23 @@ public class ProcrustesAnalysis {
SimpleMatrix svdMatrix = transposedMatrix.mult(primaryMatrix); SimpleMatrix svdMatrix = transposedMatrix.mult(primaryMatrix);
SimpleSVD<SimpleMatrix> singularValueDecomposition = svdMatrix.svd(); SimpleSVD<SimpleMatrix> singularValueDecomposition = svdMatrix.svd();
SimpleMatrix transposedU = singularValueDecomposition.getU().transpose(); SimpleMatrix transposedU = singularValueDecomposition.getU().transpose();
SimpleMatrix r = singularValueDecomposition.getV().mult(transposedU); SimpleMatrix rotationMatrix = singularValueDecomposition.getV().mult(transposedU);
primaryMatrix = primaryMatrix.mult(r); primaryMatrix = primaryMatrix.mult(rotationMatrix);
this.faceModel2.setFeaturePointsMap( this.faceModel2.setFeaturePointsMap(
ProcrustesAnalysisUtils.createFeaturePointMapFromMatrix( ProcrustesAnalysisUtils.createFeaturePointMapFromMatrix(
primaryMatrix, this.faceModel2)); primaryMatrix, this.faceModel2));
// for (int i = 0; i < this.faceModel2.getFeaturePointTypeCorrespondence().size(); i++) { rotateVertices(this.faceModel2.getVertices(), rotationMatrix);
// FeaturePoint fp = new FeaturePoint(
// primaryMatrix.get(i, 0),
// primaryMatrix.get(i, 1),
// primaryMatrix.get(i, 2),
// this.faceModel2.getFeaturePointsMap().get(
// this.faceModel2.getFeaturePointTypeCorrespondence().get(i)).getFeaturePointType()
// );
// this.faceModel2.getFeaturePointsMap().put(i, fp);
// }
rotateVertices(this.faceModel2.getVertices(), r);
// SimpleMatrix rotatedVertices = this.faceModel2.getVerticesMatrix().mult(r);
// createListFromMatrix(rotatedVertices, this.faceModel2);
} }
private void createListFromMatrix(SimpleMatrix rotatedVertices, ProcrustesAnalysisFaceModel faceModel) {
if (faceModel.getVertices() != null) {
for (int i = 0; i < rotatedVertices.numRows(); i++) {
faceModel.getVertices().get(i).getPosition().x = rotatedVertices.get(i, 0);
faceModel.getVertices().get(i).getPosition().y = rotatedVertices.get(i, 1);
faceModel.getVertices().get(i).getPosition().z = rotatedVertices.get(i, 2);
}
}
}
/** /**
* Rotates every vertex of model by given matrix * Rotates all vertices.
* *
* @param model * For more details check out single vertex rotation {@link #rotateVertex}.
*
* @param vertices
* @param matrix * @param matrix
*/ */
// if rotated vertices are drawn immediately it is better to set them after rotating them all // if rotated vertices are drawn immediately it is better to set them after rotating them all
...@@ -210,7 +134,13 @@ public class ProcrustesAnalysis { ...@@ -210,7 +134,13 @@ public class ProcrustesAnalysis {
} }
} }
public static void rotateVertex(MeshPoint v,SimpleMatrix matrix) { /**
* Rotates vertex v by simulating matrix multiplication with given matrix
*
* @param v
* @param matrix
*/
private static void rotateVertex(MeshPoint v, SimpleMatrix matrix) {
double x = ((v.getX() * matrix.get(0, 0)) double x = ((v.getX() * matrix.get(0, 0))
+ (v.getY() * matrix.get(1, 0)) + (v.getY() * matrix.get(1, 0))
+ (v.getZ() * matrix.get(2, 0))); + (v.getZ() * matrix.get(2, 0)));
...@@ -225,67 +155,4 @@ public class ProcrustesAnalysis { ...@@ -225,67 +155,4 @@ public class ProcrustesAnalysis {
v.getPosition().z = z; v.getPosition().z = z;
} }
/**
* Calculates new vertices adjusted to the centroid by method {@see findCenteroidOfFeaturePoints},
* so moved featurepoints would correspond with the same place on face as they did before.
*
* @param centroid
* @param vertices
* @return
*/
private void moveVertices(Point3d centroid, List<MeshPoint> vertices) {
if (vertices != null && centroid != null) {
// List<MeshPoint> movedVertices = null;
for (MeshPoint v : vertices) {
v.getPosition().x = (v.getPosition().x + centroid.x);
v.getPosition().y = (v.getPosition().y + centroid.y);
v.getPosition().z = (v.getPosition().z + centroid.z);
}
} else {
throw new ProcrustesAnalysisException("Could not compute vertices locations after moving the centroid from model to feature points");
}
}
/**
* Creates sorted feature point lists and compares them whether they have
* the same feature point types.
*
* @param fpList1
* @param fpList2
* @return
*/
private boolean featurePointTypesEquivalence(List<FeaturePoint> fpList1, List<FeaturePoint> fpList2) {
return ProcrustesAnalysisUtils.checkFeaturePointsType(fpList1, fpList2);
}
/**
* Calculate scaling ratio of how much the appropriate object corresponding
* to the second feature point list has to be scale up or shrunk.
* <p>
* If returned ratioValue is greater 1 then it means that the second object
* should be scaled up ratioValue times. If returned ratioValue is smaller 1
* than the second object should be shrunk.
*
* @return ratioValue
*/
// private double calculateScalingValue() {
// double[] distancesOfList1 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(
// this.faceModel1.getFeaturePointValues());
// double[] distancesOfList2 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(
// this.faceModel2.getFeaturePointValues());
//
// double[] ratioArray = new double[distancesOfList1.length];
// double ratioValue = 0;
//
// for (int i = 0; i < distancesOfList1.length; i++) {
// ratioArray[i] += distancesOfList1[i] / distancesOfList2[i];
// }
//
// for (double ratio : ratioArray) {
// ratioValue += ratio;
// }
//
// return ratioValue / distancesOfList1.length;
// }
} }
...@@ -26,7 +26,6 @@ public class ProcrustesAnalysisFaceModel { ...@@ -26,7 +26,6 @@ public class ProcrustesAnalysisFaceModel {
private final HumanFace humanFace; private final HumanFace humanFace;
private HashMap<Integer, FeaturePoint> featurePointsMap; // sorted by feature point type private HashMap<Integer, FeaturePoint> featurePointsMap; // sorted by feature point type
private List<MeshPoint> vertices; private List<MeshPoint> vertices;
private SimpleMatrix verticesMatrix;
private MeshModel meshModel; private MeshModel meshModel;
private final HashMap<Integer, Integer> featurePointTypeCorrespondence; private final HashMap<Integer, Integer> featurePointTypeCorrespondence;
...@@ -43,8 +42,6 @@ public class ProcrustesAnalysisFaceModel { ...@@ -43,8 +42,6 @@ public class ProcrustesAnalysisFaceModel {
this.featurePointsMap = createFeaturePointMap( this.featurePointsMap = createFeaturePointMap(
ProcrustesAnalysisUtils.sortListByFeaturePointType(modifiableFeaturePointList)); ProcrustesAnalysisUtils.sortListByFeaturePointType(modifiableFeaturePointList));
this.featurePointTypeCorrespondence = createFeaturePointTypeCorrespondence(face.getFeaturePoints()); this.featurePointTypeCorrespondence = createFeaturePointTypeCorrespondence(face.getFeaturePoints());
this.verticesMatrix = ProcrustesAnalysisUtils.createMatrixFromList(modifiableVertices);
// this.featurePointMatrix = ProcrustesAnalysisUtils.createMatrixFromList(modifiableFeaturePointList);
} }
/** /**
...@@ -74,28 +71,19 @@ public class ProcrustesAnalysisFaceModel { ...@@ -74,28 +71,19 @@ public class ProcrustesAnalysisFaceModel {
return featurePointsMap; return featurePointsMap;
} }
public HashMap<Integer, Integer> getFeaturePointTypeCorrespondence() {
return featurePointTypeCorrespondence;
}
/** /**
* sets vertices map and also sets feature point on human face for visualisation * Creates feature point hash map for internal use in Procrustes Analysis.
*
* Map key is feature point type (Integer).
* Value is feature point itself.
* *
* @param verticesMatrix * @param featurePointList
* @return
*/ */
public void setVerticesMatrix(SimpleMatrix verticesMatrix) {
this.verticesMatrix = verticesMatrix;
changeVerticesValues(verticesMatrix);
}
public SimpleMatrix getVerticesMatrix() {
return verticesMatrix;
}
private void changeVerticesValues(SimpleMatrix matrix) {
for (int i = 0; i < vertices.size(); i++) {
vertices.get(i).getPosition().x = (float) matrix.get(i, 0);
vertices.get(i).getPosition().y = (float) matrix.get(i, 1);
vertices.get(i).getPosition().z = (float) matrix.get(i, 2);
}
}
private HashMap<Integer, FeaturePoint> createFeaturePointMap(List<FeaturePoint> featurePointList) { private HashMap<Integer, FeaturePoint> createFeaturePointMap(List<FeaturePoint> featurePointList) {
HashMap<Integer, FeaturePoint> map = new HashMap<>(); HashMap<Integer, FeaturePoint> map = new HashMap<>();
for (FeaturePoint fp: featurePointList) { for (FeaturePoint fp: featurePointList) {
...@@ -104,10 +92,6 @@ public class ProcrustesAnalysisFaceModel { ...@@ -104,10 +92,6 @@ public class ProcrustesAnalysisFaceModel {
return map; return map;
} }
public HashMap<Integer, Integer> getFeaturePointTypeCorrespondence() {
return featurePointTypeCorrespondence;
}
/** /**
* Creates corresponding key value pair of matrix row index and a feature point type value. * Creates corresponding key value pair of matrix row index and a feature point type value.
* It is used in {@link cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils#createFeaturePointMapFromMatrix} * It is used in {@link cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils#createFeaturePointMapFromMatrix}
......
...@@ -34,21 +34,6 @@ public class ProcrustesAnalysisUtils { ...@@ -34,21 +34,6 @@ public class ProcrustesAnalysisUtils {
return featurePointList; return featurePointList;
} }
/**
* Creates hash map with a key feature point type and value feature point
* @param featurePointList
* @return
*/
public static HashMap<Integer, FeaturePoint> generateFeaturePointHashMap(List<FeaturePoint> featurePointList) {
HashMap<Integer, FeaturePoint> map = new HashMap<>();
for (FeaturePoint fp : featurePointList) {
if (fp.getFeaturePointType().getType() > 0) {
map.put(fp.getFeaturePointType().getType(), fp);
}
}
return map;
}
/** /**
* Checks if two feature point lists have the same types of feature points. * Checks if two feature point lists have the same types of feature points.
* <p> * <p>
...@@ -75,20 +60,6 @@ public class ProcrustesAnalysisUtils { ...@@ -75,20 +60,6 @@ public class ProcrustesAnalysisUtils {
return true; return true;
} }
/**
* Creates array of distance values from feature point to origin (0,0,0).
*
* @param featurePointList
* @return array of distances
*/
public static double[] calculateMeanDistancesFromOrigin(List<FeaturePoint> featurePointList) {
double[] distances = new double[featurePointList.size()];
for (int i = 0; i < featurePointList.size(); i++) {
distances[i] = calculatePointDistanceFromOrigin(featurePointList.get(i));
}
return distances;
}
/** /**
* Finds centrioid from given feature point List * Finds centrioid from given feature point List
* *
...@@ -107,33 +78,6 @@ public class ProcrustesAnalysisUtils { ...@@ -107,33 +78,6 @@ public class ProcrustesAnalysisUtils {
return new Point3d(x / featurePointList.size(), y / featurePointList.size(), z / featurePointList.size()); return new Point3d(x / featurePointList.size(), y / featurePointList.size(), z / featurePointList.size());
} }
/**
* Calculates distance of one feature point from another
*
* @param fp1
* @param fp2
* @return distance
*/
public static double calculateDistanceOfTwoPoints(FeaturePoint fp1, FeaturePoint fp2) {
return Math.sqrt(
(Math.pow(fp1.getX(), 2) - Math.pow(fp2.getX(), 2))
+ (Math.pow(fp1.getY(), 2) - Math.pow(fp2.getY(), 2))
+ (Math.pow(fp1.getZ(), 2) - Math.pow(fp2.getZ(), 2)));
}
/**
* Calculates distance of single feature point from origin (0,0,0)
*
* @param fp
* @return distance
*/
public static double calculatePointDistanceFromOrigin(FeaturePoint fp) {
return Math.sqrt(
Math.pow(fp.getX(), 2)
+ Math.pow(fp.getY(), 2)
+ Math.pow(fp.getZ(), 2));
}
/** /**
* Creates matrix from given feature point list * Creates matrix from given feature point list
* *
...@@ -174,25 +118,4 @@ public class ProcrustesAnalysisUtils { ...@@ -174,25 +118,4 @@ public class ProcrustesAnalysisUtils {
return map; return map;
} }
public static float countSize(Point3d point, HashMap<Integer, FeaturePoint> featurePointsMap) {
float size = 0;
for (FeaturePoint fp: featurePointsMap.values()) {
size += (fp.getX() - point.x) * (fp.getX() - point.x);
size += (fp.getY() - point.y) * (fp.getY() - point.y);
size += (fp.getZ() - point.z) * (fp.getZ() - point.z);
}
return ((float) Math.sqrt(size));
}
// public List<MeshPoint> CreateVerticesListFromMatrix (SimpleMatrix matrix) {
// List<MeshPoint> verticesList = new ArrayList<>();
// for (int i = 0; i < matrix.numRows(); i++) {
// float x = (float) matrix.get(i, 0);
// float y = (float) matrix.get(i, 1);
// float z = (float) matrix.get(i, 2);
// verticesList.add(new MeshPoint() {
// })
// }
// }
} }
...@@ -8,6 +8,7 @@ package cz.fidentis.analyst.feature.api; ...@@ -8,6 +8,7 @@ package cz.fidentis.analyst.feature.api;
import javax.vecmath.Point3d; import javax.vecmath.Point3d;
/** /**
* Interface for working.
* *
* @author Jakub Kolman * @author Jakub Kolman
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment