forked from midjji/pnp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
p4p.cpp
69 lines (47 loc) · 1.72 KB
/
p4p.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <limits>
#include "p4p.h"
#include <lambdatwist/lambdatwist.p3p.h>
using std::cout;using std::endl;
namespace cvl{
PoseD p4p(const std::vector<cvl::Vector3D>& xs,
const std::vector<cvl::Vector2D>& yns,
Vector4<uint> indexes)
{
assert(xs.size()==yns.size());
assert(indexes.size()==4);
assert(([&]() -> bool{for(uint i:indexes) if (i>=xs.size()) return false; return true;})());
Vector<cvl::Matrix<double,3,3>,4> Rs;
Vector<Vector3<double>,4> Ts;
int valid = p3p_lambdatwist<double,5>(
yns[indexes[0]].homogeneous(),yns[indexes[1]].homogeneous(),yns[indexes[2]].homogeneous(),
xs[ indexes[0]],xs[ indexes[1]],xs[ indexes[2]],
Rs,Ts);
// pick the minimum, whatever it is
Vector2d y=yns[indexes[3]];
Vector3d x=xs[indexes[3]];
PoseD P=PoseD(); // identity
double e0=std::numeric_limits<double>::max();
for(int v=0;v<valid;++v)
{
// the lambdatwist rotations have a problem some Rs not quite beeing rotations... ???
// this is extremely uncommon, except when you have very particular kinds of noise,
// this gets caught by the benchmark somehow?
// it never occurs for the correct solution, only ever for possible alternatives.
// investigate numerical problem later...
Vector4d q=getRotationQuaternion(Rs[v]);
q.normalize();
PoseD tmp(q,Ts[v]);
if(!tmp.isnormal()) continue;
Vector3d xr=tmp*x;
if(xr[2]<0) continue;
double e=(xr.dehom()-y).squaredNorm();
if (std::isnan(e)) continue;
if (e<e0 ){
P=tmp;
e0=e;
}
}
return P;
}
}// end namespace cvl