SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
AppDemoVideo.cpp File Reference

All video capturing and video tracking functions are in here. More...

#include <AppDemoSceneView.h>
#include <AppCommon.h>
#include <AppDemoSceneID.h>
#include <SLScene.h>
#include <SLSceneView.h>
#include <CVCapture.h>
#include <CVTracked.h>
#include <CVTrackedAruco.h>
#include <SLGLTexture.h>
#include <CVCalibrationEstimator.h>
#include <GlobalTimer.h>
#include <Profiler.h>
#include <FtpUtils.h>
Include dependency graph for AppDemoVideo.cpp:

Go to the source code of this file.

Functions

void updateTrackingSceneCamera (CVCamera *ac)
 
void runCalibrationEstimator (CVCamera *ac, SLScene *s, SLSceneView *sv)
 
void ensureValidCalibration (CVCamera *ac, SLSceneView *sv)
 logic that ensures that we have a valid calibration state More...
 
bool onUpdateVideo ()
 Implements the update per frame for video update and feature tracking. More...
 

Variables

SLGLTexturegVideoTexture = nullptr
 
CVTrackedgVideoTracker = nullptr
 
SLNodegVideoTrackedNode = nullptr
 

Detailed Description

All video capturing and video tracking functions are in here.

Date
August 2019
Authors
Marcus Hudritsch
Remarks
Please use clangformat to format the code. See more code style on https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style

Definition in file AppDemoVideo.cpp.

Function Documentation

◆ ensureValidCalibration()

void ensureValidCalibration ( CVCamera ac,
SLSceneView sv 
)

logic that ensures that we have a valid calibration state

Definition at line 173 of file AppDemoVideo.cpp.

