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

[#38] feat: procrustes analysis working with matrix

parent fa57f8e8
No related branches found
No related tags found
No related merge requests found
...@@ -153,8 +153,8 @@ public class ProcrustesAnalysis { ...@@ -153,8 +153,8 @@ public class ProcrustesAnalysis {
if (this.getFaceModel1().getFeaturePointsMap().size() < 3) { if (this.getFaceModel1().getFeaturePointsMap().size() < 3) {
throw new ProcrustesAnalysisException("To do procrustes analysis models have to have at least 3 feature points"); throw new ProcrustesAnalysisException("To do procrustes analysis models have to have at least 3 feature points");
} }
SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createFeaturePointMatrix(this.faceModel2.getFeaturePointValues()); SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createMatrixFromList(this.faceModel2.getFeaturePointValues());
SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createFeaturePointMatrix( SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createMatrixFromList(
this.faceModel1.getFeaturePointValues()).transpose(); this.faceModel1.getFeaturePointValues()).transpose();
SimpleMatrix svdMatrix = transposedMatrix.mult(primaryMatrix); SimpleMatrix svdMatrix = transposedMatrix.mult(primaryMatrix);
...@@ -178,10 +178,10 @@ public class ProcrustesAnalysis { ...@@ -178,10 +178,10 @@ public class ProcrustesAnalysis {
// this.faceModel2.getFeaturePointsMap().put(i, fp); // this.faceModel2.getFeaturePointsMap().put(i, fp);
// } // }
// rotateVertices(this.faceModel2, primaryMatrix); rotateVertices(this.faceModel2.getVertices(), r);
SimpleMatrix rotatedVertices = this.faceModel2.getVerticesMatrix().mult(r); // SimpleMatrix rotatedVertices = this.faceModel2.getVerticesMatrix().mult(r);
createListFromMatrix(rotatedVertices, this.faceModel2); // createListFromMatrix(rotatedVertices, this.faceModel2);
} }
private void createListFromMatrix(SimpleMatrix rotatedVertices, ProcrustesAnalysisFaceModel faceModel) { private void createListFromMatrix(SimpleMatrix rotatedVertices, ProcrustesAnalysisFaceModel faceModel) {
...@@ -202,13 +202,28 @@ public class ProcrustesAnalysis { ...@@ -202,13 +202,28 @@ 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(List<MeshPoint> vertices, SimpleMatrix matrix) {
// if (model.getVertices() != null) { if (vertices != null) {
// for (MeshPoint v : model.getVertices()) { for (int i = 0; i < vertices.size(); i++) {
// v.setPosition(ProcrustesAnalysisUtils.rotateVertex(v, matrix)); rotateVertex(vertices.get(i), matrix);
// } }
// } }
// } }
public 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;
}
/** /**
* Calculates new vertices adjusted to the centroid by method {@see findCenteroidOfFeaturePoints}, * Calculates new vertices adjusted to the centroid by method {@see findCenteroidOfFeaturePoints},
......
...@@ -63,20 +63,20 @@ public class ProcrustesAnalysisComparison { ...@@ -63,20 +63,20 @@ public class ProcrustesAnalysisComparison {
// System.out.println("Working Directory = " + System.getProperty("user.dir")); // System.out.println("Working Directory = " + System.getProperty("user.dir"));
// HEADS from the new models // HEADS from the new models
// List<FeaturePoint> fpList01 = featurePointImportService.importFeaturePoints(
// FP_FILE_DIRECTORY.toString(), FP_HEAD_01);
// List<FeaturePoint> fpList02 = featurePointImportService.importFeaturePoints(
// FP_FILE_DIRECTORY.toString(), FP_HEAD_02);
// HumanFace face1 = factory.getFace(factory.loadFace(fru.getFileFromResource(FACE_1_PATH.toString())));
// HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(FACE_2_PATH.toString())));
// 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(), 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(), FP_HEAD_02);
HumanFace face1 = factory.getFace(factory.loadFace(fru.getFileFromResource(OLD_HEAD_01_PATH.toString()))); HumanFace face1 = factory.getFace(factory.loadFace(fru.getFileFromResource(FACE_1_PATH.toString())));
HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(OLD_HEAD_02_PATH.toString()))); HumanFace face2 = factory.getFace(factory.loadFace(fru.getFileFromResource(FACE_2_PATH.toString())));
// HEADS from the old models
// List<FeaturePoint> fpList01 = featurePointImportService.importFeaturePoints(
// FP_FILE_DIRECTORY.toString(), OLD_FP_HEAD_01);
// List<FeaturePoint> fpList02 = featurePointImportService.importFeaturePoints(
// FP_FILE_DIRECTORY.toString(), OLD_FP_HEAD_02);
// 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())));
face1.setFeaturePoints(fpList01); face1.setFeaturePoints(fpList01);
face2.setFeaturePoints(fpList02); face2.setFeaturePoints(fpList02);
......
...@@ -17,6 +17,7 @@ import java.util.HashMap; ...@@ -17,6 +17,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
/** /**
* Holds important face attributes that are required for procrustes analysis.
* *
* @author Jakub Kolman * @author Jakub Kolman
*/ */
...@@ -29,7 +30,6 @@ public class ProcrustesAnalysisFaceModel { ...@@ -29,7 +30,6 @@ public class ProcrustesAnalysisFaceModel {
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; 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
...@@ -43,9 +43,15 @@ public class ProcrustesAnalysisFaceModel { ...@@ -43,9 +43,15 @@ 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 = createVerticesMatrix(face.getMeshModel().getFacets().get(0).getVertices()); this.verticesMatrix = ProcrustesAnalysisUtils.createMatrixFromList(modifiableVertices);
// this.featurePointMatrix = ProcrustesAnalysisUtils.createMatrixFromList(modifiableFeaturePointList);
} }
/**
* sets feature points map and also sets feature point on human face for visualisation
*
* @param featurePointsMap
*/
public void setFeaturePointsMap(HashMap<Integer, FeaturePoint> featurePointsMap) { public void setFeaturePointsMap(HashMap<Integer, FeaturePoint> featurePointsMap) {
this.featurePointsMap = featurePointsMap; this.featurePointsMap = featurePointsMap;
this.humanFace.setFeaturePoints(getFeaturePointValues()); this.humanFace.setFeaturePoints(getFeaturePointValues());
...@@ -68,6 +74,11 @@ public class ProcrustesAnalysisFaceModel { ...@@ -68,6 +74,11 @@ public class ProcrustesAnalysisFaceModel {
return featurePointsMap; return featurePointsMap;
} }
/**
* sets vertices map and also sets feature point on human face for visualisation
*
* @param verticesMatrix
*/
public void setVerticesMatrix(SimpleMatrix verticesMatrix) { public void setVerticesMatrix(SimpleMatrix verticesMatrix) {
this.verticesMatrix = verticesMatrix; this.verticesMatrix = verticesMatrix;
changeVerticesValues(verticesMatrix); changeVerticesValues(verticesMatrix);
...@@ -87,25 +98,12 @@ public class ProcrustesAnalysisFaceModel { ...@@ -87,25 +98,12 @@ public class ProcrustesAnalysisFaceModel {
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 (int i = 0; i < featurePointList.size(); i++) {
// map.put(i, featurePointList.get(i));
// }
for (FeaturePoint fp: featurePointList) { for (FeaturePoint fp: featurePointList) {
map.put(fp.getFeaturePointType().getType(), fp); map.put(fp.getFeaturePointType().getType(), fp);
} }
return map; 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;
} }
...@@ -127,8 +125,4 @@ public class ProcrustesAnalysisFaceModel { ...@@ -127,8 +125,4 @@ public class ProcrustesAnalysisFaceModel {
return map; return map;
} }
// public List<FeaturePoint> getFeaturePoints() {
// return new List<FeaturePoint>(this.featurePointsMap.values());
// }
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package cz.fidentis.analyst.procrustes.utils; package cz.fidentis.analyst.procrustes.utils;
import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.FeaturePoint;
import cz.fidentis.analyst.feature.api.IPosition;
import cz.fidentis.analyst.feature.provider.FeaturePointTypeProvider; import cz.fidentis.analyst.feature.provider.FeaturePointTypeProvider;
import cz.fidentis.analyst.mesh.core.MeshPoint; import cz.fidentis.analyst.mesh.core.MeshPoint;
import cz.fidentis.analyst.procrustes.ProcrustesAnalysisFaceModel; import cz.fidentis.analyst.procrustes.ProcrustesAnalysisFaceModel;
...@@ -136,16 +137,15 @@ public class ProcrustesAnalysisUtils { ...@@ -136,16 +137,15 @@ public class ProcrustesAnalysisUtils {
/** /**
* Creates matrix from given feature point list * Creates matrix from given feature point list
* *
* @param featurePointList * @param list
* @return matrix * @return matrix
*/ */
public static SimpleMatrix createFeaturePointMatrix(List<FeaturePoint> featurePointList) { public static <T extends IPosition> SimpleMatrix createMatrixFromList(List<T> list) {
SimpleMatrix matrix = new SimpleMatrix(featurePointList.size(), 3); SimpleMatrix matrix = new SimpleMatrix(list.size(), 3);
for (int i = 0; i < list.size(); i++) {
for (int i = 0; i < featurePointList.size(); i++) { matrix.set(i, 0, list.get(i).getPosition().x);
matrix.set(i, 0, featurePointList.get(i).getX()); matrix.set(i, 1, list.get(i).getPosition().y);
matrix.set(i, 1, featurePointList.get(i).getY()); matrix.set(i, 2, list.get(i).getPosition().z);
matrix.set(i, 2, featurePointList.get(i).getZ());
} }
return matrix; return matrix;
} }
...@@ -174,26 +174,6 @@ public class ProcrustesAnalysisUtils { ...@@ -174,26 +174,6 @@ public class ProcrustesAnalysisUtils {
return map; return map;
} }
/**
* Rotates vertex by using matrix multiplication of rotation matrix and vertex position.
*
* @param v
* @param matrix
* @return rotetedVertex coordinates [x, y, z]
*/
public static Point3d rotateVertex(MeshPoint v, SimpleMatrix matrix) {
float x = (float) ((v.getPosition().x * matrix.getIndex(0, 0))
+ (v.getPosition().y * matrix.getIndex(1, 0))
+ (v.getPosition().z * matrix.getIndex(2, 0)));
float y = (float) ((v.getPosition().x * matrix.getIndex(0, 1))
+ (v.getPosition().y * matrix.getIndex(1, 1))
+ (v.getPosition().z * matrix.getIndex(2, 1)));
float z = (float) ((v.getPosition().x * matrix.getIndex(0, 2))
+ (v.getPosition().y * matrix.getIndex(1, 2))
+ (v.getPosition().z * matrix.getIndex(2, 2)));
Point3d rotatedVertex = new Point3d(x, y, z);
return rotatedVertex;
}
public static float countSize(Point3d point, HashMap<Integer, FeaturePoint> featurePointsMap) { public static float countSize(Point3d point, HashMap<Integer, FeaturePoint> featurePointsMap) {
float size = 0; float size = 0;
......
package cz.fidentis.analyst.feature; package cz.fidentis.analyst.feature;
import cz.fidentis.analyst.feature.api.IPosition;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import javax.vecmath.Point3d; import javax.vecmath.Point3d;
...@@ -8,7 +10,7 @@ import javax.vecmath.Point3d; ...@@ -8,7 +10,7 @@ import javax.vecmath.Point3d;
* *
* @author Jakub Kolman * @author Jakub Kolman
*/ */
public class FeaturePoint implements Serializable { public class FeaturePoint implements IPosition, Serializable {
private Point3d position; private Point3d position;
private final FeaturePointType featurePointType; private final FeaturePointType featurePointType;
...@@ -30,18 +32,6 @@ public class FeaturePoint implements Serializable { ...@@ -30,18 +32,6 @@ public class FeaturePoint implements Serializable {
return position; return position;
} }
public double getX() {
return position.x;
}
public double getY() {
return position.y;
}
public double getZ() {
return position.z;
}
public FeaturePointType getFeaturePointType() { public FeaturePointType getFeaturePointType() {
return featurePointType; return featurePointType;
} }
......
/*
* 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.feature.api;
import javax.vecmath.Point3d;
/**
*
* @author Jakub Kolman
*/
public interface IPosition {
Point3d getPosition();
default double getX() {
return getPosition().x;
}
default double getY() {
return getPosition().y;
}
default double getZ() {
return getPosition().z;
}
}
\ No newline at end of file
...@@ -190,11 +190,8 @@ public class MeshFacetImpl implements MeshFacet { ...@@ -190,11 +190,8 @@ public class MeshFacetImpl implements MeshFacet {
public Iterator<MeshTriangle> iterator() { public Iterator<MeshTriangle> iterator() {
return new Iterator<MeshTriangle>() { return new Iterator<MeshTriangle>() {
private int index; private int index;
/**
*
* @param facet Mesh facet to iterate
*/
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return index < cornerTable.getSize(); return index < cornerTable.getSize();
......
package cz.fidentis.analyst.mesh.core; package cz.fidentis.analyst.mesh.core;
import cz.fidentis.analyst.feature.api.IPosition;
import java.io.Serializable; import java.io.Serializable;
import javax.vecmath.Point3d; import javax.vecmath.Point3d;
import javax.vecmath.Vector3d; import javax.vecmath.Vector3d;
...@@ -9,7 +11,7 @@ import javax.vecmath.Vector3d; ...@@ -9,7 +11,7 @@ import javax.vecmath.Vector3d;
* *
* @author Matej Lukes * @author Matej Lukes
*/ */
public interface MeshPoint extends Serializable { public interface MeshPoint extends IPosition, Serializable {
/** /**
* Helper method that calculates distance of two 3D points. * Helper method that calculates distance of two 3D points.
......
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