1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.ar.calibration;
17
18 import com.irurueta.algebra.AlgebraException;
19 import com.irurueta.algebra.CholeskyDecomposer;
20 import com.irurueta.algebra.Matrix;
21 import com.irurueta.algebra.Utils;
22 import com.irurueta.geometry.Conic;
23 import com.irurueta.geometry.DualConic;
24 import com.irurueta.geometry.DualConicNotAvailableException;
25 import com.irurueta.geometry.InvalidPinholeCameraIntrinsicParametersException;
26 import com.irurueta.geometry.NonSymmetricMatrixException;
27 import com.irurueta.geometry.PinholeCameraIntrinsicParameters;
28
29 import java.io.Serializable;
30
31
32
33
34
35
36
37
38
39
40 public class ImageOfAbsoluteConic extends Conic implements Serializable {
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public ImageOfAbsoluteConic(final PinholeCameraIntrinsicParameters k)
55 throws InvalidPinholeCameraIntrinsicParametersException {
56 super();
57 setFromPinholeCameraIntrinsicParameters(k);
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71 public ImageOfAbsoluteConic(
72 final double a, final double b, final double c, final double d, final double e, final double f) {
73 super(a, b, c, d, e, f);
74 }
75
76
77
78
79
80
81
82
83
84
85
86 public ImageOfAbsoluteConic(final Matrix m) throws NonSymmetricMatrixException {
87 super(m);
88 }
89
90
91
92
93 protected ImageOfAbsoluteConic() {
94 super();
95 }
96
97
98
99
100
101
102
103
104
105
106 @Override
107 public DualConic getDualConic() throws DualConicNotAvailableException {
108 final var dualConic = new DualImageOfAbsoluteConic();
109 dualConic(dualConic);
110 return dualConic;
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124 public final void setFromPinholeCameraIntrinsicParameters(
125 final PinholeCameraIntrinsicParameters k) throws InvalidPinholeCameraIntrinsicParametersException {
126 final var kMatrix = k.getInternalMatrix();
127 try {
128 final var invKMatrix = Utils.inverse(kMatrix);
129 setParameters(invKMatrix.transposeAndReturnNew().multiplyAndReturnNew(invKMatrix));
130 } catch (final AlgebraException e) {
131 throw new InvalidPinholeCameraIntrinsicParametersException(e);
132 } catch (final NonSymmetricMatrixException ignore) {
133
134 }
135 }
136
137
138
139
140
141
142
143
144
145
146
147 public PinholeCameraIntrinsicParameters getIntrinsicParameters()
148 throws InvalidPinholeCameraIntrinsicParametersException {
149 try {
150 normalize();
151
152
153
154
155 final var b11 = getA();
156 final var b12 = getB();
157 final var b22 = getC();
158 final var b13 = getD();
159 final var b23 = getE();
160 final var b33 = getF();
161
162
163
164
165
166
167
168 final var v0 = (b12 * b13 - b11 * b23) / (b11 * b22 - b12 * b12);
169 if (Double.isNaN(v0) || Double.isInfinite(v0)) {
170 throw new InvalidPinholeCameraIntrinsicParametersException();
171 }
172
173
174
175
176 var lambda = b33 - (b13 * b13 + v0 * (b12 * b13 - b11 * b23)) / b11;
177
178 lambda *= Math.signum(lambda) * Math.signum(b11);
179
180 if (Double.isNaN(lambda) || Double.isInfinite(lambda)) {
181 throw new InvalidPinholeCameraIntrinsicParametersException();
182 }
183
184 final var alpha = Math.sqrt(lambda / b11);
185 if (Double.isNaN(alpha) || Double.isInfinite(alpha)) {
186 throw new InvalidPinholeCameraIntrinsicParametersException();
187 }
188
189 final var beta = Math.sqrt(lambda * b11 / (b11 * b22 - b12 * b12));
190 if (Double.isNaN(beta) || Double.isInfinite(beta)) {
191 throw new InvalidPinholeCameraIntrinsicParametersException();
192 }
193
194 final var gamma = -b12 * alpha * alpha * beta / lambda;
195 if (Double.isNaN(gamma) || Double.isInfinite(gamma)) {
196 throw new InvalidPinholeCameraIntrinsicParametersException();
197 }
198
199 final var u0 = gamma * v0 / beta - b13 * alpha * alpha / lambda;
200 if (Double.isNaN(u0) || Double.isInfinite(u0)) {
201 throw new InvalidPinholeCameraIntrinsicParametersException();
202 }
203
204 return new PinholeCameraIntrinsicParameters(alpha, beta, u0, v0, gamma);
205 } catch (final ArithmeticException e) {
206 throw new InvalidPinholeCameraIntrinsicParametersException(e);
207 }
208 }
209
210
211
212
213
214
215
216
217
218
219
220 public PinholeCameraIntrinsicParameters getIntrinsicParametersCholesky()
221 throws InvalidPinholeCameraIntrinsicParametersException {
222 try {
223 normalize();
224
225 final var m = asMatrix();
226 final var decomposer = new CholeskyDecomposer(m);
227 decomposer.decompose();
228 final var inverseInternalParamsMatrix = decomposer.getR();
229 final var internalParamsMatrix = com.irurueta.algebra.Utils.inverse(inverseInternalParamsMatrix);
230 return new PinholeCameraIntrinsicParameters(internalParamsMatrix);
231 } catch (final AlgebraException e) {
232 throw new InvalidPinholeCameraIntrinsicParametersException(e);
233 }
234 }
235 }