174 {
176 
177  // we have to make sure calibration process is stopped if someone stops calibrating
179  {
182  }
183 
184  if (ac->calibration.state() == CS_uncalibrated)
185  {
186  // Try to read device lens and sensor information
187  string strF = AppCommon::deviceParameter["DeviceLensFocalLength"];
188  string strW = AppCommon::deviceParameter["DeviceSensorPhysicalSizeW"];
189  string strH = AppCommon::deviceParameter["DeviceSensorPhysicalSizeH"];
190  if (!strF.empty() && !strW.empty() && !strH.empty())
191  {
192  float devF = strF.empty() ? 0.0f : stof(strF);
193  float devW = strW.empty() ? 0.0f : stof(strW);
194  float devH = strH.empty() ? 0.0f : stof(strH);
195 
196  // Changes the state to CS_guessed
197  ac->calibration = CVCalibration(devW,
198  devH,
199  devF,
200  cv::Size(CVCapture::instance()->lastFrame.cols,
202  ac->mirrorH(),
203  ac->mirrorV(),
204  ac->type(),
206  }
207  else
208  {
209  // make a guess using frame size and a guessed field of view
210  ac->calibration = CVCalibration(cv::Size(CVCapture::instance()->lastFrame.cols,
212  60.0,
213  ac->mirrorH(),
214  ac->mirrorV(),
215  ac->type(),
217  }
218  }
219 }
@ CS_uncalibrated
The camera is not calibrated (no calibration found)
Definition: CVCalibration.h:32
#define PROFILE_FUNCTION()
Definition: Instrumentor.h:41
static CVCalibrationEstimator * calibrationEstimator
Definition: AppCommon.h:107
static map< string, string > deviceParameter
Generic device parameter.
Definition: AppCommon.h:101
Live video camera calibration class with OpenCV an OpenCV calibration.
Definition: CVCalibration.h:71
CVCalibState state() const
bool mirrorH()
Definition: CVCamera.h:22
CVCalibration calibration
Definition: CVCamera.h:36
CVCameraType type()
Definition: CVCamera.h:24
bool mirrorV()
Definition: CVCamera.h:23
CVMat lastFrame
last frame grabbed in BGR
Definition: CVCapture.h:119
static CVCapture * instance()
Public static instance getter for singleton pattern.
Definition: CVCapture.h:65
static std::string get()
Definition: Utils.cpp:1261

◆ onUpdateVideo()

bool onUpdateVideo ( )

Implements the update per frame for video update and feature tracking.

This routine is called once per frame before any other update within the the main rendering loop (see: AppDemoMainGLFW::onPaint or GLES3View::onDrawFrame). See the documentation within SLCVTracked and in all of its inheritants.

Definition at line 226 of file AppDemoVideo.cpp.

227 {
229 
230  if (AppCommon::sceneViews.empty())
231  return false;
232 
235 
236  if (CVCapture::instance()->videoType() != VT_NONE &&
237  !CVCapture::instance()->lastFrame.empty())
238  {
239  SLfloat trackingTimeStartMS = GlobalTimer::timeMS();
240 
242 
245  {
247  }
248  else
249  {
251  // Attention: Always update scene camera fovV from calibration because the calibration may have
252  // been adapted in adjustForSL after a change of aspect ratio!
253  // The active scene view camera may be a different one that the tracking camera
254  // but we have to update the tracking camera only!
256 
258  {
259  bool foundPose = gVideoTracker->track(CVCapture::instance()->lastFrameGray,
260  CVCapture::instance()->lastFrame,
261  &ac->calibration);
262  if (foundPose)
263  {
264  // clang-format off
265  // convert matrix type CVMatx44f to SLMat4f
267  SLMat4f glOVM(cvOVM.val[0], cvOVM.val[1], cvOVM.val[2], cvOVM.val[3],
268  cvOVM.val[4], cvOVM.val[5], cvOVM.val[6], cvOVM.val[7],
269  cvOVM.val[8], cvOVM.val[9], cvOVM.val[10],cvOVM.val[11],
270  cvOVM.val[12],cvOVM.val[13],cvOVM.val[14],cvOVM.val[15]);
271  // clang-format on
272 
273  // set the object matrix depending if the
274  // tracked node is attached to a camera or not
275  if (typeid(*gVideoTrackedNode) == typeid(SLCamera))
276  {
277  gVideoTrackedNode->om(glOVM.inverted());
279  }
280  else
281  {
282  // see comments in CVTracked::calcObjectMatrix
283  gVideoTrackedNode->om(sv->camera()->om() * glOVM);
285  }
286  }
287  else
289  }
290 
291  // Update info text only for chessboard scene
296  {
297  SLfloat fovH = ac->calibration.cameraFovHDeg();
299  stringstream ss; // info line text
300  ss << "Tracking Chessboard on " << (CVCapture::instance()->videoType() == VT_MAIN ? "main " : "scnd. ") << "camera. ";
301  if (ac->calibration.state() == CS_calibrated)
302  ss << "FOVH: " << fovH << ", error: " << err;
303  else
304  ss << "Not calibrated. FOVH guessed: " << fovH << " degrees.";
305  s->info(ss.str());
306  }
307  }
308 
309  //...................................................................
310  // copy image to video texture
311  if (gVideoTexture)
312  {
313  if (ac->calibration.state() == CS_calibrated && ac->showUndistorted())
314  {
315  CVMat undistorted;
316  ac->calibration.remap(CVCapture::instance()->lastFrame, undistorted);
317 
318  // CVCapture::instance()->gVideoTexture()->copyVideoImage(undistorted.cols,
319  gVideoTexture->copyVideoImage(undistorted.cols,
320  undistorted.rows,
322  undistorted.data,
323  undistorted.isContinuous(),
324  true);
325  }
326  else
327  {
328  // CVCapture::instance()->gVideoTexture()->copyVideoImage(CVCapture::instance()->lastFrame.cols,
333  CVCapture::instance()->lastFrame.isContinuous(),
334  true);
335  }
336  }
337  else
338  SL_WARN_MSG("No video texture to copy to.");
339 
340 #ifndef SL_EMSCRIPTEN
341  CVTracked::trackingTimesMS.set(GlobalTimer::timeMS() - trackingTimeStartMS);
342 #endif
343 
344  return true;
345  }
346 
347  return false;
348 }
@ SID_VideoTrackChessScnd
@ SID_VideoCalibrateScnd
@ SID_VideoCalibrateMain
@ SID_VideoTrackChessMain
SLNode * gVideoTrackedNode
SLGLTexture * gVideoTexture
void ensureValidCalibration(CVCamera *ac, SLSceneView *sv)
logic that ensures that we have a valid calibration state
void updateTrackingSceneCamera(CVCamera *ac)
CVTracked * gVideoTracker
void runCalibrationEstimator(CVCamera *ac, SLScene *s, SLSceneView *sv)
@ CS_calibrated
The camera is calibrated.
Definition: CVCalibration.h:33
@ VT_NONE
No camera needed.
Definition: CVCapture.h:41
@ VT_MAIN
Main camera on all on all all devices.
Definition: CVCapture.h:42
cv::Matx44f CVMatx44f
Definition: CVTypedefs.h:59
cv::Mat CVMat
Definition: CVTypedefs.h:38
float SLfloat
Definition: SL.h:173
#define SL_WARN_MSG(message)
Definition: SL.h:241
#define SL_DB_HIDDEN
Flags an object as hidden.
Definition: SLDrawBits.h:20
static SLVSceneView sceneViews
Vector of sceneview pointers.
Definition: AppCommon.h:62
static SLSceneID sceneID
ID of currently loaded scene.
Definition: AppCommon.h:89
static SLScene * scene
Pointer to the one and only SLScene instance.
Definition: AppCommon.h:61
void remap(CVMat &inDistorted, CVMat &outUndistorted)
Undistorts the inDistorted image into the outUndistorted.
float reprojectionError() const
float cameraFovHDeg() const
void showUndistorted(bool su)
Definition: CVCamera.h:25
CVCamera * activeCamera
Pointer to the active camera.
Definition: CVCapture.h:136
CVPixelFormatGL format
GL pixel format.
Definition: CVCapture.h:122
void videoType(CVVideoType vt)
Setter for video type also sets the active calibration.
Definition: CVCapture.cpp:866
static AvgFloat trackingTimesMS
Averaged time for video tracking in ms.
Definition: CVTracked.h:82
virtual bool track(CVMat imageGray, CVMat imageBgr, CVCalibration *calib)=0
CVMatx44f objectViewMat()
Definition: CVTracked.h:65
static float timeMS()
Definition: GlobalTimer.cpp:25
Active or visible camera node class.
Definition: SLCamera.h:54
SLbool copyVideoImage(SLint camWidth, SLint camHeight, CVPixelFormatGL glFormat, SLuchar *data, SLbool isContinuous, SLbool isTopLeft)
Copies the image data from a video camera into the current video image.
void om(const SLMat4f &mat)
Definition: SLNode.h:276
void setDrawBitsRec(SLuint bit, SLbool state)
Definition: SLNode.cpp:804
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
void info(SLstring i)
Definition: SLScene.h:93
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
void camera(SLCamera *camera)
Definition: SLSceneView.h:145
void set(T value)
Sets the current value in the value array and builds the average.
Definition: Averaged.h:53

◆ runCalibrationEstimator()

void runCalibrationEstimator ( CVCamera ac,
SLScene s,
SLSceneView sv 
)

Definition at line 62 of file AppDemoVideo.cpp.

63 {
65 
66  AppDemoSceneView* adSv = dynamic_cast<AppDemoSceneView*>(sv);
67  static bool processedCalibResult = false;
68  try
69  {
71  {
73  CVCapture::instance()->activeCamSizeIndex,
74  ac->mirrorH(),
75  ac->mirrorV(),
76  ac->type(),
81 
82  // clear grab request from sceneview
83  adSv->grab = false;
84  processedCalibResult = false;
85  }
86 
87  if (AppCommon::calibrationEstimator->isStreaming())
88  {
90  CVCapture::instance()->lastFrameGray,
91  adSv->grab);
92  // reset grabbing switch
93  adSv->grab = false;
94 
95  stringstream ss;
96  ss << "Click on the screen to create a calibration photo. Created "
99  s->info(ss.str());
100  }
101  else if (AppCommon::calibrationEstimator->isBusyExtracting())
102  {
103  // also reset grabbing, user has to click again
104  adSv->grab = false;
106  CVCapture::instance()->lastFrameGray,
107  false);
108  s->info("Busy extracting corners, please wait with grabbing ...");
109  }
110  else if (AppCommon::calibrationEstimator->isCalculating())
111  {
113  CVCapture::instance()->lastFrameGray,
114  false);
115  s->info("Calculating calibration, please wait ...");
116  }
117  else if (AppCommon::calibrationEstimator->isDone())
118  {
119  if (!processedCalibResult)
120  {
121  if (AppCommon::calibrationEstimator->calibrationSuccessful())
122  {
123  processedCalibResult = true;
125 
126  std::string computerInfo = Utils::ComputerInfos::get();
127  string mainCalibFilename = "camCalib_" + computerInfo + "_main.xml";
128  string scndCalibFilename = "camCalib_" + computerInfo + "_scnd.xml";
129  std::string errorMsg;
130  if (ac->calibration.save(AppCommon::calibFilePath, mainCalibFilename))
131  {
132 
133 #ifndef SL_EMSCRIPTEN
135  mainCalibFilename,
140  errorMsg))
141  {
142  Utils::log("WAIApp", errorMsg.c_str());
143  }
144 #endif
145  }
146  else
147  {
148  errorMsg += " Saving calibration failed!";
149  }
150 
151  s->info("Calibration successful." + errorMsg);
152  }
153  else
154  {
155  s->info(("Calibration failed!"));
156  }
157  }
158  }
159  else if (AppCommon::calibrationEstimator->isDoneCaptureAndSave())
160  {
161  s->info(("Capturing done!"));
162  }
163  }
165  {
166  log("SLProject", e.what());
167  s->info("Exception during calibration! Please restart!");
168  }
169 }
SLSceneView * sv
Definition: SLGLImGui.h:28
static const string CALIB_FTP_HOST
ftp host for calibration up and download
Definition: AppCommon.h:114
static const string CALIB_FTP_USER
ftp login user for calibration up and download
Definition: AppCommon.h:115
static const string CALIB_FTP_DIR
ftp directory for calibration up and download
Definition: AppCommon.h:117
static SLstring calibIniPath
That's where data/calibrations folder is located.
Definition: AppCommon.h:108
static SLstring exePath
executable root path
Definition: AppCommon.h:80
static const string CALIB_FTP_PWD
ftp login pwd for calibration up and download
Definition: AppCommon.h:116
static CVCalibrationEstimatorParams calibrationEstimatorParams
Definition: AppCommon.h:106
static SLstring externalPath
Default path for external file storage.
Definition: AppCommon.h:82
static SLstring calibFilePath
That's where calibrations are stored and loaded from.
Definition: AppCommon.h:109
special exception that informs about errors during calibration process
CVCalibration getCalibration()
Get resulting calibration.
bool updateAndDecorate(CVMat imageColor, const CVMat &imageGray, bool grabFrame, bool drawCorners=true)
< Finds the inner chessboard corners in the given image
bool save(const string &calibDir, const string &calibFileName)
Saves the camera calibration parameters to the config file.
bool uploadFile(const string &fileDir, const string &fileName, const string &ftpHost, const string &ftpUser, const string &ftpPwd, const string &ftpDir, string &errorMsg)
Uploads file to the ftp server.
Definition: FtpUtils.cpp:198
void errorMsg(const char *tag, const char *msg, const int line, const char *file)
Platform independent error message output.
Definition: Utils.cpp:1168
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103

