void CreateLookupTable( const calibu::CameraInterface<double>& cam_from, const Eigen::Matrix3d& R_onKinv, LookupTable& lut ) { const int w = cam_from.Width(); const int h = cam_from.Height(); // make sure we have mem in the look up table lut.m_vLutPixels.resize( w*h ); lut.m_nWidth = w; for( int r = 0; r < h; ++r) { for( int c = 0; c < w; ++c) { // Remap const Eigen::Vector3d p_o = R_onKinv * Eigen::Vector3d(c,r,1); Eigen::Vector2d p_warped = cam_from.Project(p_o); // Clamp to valid image coords. This will cause out of image // data to be stretched from nearest valid coords with // no branching in rectify function. p_warped[0] = std::min(std::max(0.0, p_warped[0]), w - 1.0 ); p_warped[1] = std::min(std::max(0.0, p_warped[1]), h - 1.0 ); // Truncates the values for the left image int u = (int) p_warped[0]; int v = (int) p_warped[1]; float su = p_warped[0] - (double)u; float sv = p_warped[1] - (double)v; // Fix pixel access for last row/column to ensure all are in bounds if(u == (w-1)) { u -= 1; su = 1.0; } if(v == (w-1)) { v -= 1; sv = 1.0; } // Pre-compute the bilinear interpolation weights BilinearLutPoint p; p.idx0 = u + v*w; p.idx1 = u + v*w + w; p.w00 = (1-su)*(1-sv); p.w01 = su *(1-sv); p.w10 = (1-su)*sv; p.w11 = su*sv; lut.SetPoint( r, c, p ); } } }
void CreateLookupTable( const std::shared_ptr<calibu::CameraInterface<double>>& cam_from, const Eigen::Matrix3d& R_onKinv, LookupTable& lut, int lookup_width, int lookup_height ) { const int cam_width = cam_from->Width(); const int cam_height = cam_from->Height(); if(lookup_width < 1 || lookup_height < 1){ if(lut.Height() == 0){ lookup_width = cam_width; lookup_height = cam_height; // make sure we have mem in the look up table lut.m_vLutPixels.resize( lookup_width*lookup_height ); lut.m_nWidth = lookup_width; }else{ lookup_width = lut.Width(); lookup_height = lut.Height(); } } double x_offset = (lookup_width - cam_width) / 2.0; double y_offset = (lookup_height - cam_height) / 2.0; for( int r = 0; r < lookup_height; ++r) { for( int c = 0; c < lookup_width; ++c) { // Remap const Eigen::Vector3d p_o = R_onKinv * Eigen::Vector3d(c - x_offset,r - y_offset,1); Eigen::Vector2d p_warped = cam_from->Project(p_o); // Clamp to valid image coords. This will cause out of image // data to be stretched from nearest valid coords with // no branching in rectify function. p_warped[0] = std::min(std::max(0.0, p_warped[0]), cam_width - 1.0 ); p_warped[1] = std::min(std::max(0.0, p_warped[1]), cam_height - 1.0 ); // Truncates the values for the left image int u = (int) p_warped[0]; int v = (int) p_warped[1]; float su = p_warped[0] - (double)u; float sv = p_warped[1] - (double)v; // Fix pixel access for last row/column to ensure all accesses are in bounds if(u == (cam_width-1)) { u -= 1; su = 1.0; } if(v == (cam_height-1)) { v -= 1; sv = 1.0; } // Pre-compute the bilinear interpolation weights BilinearLutPoint p; p.idx0 = u + v*cam_width; p.idx1 = u + v*cam_width + cam_width; p.w00 = (1-su)*(1-sv); p.w01 = su *(1-sv); p.w10 = (1-su)*sv; p.w11 = su*sv; lut.SetPoint( r, c, p ); } } }