SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
CVTracked.cpp
Go to the documentation of this file.
1 /**
2  * \file CVTracked.cpp
3  * \date Winter 2016
4  * \remarks Please use clangformat to format the code. See more code style on
5  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
6  * \authors Marcus Hudritsch, Michael Goettlicher
7  * \copyright http://opensource.org/licenses/GPL-3.0
8 */
9 
10 /*
11 The OpenCV library version 3.4 or above with extra module must be present.
12 If the application captures the live video stream with OpenCV you have
13 to define in addition the constant APP_USES_CVCAPTURE.
14 All classes that use OpenCV begin with CV.
15 See also the class docs for CVCapture, CVCalibration and CVTracked
16 for a good top down information.
17 */
18 
19 #include <CVTracked.h>
20 
21 //-----------------------------------------------------------------------------
22 // Static declarations
30 //-----------------------------------------------------------------------------
32 {
33  // Reset all timing variables
38  CVTracked::matchTimesMS.init(60, 0.0f);
40  CVTracked::poseTimesMS.init(60, 0.0f);
41 }
42 //-----------------------------------------------------------------------------
43 // clang-format off
44 //-----------------------------------------------------------------------------
45 //! Create an OpenGL 4x4 matrix from an OpenCV translation & rotation vector
47 {
48  // 1) convert the passed rotation vector to a rotation matrix
49  CVMat rMat;
50  Rodrigues(rVec, rMat);
51 
52  // 2) Create an OpenGL 4x4 column major matrix from the rotation matrix and
53  // translation vector from openCV as described in this post:
54  // www.morethantechnical.com/2015/02/17/
55  // augmented-reality-on-libqglviewer-and-opencv-opengl-tips-wcode
56 
57  // The y- and z- axis have to be inverted:
58  /*
59  tVec = | t0, t1, t2 |
60  | r00 r01 r02 t0 |
61  | r00, r10, r20 | | -r10 -r11 -r12 -t1 |
62  rMat = | r01, r11, r21 | glMat = | -r20 -r21 -r22 -t2 |
63  | r02, r12, r22 | | 0 0 0 1 |
64  */
65 
66  CVMatx44f glM((float) rMat.at<double>(0, 0), (float) rMat.at<double>(0, 1), (float) rMat.at<double>(0, 2), (float) tVec.at<double>(0, 0),
67  (float)-rMat.at<double>(1, 0), (float)-rMat.at<double>(1, 1), (float)-rMat.at<double>(1, 2), (float)-tVec.at<double>(1, 0),
68  (float)-rMat.at<double>(2, 0), (float)-rMat.at<double>(2, 1), (float)-rMat.at<double>(2, 2), (float)-tVec.at<double>(2, 0),
69  0.0f, 0.0f, 0.0f, 1.0f);
70  return glM;
71 }
72 //-----------------------------------------------------------------------------
73 //! Creates the OpenCV rvec & tvec vectors from an column major OpenGL 4x4 matrix
74 void CVTracked::createRvecTvec(const CVMatx44f& glMat, CVMat& tVec, CVMat& rVec)
75 {
76  // The y- and z- axis have to be inverted:
77  /*
78  tVec = | t0, t1, t2 |
79  | r00 r01 r02 t0 |
80  | r00, r10, r20 | | -r10 -r11 -r12 -t1 |
81  rMat = | r01, r11, r21 | glMat = | -r20 -r21 -r22 -t2 |
82  | r02, r12, r22 | | 0 0 0 1 |
83  */
84 
85  // 1) Create cv rotation matrix from OpenGL rotation matrix
86  CVMatx33f rMat(glMat.val[0], -glMat.val[1], -glMat.val[2],
87  glMat.val[4], -glMat.val[5], -glMat.val[6],
88  glMat.val[8], -glMat.val[9], -glMat.val[10]);
89 
90  // 2) Convert rotation matrix to Rodrigues rotation vector
91  Rodrigues(rMat, rVec);
92 
93  // 3) Create tvec vector from translation components
94  tVec.at<double>(0, 0) = glMat.val[3];
95  tVec.at<double>(1, 0) = -glMat.val[7];
96  tVec.at<double>(2, 0) = -glMat.val[11];
97 }
98 //-----------------------------------------------------------------------------
99 /*! Calculates the object matrix from the cameraObject and the object view matrix.
100 <br>
101 Nomenclature:
102 T = homogenous transformation matrix
103 <br>
104 <sup>a</sup>T<sub>b</sub> = homogenous transformation matrix with subscript b and superscript a
105 <br>
106 Subscrips and superscripts: w = world; o = object; c = camera
107 <br>
108 <sup>c</sup>T<sub>o</sub> = Transformation of object with respect to camera coordinate system.
109 It describes the position of an object in the camera coordinate system.
110 We get this transformation from OpenCVs solvePNP function.
111 <br>
112 <sup>w</sup>T<sub>c</sub> = (<sup>c</sup>T<sub>w</sub>)<sup>-1</sup> = Transformation of camera with respect to world coord.-system.
113 Inversion exchanges sub- and superscript.
114 <br>
115 The inverse of the camera to world matrix is the view matrix or camera matrix.
116 <br>
117 We can combine two or more homogenous transformations to a new one if the
118 inner sub- and superscript fit together. The resulting transformation
119 inherits the superscript from the left and the subscript from the right
120 transformation. The following transformation is what we want to do:
121 <br>
122 <sup>w</sup>T<sub>o</sub> = <sup>w</sup>T<sub>c</sub> * <sup>c</sup>T<sub>o</sub> =
123 Transformation of object with respect to world coordinate system (object matrix)
124 */
126  const CVMatx44f& objectViewMat)
127 {
128  // new object matrix = camera object matrix * object-view matrix
129  return cameraObjectMat * objectViewMat;
130 }
131 //-----------------------------------------------------------------------------
132 // clang-format on
133 //-----------------------------------------------------------------------------
134 CVVec3f CVTracked::averageVector(vector<CVVec3f> vectors,
135  vector<float> weights)
136 {
137  if (vectors.size() == 1)
138  return vectors[0];
139 
140  CVVec3f total;
141  float totalWeights = 0.0f;
142 
143  for (int i = 0; i < vectors.size(); i++)
144  {
145  float weight = weights[i];
146  total += vectors[i] * weight;
147  totalWeights += weight;
148  }
149 
150  return total / totalWeights;
151 }
152 //-----------------------------------------------------------------------------
153 SLQuat4f CVTracked::averageQuaternion(vector<SLQuat4f> quaternions,
154  vector<float> weights)
155 {
156  // Based on: https://math.stackexchange.com/questions/61146/averaging-quaternions
157 
158  if (quaternions.size() == 1)
159  return quaternions[0];
160 
161  SLQuat4f total(0.0f, 0.0f, 0.0f, 0.0f);
162 
163  for (int i = 0; i < quaternions.size(); i++)
164  {
165  SLQuat4f quaternion = quaternions[i];
166  float weight = weights[i];
167 
168  if (i > 0 && quaternion.dot(quaternions[0]) < 0.0)
169  weight = -weight;
170 
171  total.set(total.x() + weight * quaternion.x(),
172  total.y() + weight * quaternion.y(),
173  total.z() + weight * quaternion.z(),
174  total.w() + weight * quaternion.w());
175  }
176 
177  return total.normalized();
178 }
179 //-----------------------------------------------------------------------------
cv::Matx44f CVMatx44f
Definition: CVTypedefs.h:59
cv::Matx33f CVMatx33f
Definition: CVTypedefs.h:58
cv::Vec3f CVVec3f
Definition: CVTypedefs.h:52
cv::Mat CVMat
Definition: CVTypedefs.h:38
static AvgFloat trackingTimesMS
Averaged time for video tracking in ms.
Definition: CVTracked.h:82
static AvgFloat optFlowTimesMS
Averaged time for video feature optical flow tracking in ms.
Definition: CVTracked.h:87
static void createRvecTvec(const CVMatx44f &glMat, CVMat &tVec, CVMat &rVec)
Creates the OpenCV rvec & tvec vectors from an column major OpenGL 4x4 matrix.
Definition: CVTracked.cpp:74
static AvgFloat detectTimesMS
Averaged time for video feature detection & description in ms.
Definition: CVTracked.h:83
static CVMatx44f calcObjectMatrix(const CVMatx44f &cameraObjectMat, const CVMatx44f &objectViewMat)
Definition: CVTracked.cpp:125
static cv::Matx44f createGLMatrix(const CVMat &tVec, const CVMat &rVec)
Create an OpenGL 4x4 matrix from an OpenCV translation & rotation vector.
Definition: CVTracked.cpp:46
static SLQuat4f averageQuaternion(vector< SLQuat4f > quaternions, vector< float > weights)
Definition: CVTracked.cpp:153
static AvgFloat detect1TimesMS
Averaged time for video feature detection subpart 1 in ms.
Definition: CVTracked.h:84
static void resetTimes()
Resets all static variables.
Definition: CVTracked.cpp:31
static AvgFloat detect2TimesMS
Averaged time for video feature detection subpart 2 in ms.
Definition: CVTracked.h:85
static AvgFloat matchTimesMS
Averaged time for video feature matching in ms.
Definition: CVTracked.h:86
static AvgFloat poseTimesMS
Averaged time for video feature pose estimation in ms.
Definition: CVTracked.h:88
CVMatx44f objectViewMat()
Definition: CVTracked.h:65
static CVVec3f averageVector(vector< CVVec3f > vectors, vector< float > weights)
Definition: CVTracked.cpp:134
T w() const
Definition: SLQuat4.h:39
void set(T x, T y, T z, T w)
Definition: SLQuat4.h:140
T z() const
Definition: SLQuat4.h:38
T dot(const SLQuat4< T > &q) const
Definition: SLQuat4.h:536
T y() const
Definition: SLQuat4.h:37
T x() const
Definition: SLQuat4.h:36
SLQuat4< T > normalized() const
Definition: SLQuat4.h:550
void init(int numValues, T initValue)
Initializes the average value array to a given value.
Definition: Averaged.h:41