针孔模型
xi=PXi=K[R∣t]Xi[uiviwi]=[f∗kucuf∗kvcv1][txR3×3tytz][XiYiZiWi] x_i = PX_i = K[R|t]X_i \\ \begin{bmatrix} u_i\\ v_i\\ w_i\\ \end{bmatrix} = \begin{bmatrix} f*k_u & & c_u \\ & f*k_v & c_v \\ & & 1\\ \end{bmatrix} \begin{bmatrix} & & & t_x \\ & R_{3 \times 3} & & t_y \\ & & & t_z \\ \end{bmatrix} \begin{bmatrix} X_i\\ Y_i\\ Z_i\\ W_i\\ \end{bmatrix} xi=PXi=K[R∣t]Xi⎣⎡uiviwi⎦⎤=⎣⎡f∗kuf∗kvcucv1⎦⎤⎣⎡R3×3txtytz⎦⎤⎣⎢⎢⎡XiYiZiWi⎦⎥⎥⎤
t
的物理意义是世界坐标系原点在相机坐标系下的位置。相机坐标系原点在世界坐标系下的位置是C=−R−1tC=-R^{-1}tC=−R−1t
相机内参模型
-
Pinhole_Intrinsic : public IntrinsicBase
:经典的相机模型M1,包括焦距、主点和图像大小 -
Pinhole_Intrinsic_Radial_K1 : public Pinhole_Intrinsic
:M1+单参数径向畸变 -
Pinhole_Intrinsic_Radial_K3 : public Pinhole_Intrinsic
:M1+3个参数径向畸变 -
Pinhole_Intrinsic_Brown_T2 : public Pinhole_Intrinsic
:M+3个参数径向畸变+2个参数的次要畸变 -
Pinhole_Intrinsic_Fisheye : public Pinhole_Intrinsic
:鱼眼相机 -
径向畸变
xdistorted=x(1+k1r2+k2r4+k3r6)ydistorted=y(1+k1r2+k2r4+k3r6) x_{distorted} = x( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6) \\ y_{distorted} = y( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6)\\ xdistorted=x(1+k1r2+k2r4+k3r6)ydistorted=y(1+k1r2+k2r4+k3r6)
- 次要畸变,因为透镜和成像平面没有对齐
xdistorted=x+[2p1xy+p2(r2+2x2)]ydistorted=y+[p1(r2+2y2)+2p2xy] x_{distorted} = x + [ 2p_1xy + p_2(r^2+2x^2)] \\ y_{distorted} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy]\\ xdistorted=x+[2p1xy+p2(r2+2x2)]ydistorted=y+[p1(r2+2y2)+2p2xy]
// Setup a simple pinhole camera at origin
// Pinhole camera P = K[R|t], t = -RC
Mat3 K;
K << 1000, 0, 500,
0, 1000, 500,
0, 0, 1;
PinholeCamera cam(K, Mat3::Identity(), Vec3::Zero());
const std::vector<EINTRINSIC> vec_camera_model_type =
{
PINHOLE_CAMERA,
PINHOLE_CAMERA_RADIAL1, PINHOLE_CAMERA_RADIAL3,
PINHOLE_CAMERA_BROWN,
PINHOLE_CAMERA_FISHEYE
};
std::shared_ptr<IntrinsicBase> intrinsic(nullptr);
intrinsic = std::make_shared<Pinhole_Intrinsic>
(width, height, focal, ppx, ppy);
intrinsic = std::make_shared<Pinhole_Intrinsic_Radial_K1>
(width, height, focal, ppx, ppy);
intrinsic = std::make_shared<Pinhole_Intrinsic_Radial_K3>
(width, height, focal, ppx, ppy);
intrinsic = std::make_shared<Pinhole_Intrinsic_Brown_T2>
(width, height, focal, ppx, ppy);
//IO
std::ofstream stream(filename, std::ios::binary | std::ios::out);
CHECK(stream.is_open());
cereal::JSONOutputArchive archive(stream);
archive(cereal::make_nvp("intrinsics", intrinsic));
td::ifstream stream(filename, std::ios::binary | std::ios::in);
CHECK(stream.is_open());
cereal::JSONInputArchive archive(stream);
archive(cereal::make_nvp("intrinsics", intrinsic));
const Pinhole_Intrinsic_Brown_T2 cam(1000, 1000, 1000, 500, 500,
// K1, K2, K3, T1, T2
-0.054, 0.014, 0.006, 0.001, -0.001);
部分参数优化
Pinhole_Intrinsic cam;
// Parametrized by 3 parameters:
// 0 -> the focal,
// 1,2 -> the principal point
const std::vector<int> param_filter =
cam.subsetParameterization(Intrinsic_Parameter_Type::NONE);//向量包含(1,2,3)就是都不优化,保持不变
//Intrinsic_Parameter_Type::ADJUST_ALL
//Intrinsic_Parameter_Type::ADJUST_FOCAL_LENGTH
//Intrinsic_Parameter_Type::ADJUST_PRINCIPAL_POINT
//Intrinsic_Parameter_Type::ADJUST_DISTORTION
//Intrinsic_Parameter_Type::ADJUST_PRINCIPAL_POINT | Intrinsic_Parameter_Type::ADJUST_DISTORTION
c++技巧
//删除文件
stlplus::file_delete(filename)
//保存为json
源代码
Camera_Common.hpp
命名空间是:openMVG::cameras
内容:
enum EINTRINSIC
:有小孔相机参数(无畸变)、加畸变的、鱼眼、球状static inline bool isPinhole ( EINTRINSIC eintrinsic )
static inline bool isSpherical( EINTRINSIC eintrinsic )
static inline bool isValid( EINTRINSIC eintrinsic )
enum class Intrinsic_Parameter_Type : int
:进行捆集调整时的选项inline constexpr Intrinsic_Parameter_Type operator|(Intrinsic_Parameter_Type x, Intrinsic_Parameter_Type y)
inline constexpr Intrinsic_Parameter_Type operator&(Intrinsic_Parameter_Type x, Intrinsic_Parameter_Type y)
c++知识:
-
static inline
函数在头文件中,希望该函数是inline
的。如果编译器不肯,那么就给弄成static
的。这样函数范围就限定在单个文件里了 -
enum class Intrinsic_Parameter_Type : int
:强类型枚举
强作用域:强类型枚举成员的名称不会被输出到其父作用域空间。
转换限制: 强类型枚举成员的值不可以与整型隐式的互相转换。
可以指定底层类型。默认类型是 int, 但也可以显式的指定类型。type 可以是除 wchar_t 以外的任何整型。 -
<type_traits>
:此头文件是类型支持库的一部分。
return static_cast<Intrinsic_Parameter_Type>
(static_cast<std::underlying_type<Intrinsic_Parameter_Type>::type>(x) |
static_cast<std::underlying_type<Intrinsic_Parameter_Type>::type>(y));
underlying_type
用来获取枚举常量对应的整数类型