OSVR-Core
base_camera_server.h
Go to the documentation of this file.
1 
12 // Copyright 2015 Sensics, Inc.
13 //
14 // Licensed under the Apache License, Version 2.0 (the "License");
15 // you may not use this file except in compliance with the License.
16 // You may obtain a copy of the License at
17 //
18 // http://www.apache.org/licenses/LICENSE-2.0
19 //
20 // Unless required by applicable law or agreed to in writing, software
21 // distributed under the License is distributed on an "AS IS" BASIS,
22 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 // See the License for the specific language governing permissions and
24 // limitations under the License.
25 
26 #ifndef INCLUDED_base_camera_server_h_GUID_AE8BD56F_793F_4693_9B94_4E4CC953511C
27 #define INCLUDED_base_camera_server_h_GUID_AE8BD56F_793F_4693_9B94_4E4CC953511C
28 
29 // Internal Includes
30 #include <vrpn_Shared.h>
31 
32 // Library/third-party includes
33 // - none
34 
35 // Standard includes
36 #include <stdio.h> // For NULL
37 #include <math.h> // For floor()
38 #include <string>
39 #include <vector>
40 
41 //----------------------------------------------------------------------------
42 // This class forms a basic wrapper for an image. It treats an image as
43 // anything
44 // which can support requests on the number of pixels in an image and can
45 // perform queries by pixel coordinate in that image. It is a set of functions
46 // that are needed by the com_osvr_VideoBasedHMDTracker.
47 // @todo If we template this class based on the type of pixel it has, we may be
48 // able to speed things up quite a bit for particular cases of interest. Even
49 // better may be to implement functions that wrap the functions we need to
50 // have be fast (like writing to a GL_LUMINANCE OpenGL texture).
51 
53  public:
54  // Virtual destructor so that children can de-allocate space as needed.
55  virtual ~image_wrapper(){};
56 
57  // Tell what the range is for the image.
58  virtual void read_range(int &minx, int &maxx, int &miny,
59  int &maxy) const = 0;
60 
62  virtual unsigned get_num_colors() const = 0;
63  // XXX These should return the maximum number of possible rows/columns,
64  // like the ones in the camera server do.
65  virtual unsigned get_num_rows(void) const {
66  int _minx, _maxx, _miny, _maxy;
67  read_range(_minx, _maxx, _miny, _maxy);
68  return _maxy - _miny + 1;
69  }
70  virtual unsigned get_num_columns(void) const {
71  int _minx, _maxx, _miny, _maxy;
72  read_range(_minx, _maxx, _miny, _maxy);
73  return _maxx - _minx + 1;
74  }
75 
77  // was in the image, false if it was not.
78  virtual bool read_pixel(int x, int y, double &result,
79  unsigned rgb = 0) const = 0;
80 
81  // Overloaded by result type to enable optimization later but use by any.
82  virtual bool read_pixel(int x, int y, vrpn_uint8 &result,
83  unsigned rgb = 0) const {
84  double double_pix;
85  bool err = read_pixel(x, y, double_pix, rgb);
86  result = static_cast<vrpn_uint8>(double_pix);
87  return err;
88  }
89  virtual bool read_pixel(int x, int y, vrpn_uint16 &result,
90  unsigned rgb = 0) const {
91  double double_pix;
92  bool err = read_pixel(x, y, double_pix, rgb);
93  result = static_cast<vrpn_uint16>(double_pix);
94  return err;
95  }
96 
98  virtual double read_pixel_nocheck(int x, int y, unsigned rgb = 0) const = 0;
99 
100  // Do bilinear interpolation to read from the image, in order to
101  // smoothly interpolate between pixel values.
102  // All sorts of speed tweaks in here because it is in the inner loop for
103  // the spot tracker and other codes.
104  // Return a result of zero and false if the coordinate its outside the
105  // image.
106  // Return the correct interpolated result and true if the coordinate is
107  // inside.
108  inline bool read_pixel_bilerp(double x, double y, double &result,
109  unsigned rgb = 0) const {
110  result = 0; // In case of failure.
111  // The order of the following statements is optimized for speed.
112  // The double version is used below for xlowfrac comp, ixlow also used
113  // later.
114  // Slightly faster to explicitly compute both here to keep the answer
115  // around.
116  double xlow = floor(x);
117  int ixlow = (int)xlow;
118  // The double version is used below for ylowfrac comp, ixlow also used
119  // later
120  // Slightly faster to explicitly compute both here to keep the answer
121  // around.
122  double ylow = floor(y);
123  int iylow = (int)ylow;
124  int ixhigh = ixlow + 1;
125  int iyhigh = iylow + 1;
126  double xhighfrac = x - xlow;
127  double yhighfrac = y - ylow;
128  double xlowfrac = 1.0 - xhighfrac;
129  double ylowfrac = 1.0 - yhighfrac;
130  double ll, lh, hl, hh;
131 
132  // Combining the if statements into one using || makes it slightly
133  // slower.
134  // Interleaving the result calculation with the returns makes it slower.
135  if (!read_pixel(ixlow, iylow, ll, rgb)) {
136  return false;
137  }
138  if (!read_pixel(ixlow, iyhigh, lh, rgb)) {
139  return false;
140  }
141  if (!read_pixel(ixhigh, iylow, hl, rgb)) {
142  return false;
143  }
144  if (!read_pixel(ixhigh, iyhigh, hh, rgb)) {
145  return false;
146  }
147  result = ll * xlowfrac * ylowfrac + lh * xlowfrac * yhighfrac +
148  hl * xhighfrac * ylowfrac + hh * xhighfrac * yhighfrac;
149  return true;
150  };
151 
152  // Do bilinear interpolation to read from the image, in order to
153  // smoothly interpolate between pixel values.
154  // All sorts of speed tweaks in here because it is in the inner loop for
155  // the spot tracker and other codes.
156  // Does not check boundaries to make sure they are inside the image.
157  inline double read_pixel_bilerp_nocheck(double x, double y,
158  unsigned rgb = 0) const {
159  // The order of the following statements is optimized for speed.
160  // The double version is used below for xlowfrac comp, ixlow also used
161  // later.
162  // Slightly faster to explicitly compute both here to keep the answer
163  // around.
164  double xlow = floor(x);
165  int ixlow = (int)xlow;
166  // The double version is used below for ylowfrac comp, ixlow also used
167  // later
168  // Slightly faster to explicitly compute both here to keep the answer
169  // around.
170  double ylow = floor(y);
171  int iylow = (int)ylow;
172  int ixhigh = ixlow + 1;
173  int iyhigh = iylow + 1;
174  double xhighfrac = x - xlow;
175  double yhighfrac = y - ylow;
176  double xlowfrac = 1.0 - xhighfrac;
177  double ylowfrac = 1.0 - yhighfrac;
178 
179  // Combining the if statements into one using || makes it slightly
180  // slower.
181  // Interleaving the result calculation with the returns makes it slower.
182  return read_pixel_nocheck(ixlow, iylow, rgb) * xlowfrac * ylowfrac +
183  read_pixel_nocheck(ixlow, iyhigh, rgb) * xlowfrac * yhighfrac +
184  read_pixel_nocheck(ixhigh, iylow, rgb) * xhighfrac * ylowfrac +
185  read_pixel_nocheck(ixhigh, iyhigh, rgb) * xhighfrac * yhighfrac;
186  };
187 
188  protected:
189 };
190 
191 //----------------------------------------------------------------------------
192 // This class forms a basic wrapper for a camera. It treats an camera as
193 // anything which can do what is needed for an imager and also includes
194 // functions for reading images into memory from the camera.
195 
197  public:
198  virtual ~base_camera_server(void){};
199 
201  bool working(void) const { return _status; };
202 
203  // These functions should be used to determine the stride in the
204  // image when skipping lines. They are in terms of the full-screen
205  // number of pixels with the current binning level.
206  unsigned get_num_rows(void) const { return _num_rows / _binning; };
207  unsigned get_num_columns(void) const { return _num_columns / _binning; };
208 
216  virtual bool read_image_to_memory(unsigned minX = 255, unsigned maxX = 0,
217  unsigned minY = 255, unsigned maxY = 0,
218  double exposure_time = 250.0) = 0;
219 
221  virtual bool get_pixel_from_memory(unsigned X, unsigned Y, vrpn_uint8 &val,
222  int RGB = 0) const = 0;
223  virtual bool get_pixel_from_memory(unsigned X, unsigned Y, vrpn_uint16 &val,
224  int RGB = 0) const = 0;
225 
226  // Makes the read routines in the base class faster by calling the above
227  // methods.
228  virtual bool read_pixel(int x, int y, vrpn_uint8 &result,
229  unsigned rgb = 0) const {
230  return get_pixel_from_memory(x, y, result, rgb);
231  }
232  virtual bool read_pixel(int x, int y, vrpn_uint16 &result,
233  unsigned rgb = 0) const {
234  return get_pixel_from_memory(x, y, result, rgb);
235  }
236 
238  // was in the image, false if it was not.
239  virtual bool read_pixel(int x, int y, double &result,
240  unsigned rgb = 0) const {
241  vrpn_uint16 val = 0;
242  result = 0.0; // Until we get a better one
243  if (get_pixel_from_memory(x, y, val, rgb)) {
244  result = val;
245  return true;
246  } else {
247  return false;
248  }
249  };
250 
252  virtual double read_pixel_nocheck(int x, int y, unsigned rgb = 0) const {
253  vrpn_uint16 val = 0;
254  get_pixel_from_memory(x, y, val, rgb);
255  return val;
256  };
257 
259  virtual void read_range(int &minx, int &maxx, int &miny, int &maxy) const {
260  minx = _minX;
261  miny = _minY;
262  maxx = _maxX;
263  maxy = _maxY;
264  }
265 
266  protected:
267  bool _status; //< True is working, false is not
268  unsigned _num_rows, _num_columns; //< Size of the memory buffer
269  unsigned _minX = 0;
270  unsigned _minY = 0;
271  unsigned _maxX = 0;
272  unsigned _maxY = 0; //< Region of the image in memory
273  unsigned _binning; //< How many camera pixels compressed into image pixel
274 
275  virtual bool open_and_find_parameters(void) { return false; };
276  base_camera_server(unsigned binning = 1) {
277  _binning = binning;
278  if (_binning < 1) {
279  _binning = 1;
280  }
281  };
282 };
283 
284 #endif // INCLUDED_base_camera_server_h_GUID_AE8BD56F_793F_4693_9B94_4E4CC953511C
virtual bool read_pixel(int x, int y, double &result, unsigned rgb=0) const
Read a pixel from the image into a double; return true if the pixel.
Definition: base_camera_server.h:239
virtual double read_pixel_nocheck(int x, int y, unsigned rgb=0) const
Read a pixel from the image into a double; Don&#39;t check boundaries.
Definition: base_camera_server.h:252
Definition: base_camera_server.h:52
virtual void read_range(int &minx, int &maxx, int &miny, int &maxy) const
Instantiation needed for image_wrapper.
Definition: base_camera_server.h:259
virtual unsigned get_num_colors() const =0
Return the number of colors that the image has.
virtual double read_pixel_nocheck(int x, int y, unsigned rgb=0) const =0
Read a pixel from the image into a double; Don&#39;t check boundaries.
virtual bool read_pixel(int x, int y, double &result, unsigned rgb=0) const =0
Read a pixel from the image into a double; return true if the pixel.
Definition: base_camera_server.h:196
bool working(void) const
Is the camera working properly?
Definition: base_camera_server.h:201