1 /*
2 * Copyright (C) 2015 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.ar.epipolar;
17
18 import com.irurueta.algebra.AlgebraException;
19 import com.irurueta.algebra.Utils;
20 import com.irurueta.geometry.GeometryException;
21 import com.irurueta.geometry.estimators.LockedException;
22 import com.irurueta.geometry.estimators.NotReadyException;
23
24 /**
25 * Compares two fundamental matrices using a pure algebraic difference to
26 * determine how similar they are.
27 * This class simply computes the norm of the difference of both fundamental
28 * matrices. The smaller the value the more similar the fundamental matrices
29 * will be from a pure algebraic point of view.
30 * It must be notice that although there is a tendency to be more similar
31 * as the algebraic distance decreases, the value returned by this
32 * implementation has no geometric meaning at all.
33 */
34 public class AlgebraicFundamentalMatrixComparator extends FundamentalMatrixComparator {
35
36 /**
37 * Constructor.
38 */
39 public AlgebraicFundamentalMatrixComparator() {
40 super();
41 }
42
43 /**
44 * Constructor.
45 *
46 * @param groundTruthFundamentalMatrix fundamental matrix to be considered
47 * as ground truth to compare against.
48 * @param otherFundamentalMatrix other fundamental matrix being compared.
49 */
50 public AlgebraicFundamentalMatrixComparator(
51 final FundamentalMatrix groundTruthFundamentalMatrix, final FundamentalMatrix otherFundamentalMatrix) {
52 super(groundTruthFundamentalMatrix, otherFundamentalMatrix);
53 }
54
55 /**
56 * Constructor.
57 *
58 * @param listener listener to handle events generated by this class.
59 */
60 public AlgebraicFundamentalMatrixComparator(final FundamentalMatrixComparatorListener listener) {
61 super(listener);
62 }
63
64 /**
65 * Constructor.
66 *
67 * @param groundTruthFundamentalMatrix fundamental matrix to be considered
68 * as ground truth to compare against.
69 * @param otherFundamentalMatrix other fundamental matrix being compared.
70 * @param listener listener to handle events generated by this class.
71 */
72 public AlgebraicFundamentalMatrixComparator(
73 final FundamentalMatrix groundTruthFundamentalMatrix, final FundamentalMatrix otherFundamentalMatrix,
74 final FundamentalMatrixComparatorListener listener) {
75 super(groundTruthFundamentalMatrix, otherFundamentalMatrix, listener);
76 }
77
78 /**
79 * Compares two fundamental matrices and returns the comparison value.
80 * Comparison value will depend on the method implemented to compare both
81 * fundamental matrices.
82 *
83 * @return comparison value. Typically, the smaller the absolute value the
84 * more similar the fundamental matrices are.
85 * @throws NotReadyException if this comparator is not yet ready to start
86 * the comparison.
87 * @throws LockedException if this instance is locked.
88 * @throws FundamentalMatrixComparatorException if comparison fails due to
89 * some other reason.
90 */
91 @Override
92 public double compare() throws NotReadyException, LockedException, FundamentalMatrixComparatorException {
93 if (isLocked()) {
94 throw new LockedException();
95 }
96 if (!isReady()) {
97 throw new NotReadyException();
98 }
99
100 try {
101 locked = true;
102
103 if (listener != null) {
104 listener.onCompareStart(this);
105 }
106
107 groundTruthFundamentalMatrix.normalize();
108 otherFundamentalMatrix.normalize();
109
110 final var f1 = groundTruthFundamentalMatrix.getInternalMatrix();
111 final var f2 = otherFundamentalMatrix.getInternalMatrix();
112
113 final var diff = f1.subtractAndReturnNew(f2);
114 final var sum = f1.addAndReturnNew(f2);
115
116 var normDiff = Utils.normF(diff);
117 var normSum = Utils.normF(sum);
118
119 if (normDiff > 1.0) {
120 normDiff = 2.0 - normDiff;
121 }
122 if (normSum > 1.0) {
123 normSum = 2.0 - normSum;
124 }
125
126 if (listener != null) {
127 listener.onCompareEnd(this);
128 }
129
130 return Math.min(normDiff, normSum);
131
132 } catch (final AlgebraException | GeometryException e) {
133 throw new FundamentalMatrixComparatorException(e);
134 } finally {
135 locked = false;
136 }
137 }
138
139 /**
140 * Returns type of comparator
141 *
142 * @return type of comparator
143 */
144 @Override
145 public FundamentalMatrixComparatorType getType() {
146 return FundamentalMatrixComparatorType.ALGEBRAIC_COMPARATOR;
147 }
148 }