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

[#38] feat: rotation on procrustes analysis

parent 02ca049a
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,7 @@ import cz.fidentis.analyst.icp.IcpTransformation; ...@@ -6,6 +6,7 @@ import cz.fidentis.analyst.icp.IcpTransformation;
import cz.fidentis.analyst.mesh.core.MeshPoint; import cz.fidentis.analyst.mesh.core.MeshPoint;
import cz.fidentis.analyst.procrustes.exceptions.ProcrustesAnalysisException; import cz.fidentis.analyst.procrustes.exceptions.ProcrustesAnalysisException;
import cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils; import cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils;
import org.ejml.data.Matrix;
import org.ejml.simple.SimpleMatrix; import org.ejml.simple.SimpleMatrix;
import org.ejml.simple.SimpleSVD; import org.ejml.simple.SimpleSVD;
...@@ -20,12 +21,6 @@ import javax.vecmath.Point3d; ...@@ -20,12 +21,6 @@ import javax.vecmath.Point3d;
*/ */
public class ProcrustesAnalysis { public class ProcrustesAnalysis {
private HumanFace humanFace1;
private HumanFace humanFace2;
private List<FeaturePoint> orderedFeaturePointList1;
private List<FeaturePoint> orderedFeaturePointList2;
private ProcrustesAnalysisFaceModel faceModel1; private ProcrustesAnalysisFaceModel faceModel1;
private ProcrustesAnalysisFaceModel faceModel2; private ProcrustesAnalysisFaceModel faceModel2;
...@@ -45,8 +40,6 @@ public class ProcrustesAnalysis { ...@@ -45,8 +40,6 @@ public class ProcrustesAnalysis {
public ProcrustesAnalysis( public ProcrustesAnalysis(
HumanFace humanFace1, HumanFace humanFace1,
HumanFace humanFace2) throws ProcrustesAnalysisException { HumanFace humanFace2) throws ProcrustesAnalysisException {
this.humanFace1 = humanFace1;
this.humanFace2 = humanFace2;
ProcrustesAnalysisFaceModel model1 = new ProcrustesAnalysisFaceModel(humanFace1); ProcrustesAnalysisFaceModel model1 = new ProcrustesAnalysisFaceModel(humanFace1);
ProcrustesAnalysisFaceModel model2 = new ProcrustesAnalysisFaceModel(humanFace2); ProcrustesAnalysisFaceModel model2 = new ProcrustesAnalysisFaceModel(humanFace2);
...@@ -55,18 +48,20 @@ public class ProcrustesAnalysis { ...@@ -55,18 +48,20 @@ 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()); // this.orderedFeaturePointList1 = new ArrayList<>(model1.getFeaturePointsMap().values());
this.orderedFeaturePointList2 = new ArrayList<>(model2.getFeaturePointsMap().values()); // this.orderedFeaturePointList2 = new ArrayList<>(model2.getFeaturePointsMap().values());
if (!featurePointTypesEquivalence(orderedFeaturePointList1, orderedFeaturePointList2)) { 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");
} }
this.faceModel1 = model1; this.faceModel1 = model1;
this.faceModel2 = model2; this.faceModel2 = model2;
this.modelCentroid1 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(orderedFeaturePointList1); this.modelCentroid1 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model1.getFeaturePointValues());
this.modelCentroid2 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(orderedFeaturePointList2); this.modelCentroid2 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model2.getFeaturePointValues());
} }
...@@ -78,85 +73,133 @@ public class ProcrustesAnalysis { ...@@ -78,85 +73,133 @@ public class ProcrustesAnalysis {
return faceModel2; return faceModel2;
} }
public List<IcpTransformation> analyze(ProcrustesAnalysisFaceModel faceModel1, ProcrustesAnalysisFaceModel faceModel2) { public List<SimpleMatrix> analyze() {
List<IcpTransformation> transformation = new ArrayList<>(); List<SimpleMatrix> transformation = new ArrayList<>();
superImpose(faceModel1, faceModel2); this.superImpose();
rotate(faceModel1, faceModel2); SimpleMatrix rotation = this.rotate();
return transformation; if (rotation != null) {
transformation.add(rotation);
return transformation;
} else {
return null;
}
} }
private Point3d computeCentroidsDistance(Point3d centroid1, Point3d centroid2) { // private Point3d computeCentroidsDistance(Point3d centroid1, Point3d centroid2) {
double x = (centroid1.x - centroid2.x); // double x = (centroid1.x - centroid2.x);
double y = (centroid1.y - centroid2.y); // double y = (centroid1.y - centroid2.y);
double z = (centroid1.z - centroid2.z); // double z = (centroid1.z - centroid2.z);
//
Point3d computedCentroid = new Point3d(x, y, z); // Point3d computedCentroid = new Point3d(x, y, z);
return computedCentroid; // 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
*
* @param featurePointModel1
* @param featurePointModel2
*/ */
private void superImpose(ProcrustesAnalysisFaceModel featurePointModel1, private void superImpose() {
ProcrustesAnalysisFaceModel featurePointModel2) {
// moves vertices of face models // moves vertices of face models
moveModelToSameOrigin(featurePointModel2.getVertices(), featurePointModel2.getFeaturePointsMap()); // moveModelToSameOrigin(this.faceModel2.getVertices(), this.faceModel2.getFeaturePointsMap());
// moveVertices(this.modelCentroid1, featurePointModel1.getVertices()); normalize(this.faceModel1, this.modelCentroid1);
moveModelToPoint(this.modelCentroid1, featurePointModel1.getVertices(), featurePointModel1.getFeaturePointsMap()); normalize(this.faceModel2, this.modelCentroid2);
moveModelToPoint(this.modelCentroid1, featurePointModel2.getVertices(), featurePointModel2.getFeaturePointsMap());
}
private void moveModelToSameOrigin(List<MeshPoint> vertices, HashMap<Integer, FeaturePoint> featurePointsMap) { // moveVertices(this.modelCentroid1, featurePointModel1.getVertices());
Point3d diff = computeCentroidsDistance(modelCentroid1, modelCentroid2); // moveModelToPoint(this.modelCentroid1, faceModel1.getVertices(), faceModel1.getFeaturePointsMap());
moveModelToPoint(diff, vertices, featurePointsMap); // moveModelToPoint(this.modelCentroid1, faceModel2.getVertices(), faceModel2.getFeaturePointsMap());
} }
private void moveModelToPoint(Point3d centroid, List<MeshPoint> vertices, HashMap<Integer, FeaturePoint> featurePointsMap){ private void normalize(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) {
moveVertices(centroid, vertices); // float size = ProcrustesAnalysisUtils.countSize(centroid, faceModel.getFeaturePointsMap());
moveFeaturePointsToVertices(centroid, featurePointsMap); centerToOrigin(faceModel, centroid);
} }
private void moveFeaturePointsToVertices(Point3d centroid, HashMap<Integer, FeaturePoint> featurePointsMap) { private void centerToOrigin(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) {
for (FeaturePoint fp: featurePointsMap.values()) { for (FeaturePoint fp: faceModel.getFeaturePointsMap().values()) {
fp.getPosition().x = fp.getPosition().x + centroid.x; fp.getPosition().x -= centroid.x;
fp.getPosition().y = fp.getPosition().y + centroid.y; fp.getPosition().y -= centroid.y;
fp.getPosition().z = fp.getPosition().z + centroid.z; fp.getPosition().z -= centroid.z;
}
SimpleMatrix centeredVertices = new SimpleMatrix(
faceModel.getVerticesMatrix().numRows(), faceModel.getVerticesMatrix().numCols());
for (int i = 0; i < faceModel.getVerticesMatrix().numRows(); i++) {
centeredVertices.set(i, 0, faceModel.getVerticesMatrix().get(i, 0) - centroid.x);
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;
// }
// }
/** /**
* By rotation of matrices solves orthogonal procrustes problem * By rotation of matrices solves orthogonal procrustes problem
*
* @param featurePointModel1
* @param featurePointModel2
*/ */
private void rotate(ProcrustesAnalysisFaceModel featurePointModel1, private SimpleMatrix rotate() {
ProcrustesAnalysisFaceModel featurePointModel2) {
// There is no reason trying to rotate less than 3 elements // There is no reason trying to rotate less than 3 elements
if (this.orderedFeaturePointList1.size() < 3) { if (this.getFaceModel1().getFeaturePointsMap().size() < 3) {
return; throw new ProcrustesAnalysisException("To do procrustes analysis models have to have at least 3 feature points");
} }
SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createFeaturePointMatrix(orderedFeaturePointList2); SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createFeaturePointMatrix(this.faceModel2.getFeaturePointValues());
SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createFeaturePointMatrix( SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createFeaturePointMatrix(
orderedFeaturePointList1).transpose(); this.faceModel1.getFeaturePointValues()).transpose();
SimpleMatrix multipliedMatrix = transposedMatrix.mult(primaryMatrix); SimpleMatrix svdMatrix = transposedMatrix.mult(primaryMatrix);
SimpleSVD<SimpleMatrix> singularValueDecomposition = multipliedMatrix.svd(); SimpleSVD<SimpleMatrix> singularValueDecomposition = svdMatrix.svd();
SimpleMatrix transposedU = singularValueDecomposition.getU().transpose(); SimpleMatrix transposedU = singularValueDecomposition.getU().transpose();
SimpleMatrix r = singularValueDecomposition.getV().mult(transposedU); SimpleMatrix r = singularValueDecomposition.getV().mult(transposedU);
primaryMatrix = primaryMatrix.mult(r); primaryMatrix = primaryMatrix.mult(r);
featurePointModel2.setFeaturePointsMap( this.faceModel2.setFeaturePointsMap(
ProcrustesAnalysisUtils.createFeaturePointMapFromMatrix(primaryMatrix, featurePointModel2)); ProcrustesAnalysisUtils.createFeaturePointMapFromMatrix(
primaryMatrix, this.faceModel2));
// for (int i = 0; i < this.faceModel2.getFeaturePointTypeCorrespondence().size(); i++) {
// 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, primaryMatrix);
SimpleMatrix rotatedVertices = this.faceModel2.getVerticesMatrix().mult(r);
createListFromMatrix(rotatedVertices, this.faceModel2);
rotateVertices(featurePointModel2, primaryMatrix); return r;
}
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);
}
}
} }
/** /**
...@@ -167,39 +210,34 @@ public class ProcrustesAnalysis { ...@@ -167,39 +210,34 @@ public class ProcrustesAnalysis {
*/ */
// 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
// so it would be drawn just once // so it would be drawn just once
private void rotateVertices(ProcrustesAnalysisFaceModel model, SimpleMatrix matrix) { // private void rotateVertices(ProcrustesAnalysisFaceModel model, SimpleMatrix matrix) {
if (model.getVertices() != null) { // if (model.getVertices() != null) {
int i = 0; // for (MeshPoint v : model.getVertices()) {
for (MeshPoint v : model.getVertices()) { // v.setPosition(ProcrustesAnalysisUtils.rotateVertex(v, matrix));
v.setPosition(ProcrustesAnalysisUtils.rotateVertex(v, matrix)); // }
} // }
} // }
}
/** /**
* Calculates new vertices adjusted to the centroid by method {@see findCenteroidOfFeaturePoints}, * 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. * so moved featurepoints would correspond with the same place on face as they did before.
* @param centroid *
* @param centroid
* @param vertices * @param vertices
* @return * @return
*/ */
private void moveVertices(Point3d centroid, List<MeshPoint> vertices) { // private void moveVertices(Point3d centroid, List<MeshPoint> vertices) {
if (vertices != null && centroid != null) { // if (vertices != null && centroid != null) {
// List<MeshPoint> movedVertices = null; //// List<MeshPoint> movedVertices = null;
for (MeshPoint v : vertices) { // for (MeshPoint v : vertices) {
v.getPosition().x = (v.getPosition().x + centroid.x); // v.getPosition().x = (v.getPosition().x + centroid.x);
v.getPosition().y = (v.getPosition().y + centroid.y); // v.getPosition().y = (v.getPosition().y + centroid.y);
v.getPosition().z = (v.getPosition().z + centroid.z); // v.getPosition().z = (v.getPosition().z + centroid.z);
// float x = (float) (v.getPosition().x + centroid.x); // }
// float y = (float) (v.getPosition().y + centroid.y); // } else {
// float z = (float) (v.getPosition().z + centroid.z); // throw new ProcrustesAnalysisException("Could not compute vertices locations after moving the centroid from model to feature points");
// Point3d p = new Point3d(x, y, z); // }
// v.setPosition(new Point3d(x, y, 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 * Creates sorted feature point lists and compares them whether they have
...@@ -223,22 +261,24 @@ public class ProcrustesAnalysis { ...@@ -223,22 +261,24 @@ public class ProcrustesAnalysis {
* *
* @return ratioValue * @return ratioValue
*/ */
private double calculateScalingValue() { // private double calculateScalingValue() {
double[] distancesOfList1 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(orderedFeaturePointList1); // double[] distancesOfList1 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(
double[] distancesOfList2 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(orderedFeaturePointList2); // this.faceModel1.getFeaturePointValues());
// double[] distancesOfList2 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(
double[] ratioArray = new double[distancesOfList1.length]; // this.faceModel2.getFeaturePointValues());
double ratioValue = 0; //
// double[] ratioArray = new double[distancesOfList1.length];
for (int i = 0; i < distancesOfList1.length; i++) { // double ratioValue = 0;
ratioArray[i] += distancesOfList1[i] / distancesOfList2[i]; //
} // for (int i = 0; i < distancesOfList1.length; i++) {
// ratioArray[i] += distancesOfList1[i] / distancesOfList2[i];
for (double ratio : ratioArray) { // }
ratioValue += ratio; //
} // for (double ratio : ratioArray) {
// ratioValue += ratio;
return ratioValue / distancesOfList1.length; // }
} //
// return ratioValue / distancesOfList1.length;
// }
} }
...@@ -71,23 +71,26 @@ public class ProcrustesAnalysisComparison { ...@@ -71,23 +71,26 @@ public class ProcrustesAnalysisComparison {
// HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(FACE_2_PATH.toString()))); // HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(FACE_2_PATH.toString())));
// HEADS from the old models // HEADS from the old models
List<FeaturePoint> fpList01 = featurePointImportService.importFeaturePoints( // List<FeaturePoint> fpList01 = featurePointImportService.importFeaturePoints(
FP_FILE_DIRECTORY.toString(), OLD_FP_HEAD_01); // FP_FILE_DIRECTORY.toString(), OLD_FP_HEAD_01);
List<FeaturePoint> fpList02 = featurePointImportService.importFeaturePoints( // List<FeaturePoint> fpList02 = featurePointImportService.importFeaturePoints(
FP_FILE_DIRECTORY.toString(), OLD_FP_HEAD_02); // FP_FILE_DIRECTORY.toString(), OLD_FP_HEAD_02);
HumanFace face1 = factory.getFace(factory.loadFace(fru.getFileFromResource(OLD_HEAD_01_PATH.toString()))); // HumanFace face1 = factory.getFace(factory.loadFace(fru.getFileFromResource(OLD_HEAD_01_PATH.toString())));
HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(OLD_HEAD_02_PATH.toString()))); // HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(OLD_HEAD_02_PATH.toString())));
//
face1.setFeaturePoints(fpList01); // face1.setFeaturePoints(fpList01);
face2.setFeaturePoints(fpList02); // face2.setFeaturePoints(fpList02);
ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2);
// //
// FeaturePointExportService featurePointExportService = new FeaturePointExportService(); // ProcrustesAnalysis pa = new ProcrustesAnalysis(face1, face2);
// import fp export csv
// List<FeaturePoint> fpList01 = featurePointImportService.importFeaturePoints(
// FP_FILE_DIRECTORY.toString(), "3points_head02head01.fp");
List<FeaturePoint> fpList02 = featurePointImportService.importFeaturePoints(
FP_FILE_DIRECTORY.toString(), "3points_top_head02.fp");
FeaturePointExportService featurePointExportService = new FeaturePointExportService();
// featurePointExportService.exportFeaturePoints(fpList01, "head01", "CSV"); // featurePointExportService.exportFeaturePoints(fpList01, "head01", "CSV");
// featurePointExportService.exportFeaturePoints(fpList01, "head02", "CSV"); featurePointExportService.exportFeaturePoints(fpList02, "3points_top_head02", "CSV");
System.out.println("finished"); System.out.println("finished");
......
...@@ -7,12 +7,11 @@ package cz.fidentis.analyst.procrustes; ...@@ -7,12 +7,11 @@ package cz.fidentis.analyst.procrustes;
import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.face.HumanFace;
import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.FeaturePoint;
import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.mesh.core.MeshModel; import cz.fidentis.analyst.mesh.core.MeshModel;
import cz.fidentis.analyst.mesh.core.MeshPoint; import cz.fidentis.analyst.mesh.core.MeshPoint;
import cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils; import cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils;
import org.ejml.simple.SimpleMatrix;
import javax.vecmath.Vector3f;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -22,47 +21,91 @@ import java.util.List; ...@@ -22,47 +21,91 @@ import java.util.List;
* @author Jakub Kolman * @author Jakub Kolman
*/ */
public class ProcrustesAnalysisFaceModel { public class ProcrustesAnalysisFaceModel {
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;
public ProcrustesAnalysisFaceModel(HumanFace face) { public ProcrustesAnalysisFaceModel(HumanFace face) {
this.humanFace = face;
// getFeaturePoints() returns unmodifiable List. To sort it we need to make copy first // getFeaturePoints() returns unmodifiable List. To sort it we need to make copy first
List<FeaturePoint> modifiableFeaturePointList = new ArrayList<>(face.getFeaturePoints()); List<FeaturePoint> modifiableFeaturePointList = new ArrayList<>(face.getFeaturePoints());
// To be able to move vertices we have to make a copy of them because getFacets() returns unmodifiable List // 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()); List<MeshPoint> modifiableVertices = new ArrayList<>(face.getMeshModel().getFacets().get(0).getVertices());
this.featurePointsMap = ProcrustesAnalysisUtils.generateFeaturePointHashMap(
ProcrustesAnalysisUtils.sortListByFeaturePointType(modifiableFeaturePointList));
this.meshModel = face.getMeshModel();
this.vertices = modifiableVertices; this.vertices = modifiableVertices;
this.meshModel = face.getMeshModel();
this.featurePointsMap = createFeaturePointMap(
ProcrustesAnalysisUtils.sortListByFeaturePointType(modifiableFeaturePointList));
this.featurePointTypeCorrespondence = createFeaturePointTypeCorrespondence(face.getFeaturePoints()); this.featurePointTypeCorrespondence = createFeaturePointTypeCorrespondence(face.getFeaturePoints());
this.verticesMatrix = createVerticesMatrix(face.getMeshModel().getFacets().get(0).getVertices());
}
public void setFeaturePointsMap(HashMap<Integer, FeaturePoint> featurePointsMap) {
this.featurePointsMap = featurePointsMap;
this.humanFace.setFeaturePoints(getFeaturePointValues());
} }
public MeshModel getMeshModel() { public MeshModel getMeshModel() {
return meshModel; return meshModel;
} }
public void setVertices(List<MeshPoint> vertices) { public List<FeaturePoint> getFeaturePointValues() {
this.vertices = vertices; return new ArrayList<>(this.getFeaturePointsMap().values());
} }
public List<MeshPoint> getVertices() { public List<MeshPoint> getVertices() {
return vertices; return vertices;
} }
public void setFeaturePointsMap(HashMap<Integer, FeaturePoint> featurePointsMap) {
this.featurePointsMap = featurePointsMap;
}
public HashMap<Integer, FeaturePoint> getFeaturePointsMap() { public HashMap<Integer, FeaturePoint> getFeaturePointsMap() {
return featurePointsMap; return featurePointsMap;
} }
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) {
HashMap<Integer, FeaturePoint> map = new HashMap<>();
// for (int i = 0; i < featurePointList.size(); i++) {
// map.put(i, featurePointList.get(i));
// }
for (FeaturePoint fp: featurePointList) {
map.put(fp.getFeaturePointType().getType(), fp);
}
return map;
}
private SimpleMatrix createVerticesMatrix(List<MeshPoint> vertices) {
SimpleMatrix matrix = new SimpleMatrix(vertices.size(), 3);
for (int i = 0; i < vertices.size(); i++) {
matrix.set(i, 0, vertices.get(i).getPosition().x);
matrix.set(i, 1, vertices.get(i).getPosition().y);
matrix.set(i, 2, vertices.get(i).getPosition().z);
}
return matrix;
}
public HashMap<Integer, Integer> getFeaturePointTypeCorrespondence() { public HashMap<Integer, Integer> getFeaturePointTypeCorrespondence() {
return featurePointTypeCorrespondence; return featurePointTypeCorrespondence;
} }
......
...@@ -157,15 +157,18 @@ public class ProcrustesAnalysisUtils { ...@@ -157,15 +157,18 @@ public class ProcrustesAnalysisUtils {
* @param model * @param model
* @return * @return
*/ */
public static HashMap<Integer, FeaturePoint> createFeaturePointMapFromMatrix(SimpleMatrix matrix, ProcrustesAnalysisFaceModel model) { public static HashMap<Integer, FeaturePoint> createFeaturePointMapFromMatrix(
SimpleMatrix matrix, ProcrustesAnalysisFaceModel model) {
HashMap<Integer, FeaturePoint> map = new HashMap<>(); HashMap<Integer, FeaturePoint> map = new HashMap<>();
for (int i = 0; i < matrix.numRows(); i++) { for (int i = 0; i < matrix.numRows(); i++) {
FeaturePoint featurePoint = new FeaturePoint( FeaturePoint featurePoint = new FeaturePoint(
matrix.get(i, 0), matrix.get(i, 0),
matrix.get(i, 1), matrix.get(i, 1),
matrix.get(i, 2), matrix.get(i, 2),
FeaturePointTypeProvider.getInstance().getFeaturePointTypeById( model.getFeaturePointsMap().get(
model.getFeaturePointTypeCorrespondence().get(i))); model.getFeaturePointTypeCorrespondence().get(i)
).getFeaturePointType()
);
map.put(model.getFeaturePointTypeCorrespondence().get(i), featurePoint); map.put(model.getFeaturePointTypeCorrespondence().get(i), featurePoint);
} }
return map; return map;
...@@ -191,4 +194,25 @@ public class ProcrustesAnalysisUtils { ...@@ -191,4 +194,25 @@ public class ProcrustesAnalysisUtils {
Point3d rotatedVertex = new Point3d(x, y, z); Point3d rotatedVertex = new Point3d(x, y, z);
return rotatedVertex; return rotatedVertex;
} }
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() {
// })
// }
// }
} }
...@@ -136,6 +136,13 @@ ...@@ -136,6 +136,13 @@
<groupId>org.netbeans.external</groupId> <groupId>org.netbeans.external</groupId>
<artifactId>AbsoluteLayout</artifactId> <artifactId>AbsoluteLayout</artifactId>
<version>RELEASE123</version> <version>RELEASE123</version>
</dependency>
<!-- http://ejml.org/wiki/index.php?title=Main_Page -->
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-all</artifactId>
<version>0.41</version>
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
......
...@@ -14,6 +14,8 @@ import cz.fidentis.analyst.mesh.core.MeshFacet; ...@@ -14,6 +14,8 @@ import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.mesh.core.MeshPoint; import cz.fidentis.analyst.mesh.core.MeshPoint;
import cz.fidentis.analyst.procrustes.ProcrustesAnalysis; import cz.fidentis.analyst.procrustes.ProcrustesAnalysis;
import cz.fidentis.analyst.visitors.mesh.HausdorffDistance; import cz.fidentis.analyst.visitors.mesh.HausdorffDistance;
import org.ejml.simple.SimpleMatrix;
import java.awt.Color; import java.awt.Color;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.List; import java.util.List;
...@@ -270,7 +272,7 @@ public class RegistrationAction extends ControlPanelAction { ...@@ -270,7 +272,7 @@ public class RegistrationAction extends ControlPanelAction {
HumanFace secondaryFace = getScene().getHumanFace(1); HumanFace secondaryFace = getScene().getHumanFace(1);
ProcrustesAnalysis procrustesAnalysisInit = new ProcrustesAnalysis(primaryFace, secondaryFace); ProcrustesAnalysis procrustesAnalysisInit = new ProcrustesAnalysis(primaryFace, secondaryFace);
List<IcpTransformation> transformation = procrustesAnalysisInit.analyze(procrustesAnalysisInit.getFaceModel1(), procrustesAnalysisInit.getFaceModel2()); List<SimpleMatrix> transformation = procrustesAnalysisInit.analyze();
} }
protected void applyICP() { protected void applyICP() {
...@@ -298,7 +300,7 @@ public class RegistrationAction extends ControlPanelAction { ...@@ -298,7 +300,7 @@ public class RegistrationAction extends ControlPanelAction {
/** /**
* Sets the transparency of {@link #getPrimaryDrawableFace} or {@link #getSecondaryDrawableFace()} * Sets the transparency of {@link #getPrimaryDrawableFace} or {@link #getSecondaryDrawableFace()}
* based on the inputed value and {@link @TRANSPARENCY_RANGE} * based on the inputted value and {@link @TRANSPARENCY_RANGE}
* @param value Value * @param value Value
*/ */
private void setTransparency(int value) { private void setTransparency(int value) {
......
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