/* * ===================================================================================== * * Filename: camera.cpp * * Description: Class for camera * * Version: 1.0 * Created: 03/19/2017 09:39:58 PM * Revision: none * Compiler: gcc * * Author: Martin Miller (MHM), miller7@illinois.edu * Organization: Aerospace Robotics and Controls Lab (ARC) * * ===================================================================================== */ #include "camera.h" #include /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera * Description: constructor *-------------------------------------------------------------------------------------- */ Camera::Camera (const char *fin) { YAML::Node config = YAML::LoadFile(fin); _K(0,0) = BINNING*config["camera_matrix"]["data"][0].as(); _K(0,1) = BINNING*config["camera_matrix"]["data"][1].as(); _K(0,2) = BINNING*config["camera_matrix"]["data"][2].as(); _K(1,0) = BINNING*config["camera_matrix"]["data"][3].as(); _K(1,1) = BINNING*config["camera_matrix"]["data"][4].as(); _K(1,2) = BINNING*config["camera_matrix"]["data"][5].as(); _K(2,0) = BINNING*config["camera_matrix"]["data"][6].as(); _K(2,1) = BINNING*config["camera_matrix"]["data"][7].as(); _K(2,2) = config["camera_matrix"]["data"][8].as(); _d[0] = config["distortion_coefficients"]["data"][0].as(); _d[1] = config["distortion_coefficients"]["data"][1].as(); _d[2] = config["distortion_coefficients"]["data"][2].as(); _d[3] = config["distortion_coefficients"]["data"][3].as(); _T(0,0) = config["T_cam_imu"][0][0].as(); _T(0,1) = config["T_cam_imu"][0][1].as(); _T(0,2) = config["T_cam_imu"][0][2].as(); _T(0,3) = config["T_cam_imu"][0][3].as(); _T(1,0) = config["T_cam_imu"][1][0].as(); _T(1,1) = config["T_cam_imu"][1][1].as(); _T(1,2) = config["T_cam_imu"][1][2].as(); _T(1,3) = config["T_cam_imu"][1][3].as(); _T(2,0) = config["T_cam_imu"][2][0].as(); _T(2,1) = config["T_cam_imu"][2][1].as(); _T(2,2) = config["T_cam_imu"][2][2].as(); _T(2,3) = config["T_cam_imu"][2][3].as(); _T(3,0) = config["T_cam_imu"][3][0].as(); _T(3,1) = config["T_cam_imu"][3][1].as(); _T(3,2) = config["T_cam_imu"][3][2].as(); _T(3,3) = config["T_cam_imu"][3][3].as(); } /* ----- end of method Camera::Camera (constructor) ----- */ /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera :: Rc2b * Description: Returns the rotation matrix that transforms a point from the * camera frame to the body frame. *-------------------------------------------------------------------------------------- */ Matrix Camera::Rc2b ( ) const { #ifdef DOYAWCORRECT double yaw; yaw = M_PI*( YAWCORRECT )/180.; Matrix Ry; Ry = Eigen::AngleAxisd(yaw, Vector3d::UnitZ()); return Ry*_T.block<3,3>(0,0).transpose(); #else return _T.block<3,3>(0,0).transpose(); #endif } /* ----- end of method Camera::Rc2b ----- */ /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera :: Rc2b4 * Description: Returns the 4x4 Rc2b matrix *-------------------------------------------------------------------------------------- */ Matrix Camera::Rc2b4 ( ) const { #ifdef DOYAWCORRECT double yaw; yaw = M_PI*( YAWCORRECT )/180.; Matrix Ry; Ry = Eigen::AngleAxisd(yaw, Vector3d::UnitZ()); Matrix R; R = Matrix::Identity(); R.block<3,3>(0,0) = Ry*Rc2b(); #else Matrix R; R = Matrix::Identity(); R.block<3,3>(0,0) = Rc2b(); #endif return R ; } /* ----- end of method Camera::Rc2b4 ----- */ /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera :: K4 * Description: Returns the 4x4 camera matrix. *-------------------------------------------------------------------------------------- */ Matrix Camera::K4 ( ) const { Matrix K4; K4 = Matrix::Identity(); K4.block<3,3>(0,0) = K(); return K4 ; } /* ----- end of method Camera::K4 ----- */ /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera :: K * Description: Returns the 3x3 camera matrix. *-------------------------------------------------------------------------------------- */ Matrix Camera::K ( ) const { return _K ; } /* ----- end of method Camera::K ----- */ cv::Matx33d Camera::K (int x) const { cv::Matx33d k; k << _K(0,0), _K(0,1), _K(0,2), _K(1,0), _K(1,1), _K(1,2), _K(2,0), _K(2,1), _K(2,2); return k; } /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera :: d * Description: Returns the distortion coefficients. *-------------------------------------------------------------------------------------- */ Vector4d Camera::d ( ) const { return _d; } /* ----- end of method Camera::d ----- */ cv::Vec4d Camera::d ( int x ) const { return cv::Vec4d( _d(0), _d(1), _d(2), _d(3)); } /* *-------------------------------------------------------------------------------------- * Class: Camera * Method: Camera :: img2body * Description: Returns image points (pixel coordinates) in the body frame. * That is xi: -> K -> xc -> Rc2b -> xb, the point is tranformed to the camera * frame by K and to the body frame by Rc2b. *-------------------------------------------------------------------------------------- */ Vector3d Camera::img2body ( const Vector3d &xi ) const { Vector3d xc, xb; xc = K().inverse()*xi; // Normalize xc /= xc.norm(); xb = Rc2b()*xc; return xb; } /* ----- end of method Camera::img2body ----- */ Vector3d Camera::body2img ( const Vector3d &xb ) const { Vector3d xc,xi; xc = Rc2b().transpose()*xb; xi = K()*xc; xi /= xi[2]; return xi; } /* ----- end of method Camera::body2img ----- */ Vector3d Camera::principalPoint ( ) const { return _K.col(2); } /* ----- end of method Camera::principalPoint ----- */ cv::Mat Camera::warpPatch ( const cv::Mat &p, const Quaterniond &q0, const Quaterniond &q1 ) const { cv::Mat w; Matrix R; R = Rc2b().transpose() * q1.toRotationMatrix().transpose() * q0.toRotationMatrix() * Rc2b(); cv::Matx23d Rmat; Rmat << R(0,0), R(0,1), R(0,2), R(1,0), R(1,1), R(1,2); //R(2,0), R(2,1), R(2,2); cv::Size sz(PATCHSIZE,PATCHSIZE); cv::warpAffine(p, w, Rmat, sz); return w; } /* ----- end of method Camera::warpPatch ----- */ cv::Mat Camera::reflectPatch( const cv::Mat &p, const Quaterniond &q0, const Quaterniond &q1 ) const { Matrix3d R,tc; Vector3d nw(0.,0.,-1.); Vector3d c(0,0,1); cv::Size sz(PATCHSIZE,PATCHSIZE); tc = Matrix3d::Identity()+Rc2b().transpose()*q1.toRotationMatrix().transpose()*(PATCHSIZE+1)*nw*c.transpose(); R = Rc2b().transpose() * q1.toRotationMatrix().transpose() * (Matrix3d::Identity()-2*nw*nw.transpose())* q0.toRotationMatrix() * Rc2b() * tc; cv::Matx23d Rmat; cv::Mat w; Rmat << R(0,0), R(0,1), R(0,2), R(1,0), R(1,1), R(1,2); cv::warpAffine(p,w,Rmat,sz); return w; } /* ----- end of method Camera::warpPatch ----- */ double Camera::roll(const Quaterniond &q) const { return atan2( 2*(q.w()*q.x() + q.y()*q.z()), 1-2*(q.x()*q.x() + q.y()+q.y())); } double Camera::pitch(const Quaterniond &q) const { return asin( 2*(q.w()*q.y() - q.z()*q.x())); }