use of org.ejml.data.Complex_F64 in project BoofCV by lessthanoptimal.
the class FundamentalLinear7 method computeSolutions.
/**
* <p>
* Find the polynomial roots and for each root compute the Fundamental matrix.
* Given the two matrices it will compute an alpha such that the determinant is zero.<br>
*
* det(&alpha*F1 + (1-α)*F2 ) = 0
* </p>
*/
public void computeSolutions(FastQueue<DMatrixRMaj> solutions) {
if (!rootFinder.process(poly))
return;
List<Complex_F64> zeros = rootFinder.getRoots();
for (Complex_F64 c : zeros) {
if (!c.isReal() && Math.abs(c.imaginary) > 1e-10)
continue;
DMatrixRMaj F = solutions.grow();
double a = c.real;
double b = 1 - c.real;
for (int i = 0; i < 9; i++) {
F.data[i] = a * F1.data[i] + b * F2.data[i];
}
// that the first two singular values are zero and the last one is zero
if (!computeFundamental && !projectOntoEssential(F)) {
solutions.removeTail();
}
}
}
use of org.ejml.data.Complex_F64 in project BoofCV by lessthanoptimal.
the class TestDiscreteFourierTransformOps method multiplyRealComplex.
public void multiplyRealComplex(ImageGray realA, ImageInterleaved complexB, ImageInterleaved complexC) {
if (complexB instanceof InterleavedF32)
DiscreteFourierTransformOps.multiplyRealComplex((GrayF32) realA, (InterleavedF32) complexB, (InterleavedF32) complexC);
else
DiscreteFourierTransformOps.multiplyRealComplex((GrayF64) realA, (InterleavedF64) complexB, (InterleavedF64) complexC);
Complex_F64 expected = new Complex_F64();
for (int y = 0; y < realA.height; y++) {
for (int x = 0; x < realA.width; x++) {
Complex_F64 a = new Complex_F64(get(realA, x, y), 0);
Complex_F64 b = new Complex_F64(get(complexB, x, y, 0), get(complexB, x, y, 1));
ComplexMath_F64.multiply(a, b, expected);
assertEquals(expected.getReal(), get(complexC, x, y, 0), 1e-4);
assertEquals(expected.getImaginary(), get(complexC, x, y, 1), 1e-4);
}
}
}
use of org.ejml.data.Complex_F64 in project BoofCV by lessthanoptimal.
the class TestCirculantTracker method elementMultConjB.
@Test
public void elementMultConjB() {
InterleavedF64 a = new InterleavedF64(width, height, 2);
InterleavedF64 b = new InterleavedF64(width, height, 2);
InterleavedF64 c = new InterleavedF64(width, height, 2);
ImageMiscOps.fillUniform(a, rand, -10, 10);
ImageMiscOps.fillUniform(b, rand, -10, 10);
ImageMiscOps.fillUniform(c, rand, -10, 10);
CirculantTracker.elementMultConjB(a, b, c);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Complex_F64 aa = new Complex_F64(a.getBand(x, y, 0), a.getBand(x, y, 1));
Complex_F64 bb = new Complex_F64(b.getBand(x, y, 0), b.getBand(x, y, 1));
Complex_F64 cc = new Complex_F64();
ComplexMath_F64.conj(bb, bb);
ComplexMath_F64.multiply(aa, bb, cc);
double foundReal = c.getBand(x, y, 0);
double foundImg = c.getBand(x, y, 1);
assertEquals(cc.real, foundReal, 1e-4);
assertEquals(cc.imaginary, foundImg, 1e-4);
}
}
}
use of org.ejml.data.Complex_F64 in project BoofCV by lessthanoptimal.
the class P3PFinsterwalder method process.
/**
* @inheritDoc
*/
public boolean process(Point2D_F64 obs1, Point2D_F64 obs2, Point2D_F64 obs3, double length23, double length13, double length12) {
solutions.reset();
// cos(gama)
cos12 = computeCosine(obs1, obs2);
// cos(beta)
cos13 = computeCosine(obs1, obs3);
// cos(alpha)
cos23 = computeCosine(obs2, obs3);
double a = length23, b = length13, c = length12;
double a2_d_b2 = (a / b) * (a / b);
double c2_d_b2 = (c / b) * (c / b);
a2 = a * a;
b2 = b * b;
c2 = c * c;
// poly.c[0] = a2*(a2*pow2(sin13) - b2*pow2(sin23));
// poly.c[1] = b2*(b2-c2)*pow2(sin23) + a2*(a2 + 2*c2)*pow2(sin13) + 2*a2*b2*(-1 + cos23*cos13*cos12);
// poly.c[2] = b2*(b2-a2)*pow2(sin12) + c2*(c2 + 2*a2)*pow2(sin13) + 2*b2*c2*(-1 + cos23*cos13*cos12);
// poly.c[3] = c2*(c2*pow2(sin13) - b2*pow2(sin12) );
// Auto generated code + hand simplification. See P3PFinsterwalder.py I prefer it over the equations found
// in the paper (commented out above) since it does not require sin(theta).
poly.c[0] = a2 * (a2 * (1 - pow2(cos13)) + b2 * (pow2(cos23) - 1));
poly.c[1] = 2 * a2 * b2 * (cos12 * cos13 * cos23 - 1) + a2 * (a2 + 2 * c2) * (1 - pow2(cos13)) + b2 * (b2 - c2) * (1 - pow2(cos23));
poly.c[2] = 2 * c2 * b2 * (cos12 * cos13 * cos23 - 1) + c2 * (c2 + 2 * a2) * (1 - pow2(cos13)) + b2 * (b2 - a2) * (1 - pow2(cos12));
poly.c[3] = c2 * (b2 * (pow2(cos12) - 1) + c2 * (1 - pow2(cos13)));
if (poly.computeDegree() < 0)
return false;
if (!rootFinder.process(poly))
return false;
// search for real roots
Complex_F64 root = null;
for (Complex_F64 r : rootFinder.getRoots()) {
if (r.isReal()) {
root = r;
break;
}
}
if (root == null)
return false;
double lambda = root.real;
double A = 1 + lambda;
double B = -cos23;
double C = 1 - a2_d_b2 - lambda * c2_d_b2;
double D = -lambda * cos12;
double E = (a2_d_b2 + lambda * c2_d_b2) * cos13;
double F = -a2_d_b2 + lambda * (1 - c2_d_b2);
p = Math.sqrt(B * B - A * C);
q = Math.signum(B * E - C * D) * Math.sqrt(E * E - C * F);
computeU((-B + p) / C, (-E + q) / C);
computeU((-B - p) / C, (-E - q) / C);
return true;
}
use of org.ejml.data.Complex_F64 in project BoofCV by lessthanoptimal.
the class P3PGrunert method process.
/**
* @inheritDoc
*/
@Override
public boolean process(Point2D_F64 obs1, Point2D_F64 obs2, Point2D_F64 obs3, double length23, double length13, double length12) {
double cos12 = computeCosine(obs1, obs2);
double cos13 = computeCosine(obs1, obs3);
double cos23 = computeCosine(obs2, obs3);
double a = length23, b = length13, c = length12;
// divide out numbers before multiplying them. less overflow/underflow that way
double a2_div_b2 = (a / b) * (a / b);
double c2_div_b2 = (c / b) * (c / b);
double a2_m_c2_div_b2 = a2_div_b2 - c2_div_b2;
double a2_p_c2_div_b2 = a2_div_b2 + c2_div_b2;
poly.c[0] = -4 * a2_div_b2 * pow2(cos12) + pow2(a2_m_c2_div_b2 + 1);
poly.c[1] = 4 * (-a2_m_c2_div_b2 * (1 + a2_m_c2_div_b2) * cos13 + 2 * a2_div_b2 * pow2(cos12) * cos13 - (1 - a2_p_c2_div_b2) * cos23 * cos12);
poly.c[2] = 2 * (pow2(a2_m_c2_div_b2) - 1 + 2 * pow2(a2_m_c2_div_b2) * pow2(cos13) + 2 * (1 - c2_div_b2) * pow2(cos23) - 4 * a2_p_c2_div_b2 * cos12 * cos13 * cos23 + 2 * (1 - a2_div_b2) * pow2(cos12));
poly.c[3] = 4 * (a2_m_c2_div_b2 * (1 - a2_m_c2_div_b2) * cos13 - (1 - a2_p_c2_div_b2) * cos23 * cos12 + 2 * c2_div_b2 * pow2(cos23) * cos13);
poly.c[4] = -4 * c2_div_b2 * cos23 * cos23 + pow2(a2_m_c2_div_b2 - 1);
// solve for real roots
solutions.reset();
if (!rootFinder.process(poly))
return false;
List<Complex_F64> roots = rootFinder.getRoots();
for (Complex_F64 r : roots) {
if (!r.isReal()) {
continue;
}
double v = r.real;
double u = ((-1 + a2_div_b2 - c2_div_b2) * v * v - 2 * (a2_div_b2 - c2_div_b2) * cos13 * v + 1 + a2_div_b2 - c2_div_b2) / (2 * (cos12 - v * cos23));
// compute the distance of each point
PointDistance3 s = solutions.grow();
s.dist1 = Math.sqrt(a * a / (u * u + v * v - 2 * u * v * cos23));
s.dist2 = s.dist1 * u;
s.dist3 = s.dist1 * v;
}
return solutions.size() != 0;
}
Aggregations