相机类的抽象
上一个博客讲的是如何封装ORB-SLAM2,使其成为一项定位的服务,此举简单地解决了三维重建系统中每一帧的定位问题。该系统的输入是一组图像序列,目前来说,我们图像的输入是来自于磁盘,但或许以后系统实现实时的时候,图像的来源也可以是相机,所以我决定采用不失扩展性的方法来编写程序。
首先新建一个文件:Camera.h
为了让代码可以扩充各种各样的相机,我们先要约定好相机的标准。按经验,相机一般有三种操作:打开,关闭,读取一张图片。因此我们创建一个抽象的Camera类,作为其子类的接口约束:
class Camera
{
public:
virtual bool open(int index) = 0;
virtual void close() = 0;
virtual bool image(Mat & im) = 0;
virtual ~Camera() {}
};
一般来说,相机的打开会指定相机编号,因此open函数传入一个整数参数,作为相机编号。image函数表示从相机获得一张图片,并返回是否获得成功的标志。需要注意的是,该抽象类的析构函数需要是virtual的,以便使其子类能够正确析构。
但这样一个相机类也未免比较简单。在实际使用中,我们往往需要知道相机的一些参数,如其内矩阵、畸变向量,甚至是特殊相机的特殊参数,这些不仅在OBR-SLAM2中有用到,在三维重建的时候也是需要的。因此我们为Camera增设一个类,Parameter:
class Parameter
{
public:
/**
* @Title: load / save
* @Description: Set/save camera parameter by .yaml file.
* @param: dir, path of the file.
* @param: cam, name of the Parameter object in the setting file.
*/
virtual void load(const string & dir, const string & cam);
virtual void save(const string & dir, const string & cam);
void setIntrinsicMatrix(double fx, double fy, double cx, double cy);
void setDistortionVector(double k1, double k2, double p1, double p2, double k3 = 0.0);
void setResolution(int width, int height);
Mat getIntrinsicMatrix() const { return intrinsic; }
Mat getDistortion() const { return distortion; }
Size getResolution() const { return resolution; }
protected:
// These write and read functions must be defined for the serialization in FileStorage to work
friend void write(FileStorage & fs, const string & dir, const Parameter & x);
friend void read(const FileNode & node, Parameter & x, const Parameter & default_value);
Mat intrinsic, distortion;
Size resolution;
}
ORB-SLAM2是通过.yaml文件进行参数设置的,我打算仿照它的那种做法,因此,我的相机参数设置也是通过.yaml来操作的,具体实现在load函数与read函数:
void Camera::Parameter::load(const string