View Javadoc
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 }