@Override public void encode(CalibratedPoseAndPoint model, double[] param) { int paramIndex = 0; // first decode the transformation for (int i = 0; i < numViews; i++) { // don't encode if it is already known if (knownView[i]) continue; Se3_F64 se = model.getWorldToCamera(i); // force the "rotation matrix" to be an exact rotation matrix // otherwise Rodrigues will have issues with the noise if (!svd.decompose(se.getR())) throw new RuntimeException("SVD failed"); DenseMatrix64F U = svd.getU(null, false); DenseMatrix64F V = svd.getV(null, false); CommonOps.multTransB(U, V, R); // extract Rodrigues coordinates RotationMatrixGenerator.matrixToRodrigues(R, rotation); param[paramIndex++] = rotation.unitAxisRotation.x * rotation.theta; param[paramIndex++] = rotation.unitAxisRotation.y * rotation.theta; param[paramIndex++] = rotation.unitAxisRotation.z * rotation.theta; Vector3D_F64 T = se.getT(); param[paramIndex++] = T.x; param[paramIndex++] = T.y; param[paramIndex++] = T.z; } for (int i = 0; i < numPoints; i++) { Point3D_F64 p = model.getPoint(i); param[paramIndex++] = p.x; param[paramIndex++] = p.y; param[paramIndex++] = p.z; } }
/** * Computes a basis (the principle components) from the most dominant eigenvectors. * * @param numComponents Number of vectors it will use to describe the data. Typically much smaller * than the number of elements in the input vector. */ public void computeBasis(int numComponents) { if (numComponents > A.getNumCols()) throw new IllegalArgumentException("More components requested that the data's length."); if (sampleIndex != A.getNumRows()) throw new IllegalArgumentException("Not all the data has been added"); if (numComponents > sampleIndex) throw new IllegalArgumentException( "More data needed to compute the desired number of components"); this.numComponents = numComponents; // compute the mean of all the samples for (int i = 0; i < A.getNumRows(); i++) { for (int j = 0; j < mean.length; j++) { mean[j] += A.get(i, j); } } for (int j = 0; j < mean.length; j++) { mean[j] /= A.getNumRows(); } // subtract the mean from the original data for (int i = 0; i < A.getNumRows(); i++) { for (int j = 0; j < mean.length; j++) { A.set(i, j, A.get(i, j) - mean[j]); } } // Compute SVD and save time by not computing U SingularValueDecomposition<DenseMatrix64F> svd = DecompositionFactory.svd(A.numRows, A.numCols, false, true, false); if (!svd.decompose(A)) throw new RuntimeException("SVD failed"); V_t = svd.getV(null, true); DenseMatrix64F W = svd.getW(null); // Singular values are in an arbitrary order initially SingularOps.descendingOrder(null, false, W, V_t, true); // strip off unneeded components and find the basis V_t.reshape(numComponents, mean.length, true); }