Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
GLProjectionParametersPerspective.cpp
1 #include <GLviewer/GLProjectionParametersPerspective.hh>
2 #include <GLviewer/Scenes/SceneBGImage.hh>
3 #include <OpenGLFramework/Base/glfMatrix.hh>
4 
5 #define RAD_TO_DEG 57.29577951
6 #define DEG_TO_RAD 0.017453292
7 
8 //#define SKEW
9 
10 using namespace std;
11 using namespace BIAS;
12 
13 GLProjectionParametersPerspective::
14 GLProjectionParametersPerspective() :
16 {
17  ignoreDistortion_=false;
18  distorter_ = -1;
19 }
20 
21 
25 {
26  ignoreDistortion_=false;
27  distorter_ = -1;
28 }
29 
33 {
36  distorter_ = glppp.distorter_;
40  return *this;
41 }
42 
45 {
48  distorter_ = glppp.distorter_;
52 }
53 
54 
55 #ifdef BIAS_HAVE_XML2
57 XMLRead (const std::string &Filename){
58  //informScenesOfChange_ = true;
59  ExtrinsicStateChanged_ = false;
62 }
64 XMLWrite (const std::string &Filename) const{
66 }
67 
69 Load (const std::string& Filename){
70  return XMLRead(Filename);
71 }
73 Save (const std::string& Filename) const{
74  return XMLWrite(Filename);
75 }
76 #endif
77 
78 
80 SetSimplePerspectiveCam(double fovyDEG, int imageWidth, int imageHeight)
81 {
82  int viewport[4];
83  viewport[0] = 0;
84  viewport[1] = 0;
85 
86  if (imageWidth == -1 || imageHeight == -1)
87  {
88  viewport[2]=800;
89  viewport[3]=600;
90  }
91  else
92  {
93  viewport[2] = imageWidth;
94  viewport[3] = imageHeight;
95  }
96 
97  double imgAspectRatio = (double) viewport[2] / (double) viewport[3];
98  //use focallength of 1 since UpdateGLProjectionMatrix_ is taking care
99  //of zNear_!
100  double imageSceneHeight = 2.0 * tan(fovyDEG/2.0 * DEG_TO_RAD);
101  double imageSceneWidth = imageSceneHeight * imgAspectRatio;
102 
103  KMatrix K;
104  K.SetIdentity();
105  //principle point
106  K[0][2] = (double)viewport[2]/2.0 - 0.5;
107  K[1][2] = (double)viewport[3]/2.0 - 0.5;
108  //pixel scale
109  K[0][0] = (double)viewport[2]/imageSceneWidth;
110  K[1][1] = (double)viewport[3]/imageSceneHeight;
111 
113  {
114  RMatrix R;
115  R.SetIdentity();
116  Vector3<double> C(0.0,0.0,0.0);
119  ExtrinsicStateChanged_ = true;
120  }
121 
123  SetK(K);
124  SetImageSize((unsigned int) viewport[2],
125  (unsigned int) viewport[3]);
126 
127  IntrinsicStateChanged_ = true;
128  informScenesOfChange_ = true;
129  return 0;
130 }
131 
132 
135 {
137  = dynamic_cast<ProjectionParametersPerspective*>(proj);
138 
139  if (!ppp) {
140  BIASERR("Not a perspective projection!")
141  }
142  else {
143  const Pose pose = GetPose(); // backup of extrinsics
145  SetPose(pose);
146  InitShaders_();
147  informScenesOfChange_ = true;
148  ExtrinsicStateChanged_ = false;
149  IntrinsicStateChanged_ = true;
150  }
151 }
152 
153 
156 {
158  = dynamic_cast<ProjectionParametersPerspective*>(proj);
159 
160  if (!ppp) {
161  BIASERR("Not a perspective projection!")
162  }
163  else {
165  InitShaders_();
166  informScenesOfChange_ = true;
167  ExtrinsicStateChanged_ = true;
168  IntrinsicStateChanged_ = true;
169  }
170 }
171 
172 
174 SetGLMatrices(bool forceUpdate)
175 {
176  if(ExtrinsicStateChanged_ || forceUpdate)
177  if(UpdateGLModelViewMatrix_()!=0)
178  return -1;
179 
180  unsigned int imgWidth, imgHeight;
181  GetImageSize(imgWidth, imgHeight);
182  // cout<<" GLProjectionParametersPerspective SetGLMatrices:"<<imgWidth<<" "<<imgHeight<<endl;
183 
184  if(IntrinsicStateChanged_ || forceUpdate) {
185  if(UpdateGLProjectionMatrix_(0,0,imgWidth, imgHeight)!=0)
186  return -1;
187  }
188 
189  glMatrixMode(GL_PROJECTION);
190  glLoadMatrixd(GLProjectionMatrix_.GetData());
191  glMatrixMode(GL_MODELVIEW);
192  glLoadMatrixd(GLModelViewMatrix_.GetData());
193  return 0;
194 }
195 
196 
197 
200 {
201  ClearColor_ = cc;
202 }
203 
204 
206 Rescale_(float scale)
207 {
208  //cout << "*** GLPPP::Rescale_() with scale = " << scale << endl;
210  InitShaders_();
211 }
212 
213 
215 UpdateGLProjectionMatrix_(unsigned int x0, unsigned int y0,
216  unsigned int width, unsigned int height)
217 {
218  // cout<<"UpdateGLProjectionMatrix_ start image size: "<<width<<","<<height<<endl;
219  Vector3<double> clippingWindowUL, clippingWindowLR;
220 
221  double kc1, kc2, kc3, kc4;
222  GetUndistortion(kc1, kc2, kc3, kc4);
223  if((kc1==0.0 && kc2==0.0 && kc3==0.0 && kc4==0.0) || ignoreDistortion_)
224  {
225 
226 #ifndef SKEW
227  Vector3<double> pos;
228  UnProjectLocal(HomgPoint2D(x0-0.5,y0-0.5), pos, clippingWindowUL);
229  UnProjectLocal(HomgPoint2D(x0+width-0.5,y0+height-0.5), pos, clippingWindowLR);
230 #endif
231  distort_ = false;
232 
233  }
234  else
235  {
236  if (distorter_ < 0) InitShaders_();
237  KMatrix idealK;
238  unsigned int fullW, fullH;
239  GetImageSize(fullW, fullH);
240  SetIdealImageSize(width, height);
241 
242 #ifndef SKEW
243  GetIdealK(idealK);
244  GetIdealImageSize(width, height);
245 #endif
246 
247  if(/*x0 != 0 || y0 != 0 ||*/ fullW!=width || fullH!=height)
248  {
249  //we must allow to move the position of the viewport or we might get a black border
250  //over the image - which will result in unaligned mouse and screen coordinates
251  //x0 = 0 and y0 = 0 are gl viewport coordinates which describe the LOWER left corners
252  //of the viewport.
253  BIASERR("distortion rendering is not implemented to work with image "
254  "cut outs!"<<endl<<"x0: "<<x0<<" y0:"<<y0<<" fullW: "<<fullW
255  <<" widht:"<<width <<" fullH: "<<fullH<<" height: "<<height);
256  return -1;
257  }
258 
259 #ifndef SKEW
260  Vector3<double> pos;
261  ProjectionParametersPerspective distortDummy = *this;
262  distortDummy.SetImageSize(width, height);
263  distortDummy.SetK(idealK);
264  distortDummy.SetUndistortion(0.0,0.0,0.0,0.0);
265 
266  distortDummy.UnProjectLocal(HomgPoint2D(x0-0.5,y0-0.5), pos, clippingWindowUL);
267  distortDummy.UnProjectLocal(HomgPoint2D(x0+width-0.5, y0+height-0.5), pos, clippingWindowLR);
268 #endif
269  }
270  //calculate the near clipping plane in world coord metric
271 
272 #ifndef SKEW
273  clippingWindowUL *= (zNear_/clippingWindowUL[2]);
274  clippingWindowLR *= (zNear_/clippingWindowLR[2]);
275 #endif
276 
277  glPushAttrib(GL_TRANSFORM_BIT);
278  glMatrixMode(GL_PROJECTION);
279  glPushMatrix();
280  glLoadIdentity();
281 
282 #ifndef SKEW
283  glFrustum(clippingWindowUL[0], clippingWindowLR[0],
284  //calculate clip window in our coord system
285  //transform into gl coords by flipping around x-axis
286  -clippingWindowLR[1], -clippingWindowUL[1],
287  zNear_, zFar_);
288 #endif
289 #ifdef SKEW
290  glfMatrix projectionMatrix;
292  dynamic_cast<ProjectionParametersPerspective*>(GetMyselfAsProjectionParameterBase());
293  projectionMatrix.MakeProjectionMatrixNew(*param, zNear_, zFar_,
294  x0, y0, width, height,
295  distort_);
296  projectionMatrix.Load();
297 #endif
298 
299 
300  glGetDoublev( GL_PROJECTION_MATRIX, GLProjectionMatrix_.GetData() );
301  glPopMatrix();
302  glPopAttrib(); //GL_TRANSFORM_BIT
303 
304  IntrinsicStateChanged_ = false;
305  // cout<<"Set:zNear_, zFar_"<<zNear_<<","<<zFar_<<endl;
306  // cout<<"UpdateGLProjectionMatrix_ x0:"<<x0<<","<<y0<<","<< width<<","<<height<<endl;
307  return 0;
308 }
309 
310 
312 Draw_(std::vector<SceneBase *>& scenes,
313  BIAS::glfFramebufferObject* theTarget)
314 {
315  //////////////////////////////
316  try{
317  BeginDraw_(theTarget);
318  }catch(glfException& e){
319  BIASERR("GL Error in Draw_() : " << e.GetMessageString());
320  return -1;
321  }
322  /////////////////////////////
323  if(scenes.size() > 0){
324  for (unsigned int i=0; i<scenes.size(); i++) {
326  scenes[i]->UpdateCameraRelatedState();
327  }
328  scenes[i]->Render();
329  }
331  }//end of rendering regular scenes
332  //fragment from VisionN is in EndDraw_
333  /////////////////////////////
334 
335  try{
336  EndDraw_(theTarget);
337  }catch(glfException& e){
338  BIASERR("GL Error in Draw_() : " << e.GetMessageString());
339  return -1;
340  }
341  /////////////////////////////
342  return 0;
343 }
344 
347 {
348  //set all pixels
349  //stencil test passes to zfar
350  //enable stencil test
351  glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT |GL_STENCIL_BUFFER_BIT);
352  glEnable(GL_STENCIL_TEST);
353  glEnable(GL_DEPTH_TEST);
354  glDepthMask(GL_TRUE);
355  glStencilFunc(GL_EQUAL, 1, (GLuint)(~0));
356  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
357  glMatrixMode(GL_MODELVIEW);
358  glPushMatrix();
359  glLoadIdentity();
360  glMatrixMode(GL_PROJECTION);
361  glPushMatrix();
362  glLoadIdentity();
363  glDepthFunc(GL_ALWAYS); //<-------- overwrite everything not stenciled!
364  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
365  glColorMask(0,0,0,1); //clear alpha channel or background image blending will use alpha channel
366  float s=1;
367  glDisable(GL_TEXTURE_2D);
368  glBegin(GL_QUADS);
369  glColor4f(0,1,1,0); //clear alpha channel with 0 rgb can be anything
370  glVertex3f(-s, s, -s);
371  glVertex3f(-s, -s, -s);
372  glVertex3f(s, -s, -s);
373  glVertex3f(s, s, -s);
374  glEnd();
375  glColorMask(1,1,1,1);
376  glDepthFunc(GL_LESS);
377  glMatrixMode(GL_PROJECTION);
378  glPopMatrix();
379  glMatrixMode(GL_MODELVIEW);
380  glPopMatrix();
381  glPopAttrib();
382  //------------------------
383  glDisable(GL_STENCIL_TEST);
384 }
385 
388  int imageWidth,int imageHeight,
389  std::vector<SceneBase*>& scenes)
390 {
391  /*
392  cout << "\nentering GLPPP::DrawWithMatchedParamsAndViewport_() with image ("
393  << imageWidth << " x " << imageHeight << ")" << endl;
394  BIAS::Vector4<int> tmp;
395  glGetIntegerv(GL_VIEWPORT, tmp.GetData());
396  cout << "entering GLPPP::DrawWithMatchedParamsAndViewport_(): GLViewport is " << tmp[0]
397  << ", " << tmp[1]
398  << ", " << tmp[2]
399  << ", " << tmp[3] << endl;
400  */
401 
402  int res =0;
404  if(lastFullGLViewport_[2] == viewport[2] &&
405  lastFullGLViewport_[3] == viewport[3])
406  {
407  res = Draw_(scenes);
408  }
409  else
410  {
411  double decisionScaleWidth = (double)viewport[2] / (double)imageWidth;
412  double decisionScaleHeight = (double)viewport[3] / (double)imageHeight;
413  double decisionScale;
414 
415  if(decisionScaleWidth>decisionScaleHeight)
416  decisionScale = 1.0/decisionScaleWidth;
417  else
418  decisionScale = 1.0/decisionScaleHeight;
419 
420 
421  //force new image dimension (don't use rescale - it fails because of rounding errors)
422  SetImageSize(viewport[2],viewport[3]);
423  SetIdealImageSize(viewport[2],viewport[3]);
424  //scale principal point
425  double cx,cy;
426  GetPrincipal(cx,cy);
427  SetPrincipal(cx/decisionScale,cy/decisionScale);
428  //scale focal length
429  double f;
430  //TODO adjust skew ...
431  GetFocalLength(f);
432  SetFocalLengthAndAspect(f/decisionScale,(double)viewport[2]/(double)viewport[3]);
433  GLProjectionParametersBase::Rescale(1.0); //create new K
434 
435  for(unsigned int i=0; i<4; i++)
436  lastFullGLViewport_[i] = viewport[i];
437 
440 
442  informScenesOfChange_ = true;
443 
446  lastFullGLViewport_[3])!=0) BIASABORT;
447 
448  InitShaders_();
449 
450  res = Draw_(scenes);
451 
452  }
453  return res;
454  } //if (AutoViewingMatchBehaviour_ == AdaptToCroppedImage)
455  else
456  return GLProjectionParametersBase::DrawWithMatchedParamsAndViewport_( viewport, imageWidth, imageHeight,scenes);
457 }
458 
459 
460 
463 {
464  if (distorter_ == -1) {
465 
466  double kc1, kc2, kc3, kc4;
467  GetUndistortion(kc1, kc2, kc3, kc4);
468  if((kc1==0.0 && kc2==0.0 && kc3==0.0 && kc4==0.0) || ignoreDistortion_)
469  return;
470 
472 
473  for (unsigned int i=0;i<outputAttachmentIdentifiers_.size();i++) {
475  distorter_ = i;
476  }
477  }
478  }
479 }
480 
481 
483 Z2Depth_(const int x, const int y, const double z) const
484 {
485  double depth;
486  if (z >= 1.0){
487  depth = 0.0;
488  } else {
489  BIASASSERT(zFar_!=zNear_);
490  BIASASSERT((zFar_ - (double)z*(zFar_-zNear_))!=0);
491  depth = zNear_*zFar_ / (zFar_ - (double)z*(zFar_-zNear_));
492  // the OpenGL depth is merely the z coordinate in the camera
493  // coordinate system, while the MIP depth is given by the distance
494  // between the point and the center of projection. Compute the MIP depth
495  // from the nvidia depth
497  BIASASSERT(ppb);
498  Vector3<double> pl, pos;
499  ppb->UnProjectLocal(BIAS::HomgPoint2D(x, y, 1.0), pos, pl);
500  BIASASSERT(!Equal(pl[2], 0.0));
501  pl /= pl[2];
502  depth *= pl.NormL2();
503  }
504  return depth;
505 }
virtual int EndDraw_(BIAS::glfFramebufferObject *theTarget=NULL)
int SetSimplePerspectiveCam(double fovyDEG, int imageWidth=-1, int imageHeight=-1)
BIAS::Vector4< int > lastFullGLViewport_
Remembering the last full viewport prevent unecessary calculations in AutoRescaleParams behaviour...
GLPPB encapsulates the opengl rendering interface for the projectionparameter classes.
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
void MakeProjectionMatrixNew(const ProjectionParametersPerspective &params, GLfloat nearZ, GLfloat farZ, unsigned int x0, unsigned int y0, unsigned int width, unsigned int height, bool useIdealK=false, bool flip=false)
Definition: glfMatrix.cpp:314
int XMLRead(const std::string &Filename)
derived classes must implement the function XMLIn which is called by this function XMLRead to read ev...
Definition: XMLBase.cpp:78
std::deque< BIAS::GLProjectionOutputAttachment * > outputAttachments_
virtual void SetClearColor(const BIAS::Vector4< float > &cc)
setclearcolor is pure virtual.
virtual void SetR(const BIAS::RMatrix &R)
Set orientation from rotation matrix R.
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual int GetPrincipal(double &PrincipalX, double &PrincipalY) const
Get principal point (in pixels relative to top left corner).
virtual void SetPrincipal(const double x, const double y)
Set principal point in pixels relative to top left corner, virtual overload to recalculate K_...
virtual void SetImageSize(const unsigned int w, const unsigned int h)
Set image dimensions (in pixels).
void AppendOutputAttachment(int type, std::vector< int > args=std::vector< int >())
bool ExtrinsicStateChanged_
Changes to the parameters or GL state that lead to new calculation of GL_MODELVIEW matrix...
virtual int BeginDraw_(BIAS::glfFramebufferObject *theTarget=NULL)
int SetGLViewport_(int lowerleftx, int lowerlefty, int sizex, int sizey)
bool IntrinsicStateChanged_
Changes to the parameters or GL state that lead to new calculation of GL_PROJECTION matrix...
int DrawWithMatchedParamsAndViewport_(int viewport[4], int imageWidth, int imageHeight, std::vector< SceneBase * > &scenes)
Takes care of adapting internal parameters and gl viewport by specified behaviour scheme...
Exception class used for run-time errors in the OpenGLFramework.
Definition: glfException.hh:79
void GetUndistortion(double &kc1, double &kc2, double &kc3, double &kc4) const
void SetIdealImageSize(unsigned int width, unsigned int height)
virtual BIAS::ProjectionParametersBase * GetMyselfAsProjectionParametersBase() const
the pure virtual GetMyselfAsProjectionParameterBase() forces the child classes to inherit from a proj...
virtual int Save(const std::string &filename) const
const std::string & GetMessageString() const
Returns the description of the error including the file name and line number where the error occured...
virtual int XMLRead(const std::string &Filename)
virtual void SetPose(const BIAS::Pose pose)
Set pose from pose object.
3D rotation matrix
Definition: RMatrix.hh:49
virtual int UpdateGLProjectionMatrix_(unsigned x0, unsigned y0, unsigned width, unsigned height)
Represents 3d pose transformations, parametrized as Euclidean translation and unit quaternion orienta...
Definition: Pose.hh:73
BIAS::GLProjectionParametersInterface::ViewingReshapeBehaviour AutoViewingMatchBehaviour_
virtual bool PoseValid() const
Check if current pose is valid.
int XMLWrite(const std::string &Filename, int CompressionLevel=0, bool AutoAddCompressionSuffix=true, std::string encoding="UTF-8") const
call this to add the class to a new xml tree and write it to the file Filename.
Definition: XMLBase.cpp:40
void SetIntrinsics(BIAS::ProjectionParametersBase *p)
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
Definition: Matrix.hh:185
std::deque< std::vector< int > > outputAttachmentOptions_
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &origin, Vector3< double > &direction, bool ignoreDistortion=false) const =0
Calculates the view ray, which belongs to the given position on the image plane, in local coordinates...
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
virtual int Draw_(std::vector< SceneBase * > &scenes, BIAS::glfFramebufferObject *theTarget=NULL)
Rendering with current matrices GLProjectionMatrix_, GLModelViewMatrix_.
A 4x4 matrix in native OpenGL format.
Definition: glfMatrix.hh:41
void Rescale(float ratio)
Returns the absolute world coordinate frame position of camera.
GLProjectionParametersPerspective & operator=(const GLProjectionParametersPerspective &glppp)
double GetFocalLength() const
Returns the focal length.
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
bool informScenesOfChange_
Abstract projection params have changed, scenes have to be informed about this.
ProjectionParametersPerspective & operator=(const ProjectionParametersPerspective &P)
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &pointOnRay, Vector3< double > &direction, bool IgnoreDistortion=false) const
calculates the viewing ray from the camera center (in the camera coordinate system) which belongs to ...
void GetIdealImageSize(unsigned int &width, unsigned int &height) const
void SetFocalLengthAndAspect(double f, double AspectRatio)
Set the current camera focal length in pixel and the a spect ratio.
virtual void Rescale(double ratio, const double offset=0.0)
Adapt internal parameters to resampled image.
virtual int XMLWrite(const std::string &Filename) const
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual const BIAS::Pose & GetPose() const
Return complete pose object.
virtual void Load() const
Loads the matrix in OpenGL.
Definition: glfMatrix.cpp:540
virtual void SetK(const KMatrix &K)
sets the internal parameters from a given KMatrix and updates the cached K and its inverse ...
virtual int DrawWithMatchedParamsAndViewport_(int viewport[4], int imageWidth, int imageHeight, std::vector< SceneBase * > &scenes)
Takes care of adapting internal parameters and gl viewport by specified behaviour scheme...
virtual void SetC(const BIAS::Vector3< double > &C)
Set projection center.
virtual int Load(const std::string &filename)
virtual int SetGLMatrices(bool forceUpdate=true)
Method loads the parameters into the projection and modelview Matrix.
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
class BIASGeometryBase_EXPORT HomgPoint2D
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429
virtual double Z2Depth_(const int x, const int y, const double z) const
class for rendering with projection parameters of ProjectionParametersPerspective ...