OpenMVG、OpenMVS配置及学习记录(Win10+VS2015)

来源:互联网 发布:通信算法工程师笔试题 编辑:程序博客网 时间:2024/06/06 00:55

更新于2017年5月12日。


最近开始在做基于二维图像的三维重建项目,OpenMVG和OpenMVS可谓是必不可少的两个库,但网上配置及学习资料太少,花了整整一个月的时间才将库配置好,过程可谓艰难。本人也是入门级,此贴的目的在于将自己的经验分享给大家,给后来者提供一些方向和提示,望多交流,批评指正,可以加我微信(cppsujianpeng,注明“三维重建”),建群一起学习。OpenMVS是在OpenMVG的基础上的进一步操作,因此我们先来配置OpenMVG。

1、OpenMVG配置

首先需要一台比较“干净”的电脑,因为配置过程会用到许多的第三方库,以及对系统环境的配置,若电脑内已经装了类似opencv、boost等的,容易出现版本不匹配等各种意想不到的错误,因此建议还是删干净,或者是在虚拟机里搭(前提是电脑配置够好,不然跑不动程序),或者是用一台新的电脑,由于我笔记本之前就做图像处理,因此乱七八糟的东西很多,配了半个多月都没配好,最后还是在一台新的台式机上配置好的。另外,我的基本环境是Win10+VS2015,其他的环境没试过,不能保证可行。第二点是,本文在配置阶段主要参考了http://blog.csdn.net/mitsubishisony/article/details/52332470,然后根据自己的实际操作过程进行了一些补充,具体内容大家可以在http://download.csdn.net/detail/weixin_36408769/9838169下载。前面也说到,整个配置过程会使用到不少的第三方库,为了大家方便,特将相关的安装包提供给大家,共有三个压缩包1:http://download.csdn.net/detail/weixin_36408769/9838075  2:http://download.csdn.net/detail/weixin_36408769/9838077  3:http://download.csdn.net/detail/weixin_36408769/9838150。大家下载好后先把第三个安装包的cmake及git安装好。由于上传文件大小的限制,还有几个太大的文件放网盘了:链接:http://pan.baidu.com/s/1dF5oYtV 密码:2hdl。最后VS2015社区版的安装镜像文件也放在了网盘链接:http://pan.baidu.com/s/1pKCLPEF 密码:s9df,大家下一个虚拟光驱的软件就能运行了。

2、OpenMVG学习

openMVG提供了一个可以解决计算机视觉问题并构建完整SFM流程的小型库集合。下面对库的内容依次介绍。**图像库**图像容器:    OpenMVG Image <T>类可以存储灰度,RGB,RGBA或自定义的图像数据,提供基于像素的图像读写操作。基本方法如下:
// A 8-bit gray image:Image<unsigned char> grayscale_image_8bit;// A 32-bit gray image:Image<double> grayscale_image_32bit;// Multichannel image: (use pre-defined pixel type)// A 8-bit RGB image:Image<RGBColor> rgb_image_8bit;Image<Rgb<unsigned char> > rgb_image2_8bit;// 8-bit RGBA imageImage<RGBAColor> rgba_image_8bit;Image<Rgba<unsigned char> > rgba_image2_8bit;// 32 bit RGB image:Image<Rgb<double> > rgb_image_32bit;
图像I/O操作:
// Read a grayscale image (if conversion need, it is done on the fly)Image<unsigned char> gray_image;bool bRet = ReadImage("Foo.imgExtension", &gray_image);// Read a color imageImage<RGBColor> rgb_image_gray;bool bRet = ReadImage("Foo.imgExtension", &rgb_image);
图像绘制操作:
Image<unsigned char> image(10,10);image.fill(0);// Pixel access is done as matrix (row, line)int row = 2;int column = 4;image(row, column) = 127;// Horizontal scanlineDrawLine( 0, 5, w-1, 5, 255, &image);// Circle of radius 3 and center (5,5)const int radius = 3;const int x = 5, y = 5;DrawCircle(x, y, radius, (unsigned char)255, &image);// Ellipse of center (5,5) and (3,0const int radius1 = 3, radius2 = 1, angle = 0;const int x = 5, y = 5;DrawEllipse(x, y, radius1, radius2, (unsigned char)255, &image, (double)angle);// Example with a RGB imageImage<RGBColor> imageRGB(10,10);DrawCircle(x, y, radius, RGBColor(255,0,0), &imageRGB);

数学和线性代数库

该模块提供依赖于[Eigen]库的数学和线性代数工具。 Eigen是线性代数的C ++模板库。基本思想是提供给openMVG:

•用于矩阵和向量的高级别内存容器,
•容易的矩阵和向量操纵,
•数字求解器和相关算法的集合。
矢量,矩阵容器:
OpenMVG重新定义了代码一致性和清晰度的一些特征基类型(点,向量,矩阵):
•Vec2将单个2d点存储为列矩阵(x,y)
•Vec3将单个3d点存储为列矩阵(x,y,z)
•Vec2f,Vec3f浮点版本。
•Vec是一个值的向量(双精度)
•Vecf一个浮点值的向量
•Mat对于通用矩阵容器,
•Mat2X收集由2d列存储的列,
•Mat3X将3d点的集合存储为列。
// Create a set of 2D points store as column
//创建一组2D点存储为列
Mat2X A(2, 5);//2行5列
A << 1, 2, 3, 4, 5,
6, 7, 8, 9, 10;
A.col(); // return a column vector : (1,6)^T
A.row(); // return a row vector : (1,2,3,4,5)
线性代数
SVD/QR/LU 分解

