SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SENSWebCamera.cpp
Go to the documentation of this file.
1 #include "SENSWebCamera.h"
2 #include <SENSException.h>
3 #include <SENSUtils.h>
4 #include <Utils.h>
5 
6 #define LOG_WEBCAM_WARN(...) Utils::log("SENSWebCamera", __VA_ARGS__);
7 //#define LOG_WEBCAM_INFO(...) Utils::log("SENSWebCamera", __VA_ARGS__);
8 //#define LOG_WEBCAM_DEBUG(...) Utils::log("SENSWebCamera", __VA_ARGS__);
9 //#define LOG_WEBCAM_WARN
10 #define LOG_WEBCAM_INFO
11 #define LOG_WEBCAM_DEBUG
12 
13 const SENSCameraConfig& SENSWebCamera::start(std::string deviceId,
14  const SENSCameraStreamConfig& streamConfig,
15  bool provideIntrinsics)
16 {
17  if (_started)
18  {
19  Utils::warnMsg("SENSWebCamera", "Call to start was ignored. Camera is currently running!", __LINE__, __FILE__);
20  return _config;
21  }
22 
23  //retrieve all camera characteristics
24  if (_captureProperties.size() == 0)
26 
27  if (_captureProperties.size() == 0)
28  throw SENSException(SENSType::CAM, "Could not retrieve camera properties!", __LINE__, __FILE__);
29 
30  if (!_captureProperties.containsDeviceId(deviceId))
31  throw SENSException(SENSType::CAM, "DeviceId does not exist!", __LINE__, __FILE__);
32 
33  int id = std::stoi(deviceId);
34  _videoCapture.open(id);
35 
36  if (!_videoCapture.isOpened())
37  throw SENSException(SENSType::CAM, "Could not open camera with id: " + deviceId, __LINE__, __FILE__);
38 
39  _videoCapture.set(cv::CAP_PROP_FRAME_WIDTH, streamConfig.widthPix);
40  _videoCapture.set(cv::CAP_PROP_FRAME_HEIGHT, streamConfig.heightPix);
41  _started = true;
42  _permissionGranted = true;
43 
44  //init config here
45  _config = SENSCameraConfig(deviceId,
46  streamConfig,
49 
50  processStart();
51 
52  //start thread
53  _cameraThread = std::thread(&SENSWebCamera::grab, this);
54 
55  return _config;
56 }
57 
59 {
60  _stop = true;
61  if (_cameraThread.joinable())
62  _cameraThread.join();
63  _stop = false;
64 
65  if (_videoCapture.isOpened())
66  {
67  _videoCapture.release();
68 
69  _started = false;
70  }
71  else
72  {
73  LOG_WEBCAM_INFO("stop: ignored because camera is not open!");
74  }
75 }
76 
78 {
79  while (!_stop)
80  {
81  cv::Mat bgrImg;
82  if (_videoCapture.read(bgrImg))
83  {
84  if (bgrImg.cols == _config.streamConfig.widthPix &&
85  bgrImg.rows == _config.streamConfig.heightPix)
86  updateFrame(bgrImg, cv::Mat(), false, bgrImg.rows, bgrImg.cols);
87  else
88  LOG_WEBCAM_WARN("video capture delivers wrong resolution!");
89  }
90  }
91 }
92 
94 {
95  if (!_captureProperties.size())
96  {
97  //definition of standard frame sizes that we want to test for support
98  static std::vector<cv::Size> testSizes = {
99  {640, 480},
100  {640, 360},
101  {960, 540},
102  {1280, 960},
103  {1280, 720},
104  {1920, 1080}};
105 
106  //There is an invisible list of devices populated from your os and your webcams appear there in the order you plugged them in.
107  //If you're e.g on a laptop with a builtin camera, that will be id 0, if you plug in an additional one, that's id 1.
108  for (int i = 0; i < 10; ++i)
109  {
110  _videoCapture.open(i);
111 
112  if (_videoCapture.isOpened())
113  {
114  SENSCameraDeviceProps characteristics(std::to_string(i), SENSCameraFacing::UNKNOWN);
115 
116  //try some standard capture sizes
117  for (auto s : testSizes)
118  {
119  _videoCapture.set(cv::CAP_PROP_FRAME_WIDTH, s.width);
120  _videoCapture.set(cv::CAP_PROP_FRAME_HEIGHT, s.height);
121  cv::Mat frame;
122  _videoCapture >> frame;
123  cv::Size newSize = frame.size();
124  if (!characteristics.contains(newSize) &&
125  newSize != cv::Size(0, 0))
126  {
127  //-1 means unknown focal length
128  characteristics.add(newSize.width, newSize.height, -1.f);
129  }
130  }
131 
132  _captureProperties.push_back(characteristics);
133  _videoCapture.release();
134  }
135  }
136 
137  //if still no caputure properties add a dummy
138  if (_captureProperties.size() == 0)
139  {
141  dummyProps.add(640, 480, -1.f);
142  _captureProperties.push_back(dummyProps);
143  }
144  }
145 
146  return _captureProperties;
147 }
#define LOG_WEBCAM_INFO
#define LOG_WEBCAM_WARN(...)
SENSCameraConfig _config
indicates what is currently running
Definition: SENSCamera.h:218
std::atomic< bool > _permissionGranted
Definition: SENSCamera.h:219
SENSCaptureProps _captureProperties
Definition: SENSCamera.h:216
std::atomic< bool > _started
flags if camera was started
Definition: SENSCamera.h:217
void updateFrame(cv::Mat bgrImg, cv::Mat intrinsics, int width, int height, bool intrinsicsChanged)
Definition: SENSCamera.cpp:220
void processStart()
call from start function to do startup preprocessing
Definition: SENSCamera.cpp:294
bool contains(cv::Size toFind)
Definition: SENSCamera.h:88
void add(int widthPix, int heightPix, float focalLengthPix)
Definition: SENSCamera.h:97
bool containsDeviceId(const std::string &deviceId) const
Definition: SENSCamera.cpp:61
void stop() override
Stop a started camera device.
std::atomic_bool _stop
Definition: SENSWebCamera.h:32
cv::VideoCapture _videoCapture
Definition: SENSWebCamera.h:30
const SENSCameraConfig & start(std::string deviceId, const SENSCameraStreamConfig &streamConfig, bool provideIntrinsics=true) override
const SENSCaptureProps & captureProperties() override
Get SENSCaptureProps which contains necessary information about all available camera devices and thei...
std::thread _cameraThread
Definition: SENSWebCamera.h:33
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
void warnMsg(const char *tag, const char *msg, const int line, const char *file)
Platform independent warn message output.
Definition: Utils.cpp:1142
SENSCameraStreamConfig streamConfig
currently selected stream config index (use it to look up original capture size)
Definition: SENSCamera.h:131