◆ updateTrackingSceneCamera()

void updateTrackingSceneCamera ( CVCamera ac)

always update scene camera fovV from calibration because the calibration may have been adapted in adjustForSL after a change of aspect ratio! Attention: The active scene view camera may be a different one that the tracking camera but we have to update the tracking camera only!

Definition at line 50 of file AppDemoVideo.cpp.

51 {
53 
54  if (gVideoTrackedNode && typeid(*gVideoTrackedNode) == typeid(SLCamera))
55  {
56  SLCamera* trackingCam = dynamic_cast<SLCamera*>(gVideoTrackedNode);
57  trackingCam->fov(ac->calibration.cameraFovVDeg());
58  }
59 }
float cameraFovVDeg() const
void fov(const SLfloat fov)
vertical field of view
Definition: SLCamera.h:98

Variable Documentation

◆ gVideoTexture

SLGLTexture* gVideoTexture = nullptr

Global pointer for the video texture defined in AppDemoLoad for video scenes It gets updated in the following onUpdateTracking routine

Definition at line 32 of file AppDemoVideo.cpp.

◆ gVideoTrackedNode

SLNode* gVideoTrackedNode = nullptr

Global pointer to a node that from witch the gVideoTracker changes the pose. it gets updated in the following onUpdateTracking routine

Definition at line 42 of file AppDemoVideo.cpp.

◆ gVideoTracker

CVTracked* gVideoTracker = nullptr

Global pointer for a gVideoTracker that is set in AppDemoLoad for video scenes It gets updated in the following onUpdateTracking routine

Definition at line 37 of file AppDemoVideo.cpp.