View Javadoc
1   /*
2    * Copyright (C) 2017 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.geometry.refiners;
17  
18  import com.irurueta.geometry.estimators.LockedException;
19  import com.irurueta.numerical.robust.InliersData;
20  
21  import java.util.BitSet;
22  
23  /**
24   * Refines an instance of type T by taking into account an initial estimation,
25   * inlier matches and their residuals.
26   * This class can be used to find a solution that minimizes error of inliers in
27   * LMSE terms.
28   * Typically, a refiner is used by a robust estimator, however it can also be
29   * useful in some other situations.
30   *
31   * @param <T> type of instance to be refined.
32   */
33  public abstract class InliersDataRefiner<T> extends Refiner<T> {
34      /**
35       * Array indicating which of the provided matches are inliers.
36       */
37      protected BitSet inliers;
38  
39      /**
40       * Residuals for matched data corresponding to the initial estimation.
41       * Residuals are used to determine the amount of precision of each match
42       * in order to find a refined solution that minimizes the LMSE error of all
43       * inlier matches.
44       */
45      protected double[] residuals;
46  
47      /**
48       * Number of inliers on initial estimation.
49       */
50      protected int numInliers;
51  
52      /**
53       * Constructor.
54       */
55      protected InliersDataRefiner() {
56      }
57  
58      /**
59       * Constructor.
60       *
61       * @param initialEstimation initial estimation to be set.
62       * @param keepCovariance    true if covariance of estimation must be kept after
63       *                          refinement, false otherwise.
64       * @param inliers           set indicating which of the provided matches are inliers.
65       * @param residuals         residuals for matched samples.
66       * @param numInliers        number of inliers on initial estimation.
67       */
68      protected InliersDataRefiner(final T initialEstimation, final boolean keepCovariance, final BitSet inliers,
69                                   final double[] residuals, final int numInliers) {
70          super(initialEstimation, keepCovariance);
71          this.inliers = inliers;
72          this.residuals = residuals;
73          this.numInliers = numInliers;
74      }
75  
76      /**
77       * Constructor.
78       *
79       * @param initialEstimation initial estimation to be set.
80       * @param keepCovariance    true if covariance of estimation must be kept after
81       *                          refinement, false otherwise.
82       * @param inliersData       inlier data, typically obtained from a robust
83       *                          estimator.
84       */
85      protected InliersDataRefiner(final T initialEstimation, final boolean keepCovariance,
86                                   final InliersData inliersData) {
87          super(initialEstimation, keepCovariance);
88          inliers = inliersData.getInliers();
89          residuals = inliersData.getResiduals();
90          numInliers = inliersData.getNumInliers();
91      }
92  
93      /**
94       * Gets set indicating which of the provided matches are inliers.
95       *
96       * @return set indicating which of the provided matches are inliers.
97       */
98      public BitSet getInliers() {
99          return inliers;
100     }
101 
102     /**
103      * Specifies set indicating which of the provided matches are inliers.
104      *
105      * @param inliers set indicating which of the provided matches are inliers.
106      * @throws LockedException if estimator is locked.
107      */
108     public void setInliers(final BitSet inliers) throws LockedException {
109         if (isLocked()) {
110             throw new LockedException();
111         }
112         this.inliers = inliers;
113     }
114 
115     /**
116      * Gets residuals for matched samples corresponding to the initial
117      * estimation.
118      * Residuals are used to determine the amount of precision of each matched
119      * sample in order to find a refined solution that minimizes the LMSE error
120      * of all inlier matches.
121      *
122      * @return residuals for matched samples.
123      */
124     public double[] getResiduals() {
125         return residuals;
126     }
127 
128     /**
129      * Sets residuals for matched samples corresponding to the initial
130      * estimation.
131      * Residuals are used to determine the amount of precision of each matched
132      * sample in order to find a refined solution that minimizes the LMSE error
133      * of all inlier matches.
134      *
135      * @param residuals residuals for matched samples.
136      * @throws LockedException if estimator is locked.
137      */
138     public void setResiduals(final double[] residuals) throws LockedException {
139         if (isLocked()) {
140             throw new LockedException();
141         }
142         this.residuals = residuals;
143     }
144 
145     /**
146      * Gets number of inliers on initial estimation.
147      *
148      * @return number of inliers on initial estimation.
149      */
150     public int getNumInliers() {
151         return numInliers;
152     }
153 
154     /**
155      * Sets number of inliers on initial estimation.
156      *
157      * @param numInliers number of inliers on initial estimation.
158      * @throws LockedException          if estimator is locked.
159      * @throws IllegalArgumentException if provided value is zero or negative.
160      */
161     public void setNumInliers(final int numInliers) throws LockedException {
162         if (isLocked()) {
163             throw new LockedException();
164         }
165         if (numInliers <= 0) {
166             throw new IllegalArgumentException();
167         }
168         this.numInliers = numInliers;
169     }
170 
171     /**
172      * Gets total number of provided matched samples.
173      *
174      * @return total number of provided matched samples.
175      */
176     public int getTotalSamples() {
177         return residuals != null ? residuals.length : 0;
178     }
179 
180     /**
181      * Sets inlier data.
182      *
183      * @param inliersData inlier data, typically obtained from a robust
184      *                    estimator.
185      * @throws LockedException if estimator is locked.
186      */
187     public void setInliersData(final InliersData inliersData) throws LockedException {
188         if (isLocked()) {
189             throw new LockedException();
190         }
191         inliers = inliersData.getInliers();
192         residuals = inliersData.getResiduals();
193         numInliers = inliersData.getNumInliers();
194     }
195 }