特征库

该模块为特征和相关描述符提供通用容器。
特征:提供基本结构和IO来存储基于Point的特征。
存储点特征的类:PointFeature存储特征的位置(x,y)。SIOPointFeature存储特征(x,y,s,o)的位置,方向和尺度。

特征描述符:提供描述符数据的基本结构和IO。
模板

// SIFT like descriptorusing siftDescriptorData Descriptor<float, 128>;// SURF like descriptorusing surfDescriptorData = Descriptor<float, 64>;// Binary descriptor (128 bits)using binaryDescriptor_bitset = Descriptor<std::bitset<128>,1> binaryDescriptor_bitset;// or using unsigned charsusing binaryDescriptor_uchar = Descriptor<unsigned char, 128/sizeof(unsigned char)>;

特征点集:
存储特征点及其相关描述符:

template<typename FeaturesT, typename DescriptorsT> class KeypointSet
// Define SIFT Keypoints:// Define the SIFT descriptor [128 floating point value]using Descriptor<float, 128> DescriptorT;// Use SIFT compatible features (scale, orientation and position)using FeatureT = SIOPointFeature;// Describe what a collection of local feature is for a given image:using FeatsT = std::vector<FeatureT>;using DescsT = std::vector<DescriptorT>;// Link features and their descriptors as a collection:using KeypointSetT = KeypointSet<FeatsT, DescsT>;

相机库

该模块提供不同的相机模型。针孔相机模型:相机可以由投影模型近似,通常称为针孔投影。 相机的最简单的表示是光敏表面(传感器):图像平面,在给定位置处的透镜(投影投影)和空间中的取向。

针孔相机模型,定向中心投影摄像机

针孔摄像机几何模型的投影相机具有两个子参数,内在和外在参数。 内在参数对光学元件(无变形)进行建模,外在模型将相机的位置和方向置于空间中。 相机的投影描述如下:

这里写图片描述

内部参数:ku和kv通常为1,f表示焦距,cu和cv为主点,表示图像的理想中心。外部参数:R,t分别表示旋转矩阵和平移矩阵。

OpenMVG针孔相机模型

Pinhole_Intrinsic : public IntrinsicBase

classic pinhole camera (Focal + principal point and image size).焦距、主点与图像大小

Pinhole_Intrinsic_Radial_K1 : public Pinhole_Intrinsic

classic pinhole camera (Focal + principal point and image size) + radial distortion defined by one factor.使用一个因素设置径向畸变。

Pinhole_Intrinsic_Radial_K3 : public Pinhole_Intrinsic

classic pinhole camera (Focal + principal point and image size) + radial distortion by three factors.使用三个因素设置径向畸变。

Pinhole_Intrinsic_Brown_T2 : public Pinhole_Intrinsic

classic pinhole camera (Focal + principal point and image size) + radial distortion by three factors + tangential distortion by two factors.使用三个因素设置径向畸变,使用两个因素设置切向畸变。

Pinhole_Intrinsic_Fisheye : public Pinhole_Intrinsic

classic pinhole camera (Focal + principal point and image size) + fish-eye distortion by four factors.使用四个因素设置鱼眼畸变。

// Setup a simple pinhole camera at origin// Pinhole camera P = K[R|t], t = -RCMat3 K;K << 1000, 0, 500,     0, 1000, 500,     0, 0, 1;PinholeCamera cam(K, Mat3::Identity(), Vec3::Zero());

多视角库

多视角模板主要包括:用于在多视图几何中出现的2到n维视图几何约束的求解器的集合。一个通用框架“内核”可以嵌入这些求解器进行鲁棒估计。列出并解释了第一个可访问的解算程序,并记录了“内核”概念。

2维求解(2D到2D对应)

openMVG为以下几何估计提供求解器:仿射,同形异义,基本矩阵,7到n pt,8到n pt(直线变换)[HZ]。必要矩阵,8到n pt(直线变换)[HZ],5pt +内在参数[Stewenius],[Nister]。

N-View几何估计

三角测量,旋转,平移

单应性矩阵:

单应性矩阵绘制了一个平面的两个投影之间的关系。H是一个(3×3)矩阵,它将左右图像中的坐标与以下关系联系起来。

单应性矩阵以及点与点之间的约束
H可由四对以上的对应点估计出来。

基本矩阵:

基本矩阵是观察相同场景的两个图像之间的关系,其中这些点的投影在两个图像中是可见的。 给定两个视图之间的点对应:

这里写图片描述

F是(3×3)基本矩阵,它将点x与属于3D X点的投影的线相关联。F有七个自由度,需要至少七个以上的已知对应点关系才能进行计算。

相对姿态估计(本质矩阵)

向基本矩阵添加内在参数,得到本质矩阵,该本质矩阵将相机的相对位置与基本矩阵关系相连。

这里写图片描述

绝对姿态估计/相机切除(位姿矩阵)

给定3D-2D点对应的列表,可以计算相机姿态估计。 它包括估计右侧相机的相机参数,使3D点重新投影的残差可以最小化,这是一个优化问题,试图解决P参数,以便最小化:

这里写图片描述

openMVG 提供了三种不同的方法来解决这个问题:6pt直接线性变换[HZ],具有内在EPnP [EPnP]的4pt,3pt内在P3P [Kneip]。

内核概念

为了在通用的鲁棒估计框架中使用求解器,我们将它们与允许链接的Kernel类结合使用:

这里写图片描述

线型规划

其他内容参见http://openmvg.readthedocs.io/en/latest/

1 1
原创粉丝点击