OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ViewTrackingCamera.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
28 
29 // Library/third-party includes
30 #include <opencv2/highgui/highgui.hpp>
31 
32 // Standard includes
33 #include <chrono>
34 #include <iostream>
35 #include <memory>
36 #include <sstream>
37 
38 #undef OSVR_ENABLE_RECORDING
39 
42 static const std::string windowNameAndInstructions(
43  "OSVR tracking camera preview | q or esc to quit");
44 
45 static const auto VIDEO_FILENAME = "capture.avi";
46 
47 static const auto FPS_MEASUREMENT_PERIOD = std::chrono::seconds(3);
48 class FrameCounter {
49  public:
50  FrameCounter() { reset(); }
51  void gotFrame() {
52  ++m_frames;
53  auto now = clock::now();
54  if (now >= m_end) {
55  auto duration =
56  std::chrono::duration_cast<std::chrono::duration<double>>(
57  now - m_begin);
58  std::cout << m_frames / duration.count() << " FPS read from camera"
59  << std::endl;
60  reset();
61  }
62  }
63 
64  void reset() {
65  m_begin = clock::now();
66  m_end = m_begin + FPS_MEASUREMENT_PERIOD;
67  m_frames = 0;
68  }
69 
70  private:
71  using clock = std::chrono::system_clock;
72  using time_point = std::chrono::time_point<clock>;
73  time_point m_begin;
74  time_point m_end;
75  std::size_t m_frames = 0;
76 };
77 
78 int main(int argc, char *argv[]) {
79 
80 #ifdef _WIN32
81  auto cam = osvr::vbtracker::openHDKCameraDirectShow();
82 #else
83  std::cerr << "Warning: Just using OpenCV to open Camera #0, which may not "
84  "be the tracker camera."
85  << std::endl;
86  auto cam = osvr::vbtracker::openOpenCVCamera(0);
87 #endif
88  if (!cam || !cam->ok()) {
89  std::cerr << "Couldn't find, open, or read from the OSVR HDK tracking "
90  "camera.\n"
91  << "Press enter to exit." << std::endl;
92  std::cin.ignore();
93  return -1;
94  }
95  auto FRAME_DISPLAY_STRIDE = 3u;
96  if (argc > 1) {
97  std::stringstream ss;
98  ss << argv[1];
99  if (ss >> FRAME_DISPLAY_STRIDE) {
100  std::cout << "Custom display stride passed: "
101  << FRAME_DISPLAY_STRIDE << std::endl;
102  } else {
103  std::cout << "Could not parse first command-line argument as a "
104  "display stride : '"
105  << argv[1] << "' (will use default)" << std::endl;
106  }
107  }
108 
109  cam->grab();
110 
111  std::cout << "Will display 1 out of every " << FRAME_DISPLAY_STRIDE
112  << " frames captured." << std::endl;
113  std::cout << "\nPress q or esc to quit, c to capture a frame to file.\n"
114  << std::endl;
115 
116  auto frame = cv::Mat{};
117  auto grayFrame = cv::Mat{};
118 
119  auto savedFrame = false;
120  static const auto FILENAME = "capture.png";
121  static const auto FILENAME_STEM = "image";
122  static const auto EXTENSION = ".png";
123  auto captures = std::size_t{0};
124  FrameCounter counter;
125 
126 #ifdef OSVR_ENABLE_RECORDING
127  std::cout << "\nThis build is also video capture enabled: continuously "
128  "recording to "
129  << VIDEO_FILENAME << std::endl;
130  cv::VideoWriter outputVideo{"capture.avi",
131  CV_FOURCC_MACRO('M', 'J', 'P', 'G'), 100,
132  cv::Size(640, 480), true};
133  if (!outputVideo.isOpened()) {
134  std::cerr << "Could not open the output video for writing!"
135  << std::endl;
136  return -1;
137  }
138 #endif
139 
140  cv::namedWindow(windowNameAndInstructions);
141  auto frameCount = std::size_t{0};
142  do {
143  cam->retrieve(frame, grayFrame);
144 
145 #ifdef OSVR_ENABLE_RECORDING
146  outputVideo.write(frame);
147 #endif
148 
149  counter.gotFrame();
150  ++frameCount;
151  if (frameCount % FRAME_DISPLAY_STRIDE == 0) {
152  frameCount = 0;
153  cv::imshow(windowNameAndInstructions, frame);
154  if (!savedFrame) {
155  savedFrame = true;
156  cv::imwrite(FILENAME, frame);
157  std::cout << "Wrote a captured frame to " << FILENAME
158  << std::endl;
159  }
160  char key = static_cast<char>(cv::waitKey(1)); // wait 1 ms for a key
161  if ('q' == key || 'Q' == key || 27 /*esc*/ == key) {
162  break;
163  } else if ('c' == key) {
164  // capture
165  std::ostringstream os;
166  os << FILENAME_STEM << captures << EXTENSION;
167  cv::imwrite(os.str(), frame);
168  std::cout << "Captured frame to " << os.str() << std::endl;
169  captures++;
170  }
171  }
172  } while (cam->grab());
173  return 0;
174 }
double duration(TimeValue const &a, TimeValue const &b)
Get a double containing seconds between the time points.
Definition: TimeValue.h:62