OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
com_osvr_VideoCapture_OpenCV.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
29 
30 #include "com_osvr_VideoCapture_OpenCV_json.h"
31 
32 // Library/third-party includes
33 #include <opencv2/core/core.hpp> // for basic OpenCV types
34 #include <opencv2/core/operations.hpp>
35 
36 #include <opencv2/core/version.hpp>
37 #if CV_MAJOR_VERSION == 2 || CV_VERSION_EPOCH == 2
38 #include <opencv2/highgui/highgui.hpp> // for image capture
39 #else
40 #include <opencv2/videoio.hpp> // for image capture
41 #endif
42 
43 #include <boost/noncopyable.hpp>
44 #include <boost/lexical_cast.hpp>
45 
46 // Standard includes
47 #include <iostream>
48 #include <sstream>
49 
50 namespace {
51 
52 OSVR_MessageType cameraMessage;
53 
54 class CameraDevice : boost::noncopyable {
55  public:
56  CameraDevice(OSVR_PluginRegContext ctx, int cameraNum = 0, int channel = 0)
57  : m_camera(cameraNum), m_channel(channel) {
58 
61 
64  m_imaging = osvr::pluginkit::ImagingInterface(opts);
65 
67  std::ostringstream os;
68  os << "Camera" << cameraNum << "_" << m_channel;
69 
71  m_dev.initAsync(ctx, os.str(), opts);
72  // Puts an object in m_dev that knows it's a
73  // threaded device so osvrDeviceSendData knows
74  // that it needs to get a connection lock first.
75 
77  m_dev.sendJsonDescriptor(
78  osvr::util::makeString(com_osvr_VideoCapture_OpenCV_json));
79 
81  m_dev.registerUpdateCallback(this);
82  }
83 
84  OSVR_ReturnCode update() {
85  if (!m_camera.isOpened()) {
86  // Couldn't open the camera. Failing silently for now. Maybe the
87  // camera will be plugged back in later.
88  return OSVR_RETURN_SUCCESS;
89  }
90 
91  // Get a timestamp for the upcoming camera grab.
92  auto frameTime = osvr::util::time::getNow();
93 
94  // Trigger a camera grab.
95  bool grabbed = m_camera.grab();
96 
97  if (!grabbed) {
98  // No frame available.
99  return OSVR_RETURN_SUCCESS;
100  }
101  bool retrieved = m_camera.retrieve(m_frame, m_channel);
102  if (!retrieved) {
103  return OSVR_RETURN_FAILURE;
104  }
105 
106  // Send the image.
107  // Note that if larger than 160x120 (RGB), will used shared memory
108  // backend only.
109  m_dev.send(m_imaging, osvr::pluginkit::ImagingMessage(m_frame),
110  frameTime);
111 
112  return OSVR_RETURN_SUCCESS;
113  }
114 
115  private:
118  cv::VideoCapture m_camera;
119  int m_channel;
120  cv::Mat m_frame;
121 };
122 
123 class CameraDetection {
124  public:
125  CameraDetection() : m_found(false) {}
126 
127  OSVR_ReturnCode operator()(OSVR_PluginRegContext ctx) {
128  if (m_found) {
129  return OSVR_RETURN_SUCCESS;
130  }
131 
132  {
133  // Autodetect camera
134  cv::VideoCapture cap(0);
135  if (!cap.isOpened()) {
136  // Failed to find camera
137  return OSVR_RETURN_FAILURE;
138  }
139  }
140 
141  m_found = true;
142 
145  osvr::pluginkit::registerObjectForDeletion(ctx, new CameraDevice(ctx));
146 
147  return OSVR_RETURN_SUCCESS;
148  }
149 
150  private:
151  bool m_found;
152 };
153 
154 } // end anonymous namespace
155 
156 OSVR_PLUGIN(com_osvr_VideoCapture_OpenCV) {
157  osvr::pluginkit::PluginContext context(ctx);
158 
159  context.registerHardwareDetectCallback(new CameraDetection());
160 
161  return OSVR_RETURN_SUCCESS;
162 }
Wrapper class for OSVR_DeviceToken.
void getNow(TimeValue &tv)
Set the given TimeValue to the current time.
Definition: TimeValue.h:51
std::string makeString(const char(&arrayLiteral)[N])
Safely and easily convert a literal array of characters (like from osvr_json_to_c) into a std::string...
A class wrapping a cv::Mat representing a frame, as well as the sensor ID it corresponds to...
C++ wrapper class for the opaque plugin context.
Definition: PluginKit.h:59
Structure used internally to construct the desired type of device.
Header with a convenience function to make a std::string out of a non-null-terminated char array (str...
A class wrapping an imaging interface for a device.
Base class for connection-specific message type registration.
Definition: MessageType.h:38
#define OSVR_RETURN_FAILURE
The "failure" value for an OSVR_ReturnCode.
Definition: ReturnCodesC.h:47
T * registerObjectForDeletion(OSVR_PluginRegContext ctx, T *obj)
Registers an object to be destroyed with delete when the plugin is unloaded.
#define OSVR_RETURN_SUCCESS
The "success" value for an OSVR_ReturnCode.
Definition: ReturnCodesC.h:45
OSVR_DeviceInitOptions osvrDeviceCreateInitOptions(OSVR_PluginRegContext ctx)
Create a OSVR_DeviceInitOptions object.
Header including the full PluginKit C++ interface.
#define OSVR_PLUGIN(PLUGIN_NAME)
This macro begins the entry point function of your plugin.
OSVR_EXTERN_C_BEGIN typedef void * OSVR_PluginRegContext
A context pointer passed in to your plugin's entry point and other locations of control flow transfer...