Matching Calibrated Ca…

xiaoxiao2021-02-28  129

最近在做数据集的时候,本来想用Unity简简单单就搞定了,没想到投影矩阵的计算和标定中的不一样,导致实验结果迟迟出不来,翻墙看到http://jamesgregson.blogspot.com/2011/11/matching-calibrated-cameras-with-opengl.html 这篇博文,mark一下,防止以后被墙

When working with calibrated cameras it is often useful to be able to display things on screen for debugging purposes.  However the camera model used by OpenGL is quite different from the calibration parameters from, for example, OpenCV.  The linear parameters that OpenCV provides are the following:

where (from http://en.wikipedia.org/wiki/Camera_resectioning) is the skew between the x and y axes, are the image principle point , with f being the focal length and being scale factors relating pixels to distance.  Multiplying a point by this matrix and dividing by resulting z-coordinate then gives the point projected into the image. The OpenGL parameters are quite different.  Generally the projection is set using the glFrustumcommand, which takes the left, right, top, bottom, near and far clip plane locations as parameters and maps these into "normalized device coordinates" which range from [-1, 1].  The normalized device coordinates are then transformed by the current viewport, which maps them onto the final image plane.  Because of the differences, obtaining an OpenGL projection matrix which matches a given set of intrinsic parameters is somewhat complicated. Roughly following this post, (update: a much-improved update from Kyle, the post's author isavailable here) the following code will produce an OpenGL projection matrix and viewport.  I have tested this code against the OS-X OpenGL implementation (using gluProject) to verify that for randomly generated intrinsic parameters, the corresponding OpenGL frustum and viewport reproduce the x and y coordinates of the projected point.  The code works by multiplying a perspective projection matrix by an orthographic projection to map into normalized device coordinates, and setting the appropriate box for the glViewport command.

1: 32:  33: void build_opengl_projection_for_intrinsics( Eigen::Matrix4d &frustum, int *viewport, double alpha, double beta, double skew, double u0, double v0, int img_width, int img_height, double near_clip, double far_clip ){ 34:  35:  36: // These parameters define the final viewport that is rendered into by 37:  38: // the camera. 39:  40: double L = 0; 41:  42: double R = img_width; 43:  44: double B = 0; 45:  46: double T = img_height; 47:  48:  49: // near and far clipping planes, these only matter for the mapping from 50:  51: // world-space z-coordinate into the depth coordinate for OpenGL 52:  53: double N = near_clip; 54:  55: double F = far_clip; 56:  57:  58: // set the viewport parameters 59:  60: viewport[0] = L; 61:  62: viewport[1] = B; 63:  64: viewport[2] = R-L; 65:  66: viewport[3] = T-B; 67:  68:  69: // construct an orthographic matrix which maps from projected 70:  71: // coordinates to normalized device coordinates in the range 72:  73: // [-1, 1]. OpenGL then maps coordinates in NDC to the current 74:  75: // viewport 76:  77: Eigen::Matrix4d ortho = Eigen::Matrix4d::Zero(); 78:  79: ortho(0,0) = 2.0/(R-L); ortho(0,3) = -(R+L)/(R-L); 80:  81: ortho(1,1) = 2.0/(T-B); ortho(1,3) = -(T+B)/(T-B); 82:  83: ortho(2,2) = -2.0/(F-N); ortho(2,3) = -(F+N)/(F-N); 84:  85: ortho(3,3) = 1.0; 86:  87:  88: // construct a projection matrix, this is identical to the 89:  90: // projection matrix computed for the intrinsicx, except an 91:  92: // additional row is inserted to map the z-coordinate to 93:  94: // OpenGL. 95:  96: Eigen::Matrix4d tproj = Eigen::Matrix4d::Zero(); 97:  98: tproj(0,0) = alpha; tproj(0,1) = skew; tproj(0,2) = u0; 99:  100: tproj(1,1) = beta; tproj(1,2) = v0; 101:  102: tproj(2,2) = -(N+F); tproj(2,3) = -N*F; 103:  104: tproj(3,2) = 1.0; 105:  106:  107: // resulting OpenGL frustum is the product of the orthographic 108:  109: // mapping to normalized device coordinates and the augmented 110:  111: // camera intrinsic matrix 112:  113: frustum = ortho*tproj 114:  115: }

貌似大神还用了Eigen库,之前安装为了模拟C++的Matlab功能用过但是无果,看起来很值得研究一下啊。

The code uses the Eigen linear algebra library, which conveniently stored matrices in column-major order, so applying the resulting frustum matrix is as simple as:

glMatrixMode(GL_PROJECTION);

glLoadMatrixd( &frustum(0,0) );

注意矩阵是列主元的

转载请注明原文地址: https://www.6miu.com/read-32746.html

最新回复(0)