@Override public FaceAligner<KEDetectedFace> getAligner() { return new MeshWarpAligner(); }
protected FImage getWarpedImage(FacialKeypoint[] kpts, FImage patch, Matrix tf0) { final FacialKeypoint[] det = getActualPoints(kpts, tf0); final List<Pair<Shape>> mesh = createMesh(det); final FImage newpatch = patch.process(new PiecewiseMeshWarp<Float, FImage>(mesh)); return newpatch; }
protected List<Pair<Shape>> createMesh(FacialKeypoint[] det) { final List<Pair<Shape>> shapes = new ArrayList<Pair<Shape>>(); for (final String[] vertDefs : meshDefinition) { final Polygon p1 = new Polygon(); final Polygon p2 = new Polygon(); for (final String v : vertDefs) { p1.getVertices().add(lookupVertex(v, det)); p2.getVertices().add(lookupVertex(v, canonical)); } shapes.add(new Pair<Shape>(p1, p2)); } return shapes; }
/** * Construct with the given mesh definition * * @param meshDefinition * The mesh definition */ public MeshWarpAligner(String[][] meshDefinition) { this.meshDefinition = meshDefinition; final List<Pair<Shape>> mesh = createMesh(canonical); // build mask by mapping the canonical coords to themselves on a white // image mask = new FImage((int) P2.getX(), (int) P2.getY()); mask.fill(1f); mask = mask.processInplace(new PiecewiseMeshWarp<Float, FImage>(mesh)); }
@Override public FImage align(KEDetectedFace descriptor) { final float scalingX = P2.getX() / descriptor.getFacePatch().width; final float scalingY = P2.getY() / descriptor.getFacePatch().height; final Matrix tf0 = TransformUtilities.scaleMatrix(scalingX, scalingY); final Matrix tf = tf0.inverse(); final FImage J = FKEFaceDetector.pyramidResize(descriptor.getFacePatch(), tf); final FImage smallpatch = FKEFaceDetector.extractPatch(J, tf, 80, 0); return getWarpedImage(descriptor.getKeypoints(), smallpatch, tf0); }
@Override public FaceAligner<KEDetectedFace> getAligner() { return new MeshWarpAligner(); }