Robot Simulator of the Robotics Group for Self-Organization of Control  0.8.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
camerasensors.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2011 LpzRobots development team *
3  * Georg Martius <georg dot martius at web dot de> *
4  * Frank Guettler <guettler at informatik dot uni-leipzig dot de *
5  * Frank Hesse <frank at nld dot ds dot mpg dot de> *
6  * Ralf Der <ralfder at mis dot mpg dot de> *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the *
20  * Free Software Foundation, Inc., *
21  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22  * *
23  ***************************************************************************/
24 
25 #ifndef __CAMERASENSORS_H
26 #define __CAMERASENSORS_H
27 
28 #include "camerasensor.h"
29 #include <selforg/controller_misc.h>
30 
31 namespace lpzrobots {
32 
33 
34  /** This CameraSensor implements a direct conversion from pixels to sensors.
35  Probably you want to use an image processor like LineImgProc before.
36  */
38  public:
39 
40  /** the camera image should be black and white (e.g. @see BWImageProcessor)
41  @see CameraSensor for further parameter explanation.
42  @param minValue pixel value that corresponds to -1
43  @param maxValue pixel value that corresponds to 1
44  (for minValue =-256 and maxValue=256 the sensor values are in [0,1)
45  */
48  }
49 
50 
52  delete[] data;
53  }
54 
55  virtual void intern_init(){
56  assert(camera->isInitialized());
57  const osg::Image* img = camera->getImage();
58  assert(img && img->getPixelFormat()==GL_LUMINANCE && img->getDataType()==GL_UNSIGNED_BYTE);
59  num = img->s() * img->t();
60  data = new sensor[num];
61  };
62 
63 
64  /// Performs the calculations
65  virtual bool sense(const GlobalData& globaldata){
66  const osg::Image* img = camera->getImage();
67  const unsigned char* pixel = img->data();
68  if(img->s() * img->t() < num) return false;
69  int center = (maxValue+minValue)/2;
70  for(int k=0; k< num; k++){
71  data[k]=(pixel[k]-center)*2.0/double(maxValue-minValue);
72 }
73  return true;
74  }
75 
76  virtual int getSensorNumber() const {
77  return num;
78  };
79 
80  /// overload this function and return the sensor values
81  virtual int get(sensor* sensors, int length) const {
82  assert(length>=num);
83  memcpy(sensors, data, num * sizeof(sensor));
84  return num;
85  }
86 
87 
88  protected:
89  int num;
90  int minValue;
91  int maxValue;
93  };
94 
96  typedef short Values; ///< combination of PositionCameraSensor::ValueTypes
97 
98  /// values additional sensor values, @see PositionCameraSensor::Values
100  /// dims dimensions to return the position (X means horizonal, Y vertical)
102  /** exponent for the measured size. A sqrt (0.5) make small sizes larger, so
103  that changes in the distance can be measured better */
104  double sizeExponent;
105  /// factor for measured size change (velocity is in framesize/frame)
107  /// clipsize value at which the values are clipped, e.g. [-1.5,1.5]
108  double clipsize ;
109  /** if >0 then the size and sizechange are zero if position is that far (border) away from the image border @see PositionCameraSensor */
110  double border ;
111  };
112 
113 
114  /** This CameraSensor calculates the position of the visible object(s) that
115  is essentially the center of gravity of the image.
116  The position in normalized to -1 to 1.
117  Probably you want to use an image processor like ColorFilterImgProc before.
118  */
120  public:
121  /** additional sensor values. Size is the size of the object (only one value,
122  independent of the dimensions */
123  enum ValueTypes { None = 0, Position = 1, Size = 2, SizeChange = 4 };
124 
125  /** The camera image should be black and white
126  (e.g. @see BWImageProcessor or ColorFilterImgProc)
127  @see CameraSensor for further parameter explanation.
128  @param values sensor values to compute (@see PositionCameraSensor::ValueTypes)
129  @param dims dimensions to return the position (X means horizonal, Y vertical)
130  @param border if >0 then the size and sizechange are zero if position is that far (border) away from
131  image border
132  */
134  : conf(conf), oldsize(0) {
135  num = (bool(conf.dims & X) + bool(conf.dims & Y))* bool(conf.values & Position) +
136  bool(conf.values & Size) + bool(conf.values & SizeChange);
137  std::vector<std::string> names;
138  setNamesIntern(names);
139  }
140 
143  c.values = Position;
144  c.dims = XY;
145  c.factorSizeChange = 10.0;
146  c.sizeExponent = 1;
147  c.clipsize = 1.5;
148  c.border = 0;
149  return c;
150  }
151 
152  /// sets the names of the sensors and starts with the given names (for subclasses)
153  virtual void setNamesIntern(std::vector<std::string>& names){
154  setBaseInfo(SensorMotorInfo("CamAvg: ").changequantity(SensorMotorInfo::Other));
155  if(conf.values & Position) {
156  if(conf.dims & X) names.push_back("PosH");
157  if(conf.dims & Y) names.push_back("PosV");
158  }
159  if(conf.values & Size) names.push_back("Size");
160  if(conf.values & SizeChange) names.push_back("Size Change");
161  setNames(names);
162  }
163 
165  if(data) delete[] data;
166  }
167 
168  virtual void intern_init(){
169  assert(camera->isInitialized());
170 
171  data = new sensor[num];
172  memset(data,0,sizeof(sensor)*num);
173 
174  const osg::Image* img = camera->getImage();
175  img=img; // to avoid unused variable in NDEBUG mode
176  assert(img && img->getPixelFormat()==GL_LUMINANCE &&
177  img->getDataType()==GL_UNSIGNED_BYTE);
178  };
179 
180 
181  /// Performs the calculations
182  virtual bool sense(const GlobalData& globaldata){
183  const osg::Image* img = camera->getImage();
184  double x;
185  double y;
186  double size;
187  calcImgCOG(img, x, y, size);
188  int k=0;
189  return processAndFillData(x, y, size, k );
190  }
191 
192  virtual int getSensorNumber() const {
193  return num;
194  };
195 
196  /// overload this function and return the sensor values
197  virtual int get(sensor* sensors, int length) const {
198  assert(length>=num);
199  memcpy(sensors, data, num * sizeof(sensor));
200  return num;
201  }
202 
203  protected:
204  /// process sensor information and fills
205  // the data buffer starting at intex k
206  virtual bool processAndFillData(double& x, double& y, double& size, int& k){
207  int kstart = k;
208  if(conf.sizeExponent!=1)
209  size = pow(size,conf.sizeExponent);
210 
211  if(conf.values & Position){
212  if(conf.dims & X) data[k++] = x;
213  if(conf.dims & Y) data[k++] = y;
214  }
215  double sizeChange = (size - oldsize)*conf.factorSizeChange;
216  oldsize = size;
217 
218  // check border effects
219  if(conf.border>0){
220  if((x==0 && y==0) || ((conf.dims & X) && (fabs(x) > (1-conf.border))) ||
221  ((conf.dims & Y) && (fabs(y) > (1-conf.border))) ){
222  size=0;
223  sizeChange=0;
224  }
225  }
226  if(conf.values & Size) data[k++] = size;
227  if(conf.values & SizeChange) data[k++] = sizeChange;
228 
229  // clip values
230  if(conf.clipsize!=0){
231  for(int i=kstart; i<k; i++){
232  data[i] = clip(data[i],-conf.clipsize,conf.clipsize);
233  }
234  }
235  return true;
236  }
237 
238  /** calculates the Center of Gravity (normalized to -1 to 1) of an image.
239  As a bonus it also calculates the sum of all pixels (normalizes to 0-2.5) in size
240  @return false if image is too dark
241  */
242  static bool calcImgCOG(const osg::Image* img, double& x, double& y, double& size,
243  int threshold = 1){
244  int w = img->s();
245  int h = img->t();
246  double centerX = w/2.0;
247  double centerY = h/2.0;
248  if(threshold<1) threshold = 1;
249  x = y = 0;
250  double sum= 0;
251  for(int r=0; r< h; r++){
252  const unsigned char* row = img->data(0, r);
253  double pY = ((double)r-centerY);
254  for(int c=0; c < w; c++){
255  sum += row[c];
256  x += row[c] * ((double)c-centerX);
257  y += row[c] * pY;
258  }
259  }
260  if(sum<threshold){
261  x = y = size = 0;
262  return false;
263  }else{
264  x /= sum * centerX; // normalize to -1 to 1
265  y /= sum * centerY; // normalize to -1 to 1
266  // the /255 would be correct, but then the values is so small
267  size = double(sum) / (w*h) / 128;
268  return true;
269  }
270  }
271 
272 
273  protected:
275  int num;
277  double oldsize;
278  };
279 
280 
282  /// averaging time window (1: no averaging)
283  int avg ;
284  /// factor for measured velocity (velocity is in framesize/frame)
285  double factorMotion ;
286  /// window whether to apply a windowing function to motion data to avoid edge effects
287  bool window ;
288 
289  };
290 
291 
292  /** This CameraSensor calculates the global optical flow of the camera image
293  using the center of gravity method. It requires objects to be bright on black ground.
294  The velocity is by default windowed to avoid step-like artefacts at the border.
295  Probably you want to use an image processor like ColorFilterImgProc before.
296  */
298  public:
299 
300  /** The camera image should be black and white
301  (e.g. @see BWImageProcessor or ColorFilterImgProc)
302  @see CameraSensor for further parameter explanation.
303  @param mconf configuration object @see MotionCameraSensorConf
304  and @see PositionCameraSensorConf
305  */
308  last(false), lastX(0), lastY(0)
309  {
310  if(this->mconf.avg<1) this->mconf.avg=1;
311  lambda = 1/(double)this->mconf.avg;
312  num += bool(this->mconf.dims & X) + bool(this->mconf.dims & Y);
313  std::vector<std::string> names;
314  if(mconf.dims & X) names.push_back("MotionH");
315  if(mconf.dims & Y) names.push_back("MotionV");
316  setNamesIntern(names);
317  }
318 
321  c.avg = 2;
322  c.values = None;
323  c.dims = X;
324  c.factorSizeChange = 10.0;
325  c.sizeExponent = 1;
326  c.clipsize = 1.5;
327  c.border = 0;
328  c.factorMotion = 5.0;
329  c.window = true;
330  return c;
331  }
332 
334  }
335 
336  /// Performs the calculations
337  virtual bool sense(const GlobalData& globaldata){
338  const osg::Image* img = camera->getImage();
339  double x;
340  double y;
341  double size;
342  bool success = calcImgCOG(img, x, y, size);
343  int k=0;
344  // check if the apparent shift is feasible, otherwise set to no motion.
345  if(last && success && fabs(x - lastX) < 0.4 && fabs(y - lastY) < 0.4){
346  if(mconf.dims & X) {
347  data[k] = lambda*(x - lastX)*mconf.factorMotion* (mconf.window ? windowfunc(x) : 1)
348  + (1- lambda)*data[k];
349  k++;
350  }
351  if(mconf.dims & Y) {
352  data[k] = lambda*(y - lastY)*mconf.factorMotion* (mconf.window ? windowfunc(y) : 1)
353  + (1- lambda)*data[k]; k++;
354  }
355  // clip values
356  if(conf.clipsize!=0){
357  for(int i=0; i<k; i++){
359  }
360  }
361  }else{
362  if(mconf.dims & X) data[k++]=0;
363  if(mconf.dims & Y) data[k++]=0;
364  }
365  lastX = x;
366  lastY = y;
367  last = success;
368  // add all other sensor values
369  return processAndFillData(x,y,size,k);
370  }
371 
372  /// window function for the interval -1 to 1, with ramps from 0.5 off center
373  double windowfunc(double x){
374  if(x>-0.5 && x<0.5) return 1.0;
375  if(x<= -0.5) return 2+ 2*x;
376  else return 2- 2*x; // (x>0.5)
377  }
378 
379  protected:
381  double lambda;
382  bool last; ///< whether last image had a valid position
383  double lastX;
384  double lastY;
385 
386  };
387 
388 }
389 
390 #endif
virtual ~PositionCameraSensor()
Definition: camerasensors.h:164
This CameraSensor calculates the position of the visible object(s) that is essentially the center of ...
Definition: camerasensors.h:119
void setBaseInfo(const SensorMotorInfo &baseinfo)
Definition: sensormotorinfoable.h:50
double lastX
Definition: camerasensors.h:383
int maxValue
Definition: camerasensors.h:91
Definition: camerasensors.h:281
ValueTypes
additional sensor values.
Definition: camerasensors.h:123
virtual bool processAndFillData(double &x, double &y, double &size, int &k)
process sensor information and fills
Definition: camerasensors.h:206
static PositionCameraSensorConf getDefaultConf()
Definition: camerasensors.h:141
Definition: sensor.h:46
virtual bool sense(const GlobalData &globaldata)
Performs the calculations.
Definition: camerasensors.h:182
Sensor::Dimensions dims
dims dimensions to return the position (X means horizonal, Y vertical)
Definition: camerasensors.h:101
Definition: sensormotorinfo.h:36
double windowfunc(double x)
window function for the interval -1 to 1, with ramps from 0.5 off center
Definition: camerasensors.h:373
Values values
values additional sensor values,
Definition: camerasensors.h:99
static MotionCameraSensorConf getDefaultConf()
Definition: camerasensors.h:319
void setNames(const std::vector< std::string > &names)
set names explicitly (basename is anyway suffixed)
Definition: sensormotorinfoable.h:67
PositionCameraSensorConf conf
Definition: camerasensors.h:274
bool last
whether last image had a valid position
Definition: camerasensors.h:382
double sensor
Definition: types.h:29
int num
Definition: camerasensors.h:275
MotionCameraSensor(const MotionCameraSensorConf &mconf=getDefaultConf())
The camera image should be black and white (e.g.
Definition: camerasensors.h:306
Definition: camerasensors.h:123
Definition: camerasensors.h:123
This CameraSensor implements a direct conversion from pixels to sensors.
Definition: camerasensors.h:37
virtual int getSensorNumber() const
overload this function and return the number of sensor values
Definition: camerasensors.h:76
Definition: position.h:30
sensor * data
Definition: camerasensors.h:276
virtual bool sense(const GlobalData &globaldata)
Performs the calculations.
Definition: camerasensors.h:65
double factorMotion
factor for measured velocity (velocity is in framesize/frame)
Definition: camerasensors.h:285
virtual ~DirectCameraSensor()
Definition: camerasensors.h:51
double factorSizeChange
factor for measured size change (velocity is in framesize/frame)
Definition: camerasensors.h:106
virtual void setNamesIntern(std::vector< std::string > &names)
sets the names of the sensors and starts with the given names (for subclasses)
Definition: camerasensors.h:153
Interface for objects, that can be stored and restored to/from a file stream (binary).
Definition: sensormotorinfo.h:33
virtual int getSensorNumber() const
overload this function and return the number of sensor values
Definition: camerasensors.h:192
virtual ~MotionCameraSensor()
Definition: camerasensors.h:333
int minValue
Definition: camerasensors.h:90
Data structure holding all essential global information.
Definition: globaldata.h:57
Camera * camera
Definition: camerasensor.h:91
double clip(double r, double x)
clipping function for mapP
Definition: controller_misc.cpp:39
bool isInitialized()
Definition: camera.h:145
int avg
averaging time window (1: no averaging)
Definition: camerasensors.h:283
virtual bool sense(const GlobalData &globaldata)
Performs the calculations.
Definition: camerasensors.h:337
double lambda
Definition: camerasensors.h:381
double lastY
Definition: camerasensors.h:384
double border
if >0 then the size and sizechange are zero if position is that far (border) away from the image bord...
Definition: camerasensors.h:110
Definition: camerasensors.h:123
sensor * data
Definition: camerasensors.h:92
Class to connect a Camera as a sensor to a robot.
Definition: camerasensor.h:43
short Values
combination of PositionCameraSensor::ValueTypes
Definition: camerasensors.h:96
Definition: sensor.h:46
double clipsize
clipsize value at which the values are clipped, e.g. [-1.5,1.5]
Definition: camerasensors.h:108
double sizeExponent
exponent for the measured size.
Definition: camerasensors.h:104
MotionCameraSensorConf mconf
Definition: camerasensors.h:380
static bool calcImgCOG(const osg::Image *img, double &x, double &y, double &size, int threshold=1)
calculates the Center of Gravity (normalized to -1 to 1) of an image.
Definition: camerasensors.h:242
DirectCameraSensor(int minValue=-256, int maxValue=256)
the camera image should be black and white (e.g.
Definition: camerasensors.h:46
PositionCameraSensor(PositionCameraSensorConf conf=getDefaultConf())
The camera image should be black and white (e.g.
Definition: camerasensors.h:133
virtual const osg::Image * getImage() const
last image of processing stack
Definition: camera.h:139
Definition: camerasensors.h:123
This CameraSensor calculates the global optical flow of the camera image using the center of gravity ...
Definition: camerasensors.h:297
virtual void intern_init()
overload this function to initialized you data structures.
Definition: camerasensors.h:168
Dimensions
defines which dimensions should be sensed. The meaning is sensor specific.
Definition: sensor.h:46
Definition: sensor.h:46
virtual void intern_init()
overload this function to initialized you data structures.
Definition: camerasensors.h:55
int num
Definition: camerasensors.h:89
bool window
window whether to apply a windowing function to motion data to avoid edge effects ...
Definition: camerasensors.h:287
double oldsize
Definition: camerasensors.h:277
Definition: camerasensors.h:95
int c
Definition: hexapod.cpp:56