/* * Copyright Inria and Bordeaux University. * Author Jeremy Laviole. jeremy.laviole@inria.fr * PapAR project is the open-source version of the * PapARt project. License is LGPLv3, distributed with the sources. * This project can also distributed with standard commercial * licence for closed-sources projects. */ package fr.inria.papart.calibration; import java.io.FileNotFoundException; import processing.core.PApplet; import processing.core.PMatrix3D; import processing.core.PVector; import processing.data.XML; import toxi.geom.Matrix4x4; import toxi.geom.ReadonlyVec3D; import toxi.geom.Vec3D; /** * * @author Jeremy Laviole <jeremy.laviole@inria.fr> */ public class HomographyCalibration extends Calibration { static final String HOMOGRAPHY_XML_NAME = "Homography"; protected Matrix4x4 mat; protected PMatrix3D pmatrix; protected PMatrix3D invPmatrix; public void setMatrix(PMatrix3D inputMatrix) { checkAndCreateMatrix(inputMatrix); this.initMat(); } private void checkAndCreateMatrix(PMatrix3D inputMatrix) { if (this.pmatrix == null) { this.pmatrix = inputMatrix.get(); } else { this.pmatrix.set(inputMatrix); } } private void initMat() { float[] valuesFloat = new float[16]; double[] valuesDouble = new double[16]; pmatrix.get(valuesFloat); for (int i = 0; i < valuesFloat.length; i++) { valuesDouble[i] = (double) valuesFloat[i]; } mat = new Matrix4x4(valuesDouble); invPmatrix = pmatrix.get(); invPmatrix.invert(); } public Vec3D applyTo(ReadonlyVec3D src) { return this.mat.applyTo(src); } public PVector applyTo(PVector src) { PVector out = new PVector(); this.pmatrix.mult(src, out); return out; } @Override public void addTo(XML xml) { XML homographyNode = new XML(HOMOGRAPHY_XML_NAME); setHomographyTo(homographyNode); xml.addChild(homographyNode); } @Override public void replaceIn(XML xml) { XML homographyNode = xml.getChild(HOMOGRAPHY_XML_NAME); setHomographyTo(homographyNode); } private void setHomographyTo(XML xml) { xml.setFloat("m00", pmatrix.m00); xml.setFloat("m01", pmatrix.m01); xml.setFloat("m02", pmatrix.m02); xml.setFloat("m03", pmatrix.m03); xml.setFloat("m10", pmatrix.m10); xml.setFloat("m11", pmatrix.m11); xml.setFloat("m12", pmatrix.m12); xml.setFloat("m13", pmatrix.m13); xml.setFloat("m20", pmatrix.m20); xml.setFloat("m21", pmatrix.m21); xml.setFloat("m22", pmatrix.m22); xml.setFloat("m23", pmatrix.m23); xml.setFloat("m30", pmatrix.m30); xml.setFloat("m31", pmatrix.m31); xml.setFloat("m32", pmatrix.m32); xml.setFloat("m33", pmatrix.m33); } @Override public void loadFrom(PApplet parent, String fileName) { XML root = parent.loadXML(fileName); XML homographyNode = root.getChild(HOMOGRAPHY_XML_NAME); pmatrix = new PMatrix3D(); pmatrix.m00 = homographyNode.getFloat("m00"); pmatrix.m01 = homographyNode.getFloat("m01"); pmatrix.m02 = homographyNode.getFloat("m02"); pmatrix.m03 = homographyNode.getFloat("m03"); pmatrix.m10 = homographyNode.getFloat("m10"); pmatrix.m11 = homographyNode.getFloat("m11"); pmatrix.m12 = homographyNode.getFloat("m12"); pmatrix.m13 = homographyNode.getFloat("m13"); pmatrix.m20 = homographyNode.getFloat("m20"); pmatrix.m21 = homographyNode.getFloat("m21"); pmatrix.m22 = homographyNode.getFloat("m22"); pmatrix.m23 = homographyNode.getFloat("m23"); pmatrix.m30 = homographyNode.getFloat("m30"); pmatrix.m31 = homographyNode.getFloat("m31"); pmatrix.m32 = homographyNode.getFloat("m32"); pmatrix.m33 = homographyNode.getFloat("m33"); initMat(); } @Override public boolean isValid() { return this.pmatrix != null; } @Deprecated public Matrix4x4 getHomographyMat4x4() { return mat; } public PMatrix3D getHomography() { return this.pmatrix; } public PMatrix3D getHomographyInv() { return this.invPmatrix; } @Override public String toString() { return this.mat.toString(); } public static void saveMatTo(PApplet applet, PMatrix3D mat, String fileName) { HomographyCalibration hc = new HomographyCalibration(); hc.setMatrix(mat); hc.saveTo(applet, fileName); } public static PMatrix3D getMatFrom(PApplet applet, String fileName) { HomographyCalibration hc = new HomographyCalibration(); hc.loadFrom(applet, fileName); return hc.getHomography(); } public static HomographyCalibration CreateHomographyCalibrationFrom(PMatrix3D mat, PVector size) { float step = 0.5f; int nbPoints = (int) ((1 + 1f / step) * (1 + 1f / step)); HomographyCreator homographyCreator = new HomographyCreator(3, 2, nbPoints); for (float i = 0; i <= 1.0; i += step) { for (float j = 0; j <= 1.0; j += step) { mat.translate(-i * size.x, -j * size.y); homographyCreator.addPoint(new PVector(mat.m03, mat.m13, mat.m23), new PVector(i, j)); mat.translate(i * size.x, j * size.y); } } assert (homographyCreator.isComputed()); return homographyCreator.getHomography(); } }