AlgebraicFundamentalMatrixComparator.java
/*
* Copyright (C) 2015 Alberto Irurueta Carro (alberto@irurueta.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.irurueta.ar.epipolar;
import com.irurueta.algebra.AlgebraException;
import com.irurueta.algebra.Utils;
import com.irurueta.geometry.GeometryException;
import com.irurueta.geometry.estimators.LockedException;
import com.irurueta.geometry.estimators.NotReadyException;
/**
* Compares two fundamental matrices using a pure algebraic difference to
* determine how similar they are.
* This class simply computes the norm of the difference of both fundamental
* matrices. The smaller the value the more similar the fundamental matrices
* will be from a pure algebraic point of view.
* It must be notice that although there is a tendency to be more similar
* as the algebraic distance decreases, the value returned by this
* implementation has no geometric meaning at all.
*/
public class AlgebraicFundamentalMatrixComparator extends FundamentalMatrixComparator {
/**
* Constructor.
*/
public AlgebraicFundamentalMatrixComparator() {
super();
}
/**
* Constructor.
*
* @param groundTruthFundamentalMatrix fundamental matrix to be considered
* as ground truth to compare against.
* @param otherFundamentalMatrix other fundamental matrix being compared.
*/
public AlgebraicFundamentalMatrixComparator(
final FundamentalMatrix groundTruthFundamentalMatrix, final FundamentalMatrix otherFundamentalMatrix) {
super(groundTruthFundamentalMatrix, otherFundamentalMatrix);
}
/**
* Constructor.
*
* @param listener listener to handle events generated by this class.
*/
public AlgebraicFundamentalMatrixComparator(final FundamentalMatrixComparatorListener listener) {
super(listener);
}
/**
* Constructor.
*
* @param groundTruthFundamentalMatrix fundamental matrix to be considered
* as ground truth to compare against.
* @param otherFundamentalMatrix other fundamental matrix being compared.
* @param listener listener to handle events generated by this class.
*/
public AlgebraicFundamentalMatrixComparator(
final FundamentalMatrix groundTruthFundamentalMatrix, final FundamentalMatrix otherFundamentalMatrix,
final FundamentalMatrixComparatorListener listener) {
super(groundTruthFundamentalMatrix, otherFundamentalMatrix, listener);
}
/**
* Compares two fundamental matrices and returns the comparison value.
* Comparison value will depend on the method implemented to compare both
* fundamental matrices.
*
* @return comparison value. Typically, the smaller the absolute value the
* more similar the fundamental matrices are.
* @throws NotReadyException if this comparator is not yet ready to start
* the comparison.
* @throws LockedException if this instance is locked.
* @throws FundamentalMatrixComparatorException if comparison fails due to
* some other reason.
*/
@Override
public double compare() throws NotReadyException, LockedException, FundamentalMatrixComparatorException {
if (isLocked()) {
throw new LockedException();
}
if (!isReady()) {
throw new NotReadyException();
}
try {
locked = true;
if (listener != null) {
listener.onCompareStart(this);
}
groundTruthFundamentalMatrix.normalize();
otherFundamentalMatrix.normalize();
final var f1 = groundTruthFundamentalMatrix.getInternalMatrix();
final var f2 = otherFundamentalMatrix.getInternalMatrix();
final var diff = f1.subtractAndReturnNew(f2);
final var sum = f1.addAndReturnNew(f2);
var normDiff = Utils.normF(diff);
var normSum = Utils.normF(sum);
if (normDiff > 1.0) {
normDiff = 2.0 - normDiff;
}
if (normSum > 1.0) {
normSum = 2.0 - normSum;
}
if (listener != null) {
listener.onCompareEnd(this);
}
return Math.min(normDiff, normSum);
} catch (final AlgebraException | GeometryException e) {
throw new FundamentalMatrixComparatorException(e);
} finally {
locked = false;
}
}
/**
* Returns type of comparator
*
* @return type of comparator
*/
@Override
public FundamentalMatrixComparatorType getType() {
return FundamentalMatrixComparatorType.ALGEBRAIC_COMPARATOR;
}
}