大家好,又见面了,我是你们的朋友全栈君。
visualSFM:http://ccwu.me/vsfm/ (A visual structure from motion sysytem)
visualSFM是一个使用SFM方法(structure from motion)用于3D重建的GUI应用,这个重建系统融合了Changchang Wu的先前的几个工程: SIFT on GPU(SiftGPU), Multicore Bundle Adjustment, and Towards Linear-time Incremental Structure from Motion .,该系统的运行的速度很快,是因为采用了多核并发性用于特征提取,特征匹配和光束法平差(bundle adjustment) 。
为了用于稠密重建,这个工程还融合了 Yasutaka Furukawa 的 PMVS/CMVS,另外,visualSFM的SFM的输出结果是与几个其他的工具相结合产生的,包括有 CMP-MVS by Michal Jancosek, MVE by Michael Goesele’s research group, SURE by Mathias Rothermel and Konrad Wenzel, and MeshRecon by Zhuoliang Kang.
代表性的3D重建有如下步骤:
1.导入图像
Option 1. 选择”File->Open Multi Images”. z这个可以多次的加载图片。
Option 2. 选择”SfM->Load NView Match”. (选择一个包含相关图像路径的TXT文件)
Option 3. 选择”SfM->Load NView Match”. 然后文件类型选为 “All Jpegs in Folder” , ant select one.
Option 4. 点击1图标
2.图像匹配
选择”SfM->Pairwise Matching->Compute Missing Match”/点击2图标
这时还可以继续往里添加图片,再次计算。
该系统还允许使用自定义的特征提取和特征匹配,具体下面讲。
这个特征提取和特征匹配,使用的是siftGPU
3.稀疏重建
选择”SfM->Reconstruct Sparse” /点击3图标
这时光束法平差( Bundle Adjustment)步骤就会自动的使用多核光束法平差( Multicore Bundle Adjustment)
4.稠密重建
选择”Sfm->Reconstruct Dense” /点击4图标
稠密重建使用的 Yasutaka Furukawa 的 PMVS/CMVS,PMVS/CMVS的的相关参数存储在ni.ini文件中。
这时你会被提示保存[name].nvm 文件,并且CMVS将会在文件夹[name].nvm.cmvs中运行,如果你把重建保存为[name].nvm 文件,则[name].i.ply就是第i个模型的结果。
注1:当闲置时,可以保存sfm的工作空间”SfM->Save NView Match”. 默认被保存为 NVM格式,里面包含所有的工作空间信息。
注2: 还可以使用命令行进行软件操作进行三维重建
注3:visualSFM GUI可以没有这些库( SiftGPU/PBA and PMVS/CMVS)运行, SiftGPU是用于特征提取和特征匹配的, PBA用于稀疏重建, PMVS/CMVS 用于稠密重建。
SiftGPU & PBA 是增量式的GPU特征提取,且光束法平差用于SFM系统。
PMVS/CMVS 是用于visualSFM的稠密重建, Yasutaka Furukawa的最初的CMVS是 here .
硬件需求:
特征提取阶段需要一个合适的GPU( ATI/nVidia/Intel),特别是,需要有大的GPU内存(1GB),小的GPU内存会在特征提取时出问题,最新的siftgpu在一些平台上可以在intel的图像卡上工作。
Multicore Bundle Adjustment运行在nVidia CUDA或cpu上。
gpu不会在windows的远程桌面上工作,但可以使用 vnc用于远程工作。
当使用siftGPU时,对于高分辨率的图像需要注意的地方:
siftGPU特征提取有一个重要的且可修改的参数—— maximum_working_dimension=3200 (默认值)
给定一个图像,它的尺寸大小d=max(w,h), Lowe’s SIFT 最初的sift提取开始使用的图像大小为sz=2*d进行的上采样, siftGPU实际上开始时使用的图像大小为 sz’ = max{sz/2^i | sz/2^i <= maximum_working_dimension, 整数i >= 0},例如,如果你的图像大小为1024,1600,2048,3200,4000,在调整之后相应的大小分别为2048,3200,2048,3200,2000
这通常不是个问题,但有时你想去获得更多的特征得到更好的结果,所以你不会想把尺寸大小为4000的减小到2000,在这种情况下,有两种方法,可以这么做:option 1.如果你确定你有足够的内存去存储4000,你可以改变参数通过选择”Tools -> Enable GPU -> Set Maximum DIM”。option 2. 调整你输入的图像大小为3200。
另外,siftGPU可能会根据你的可利用的GPU内存再次进行下采样,这可能在小内存GPU上引起不希望得到的行为。
匹配时指定你自己的成对列表:
允许匹配部分的图像对,来代替做全匹配(full-pairwise matching),步骤如下:
1.写一个包含了图像对路径的txt文件,不要写入空路径。
2.把图像加载进visualSFM
3.这里使用”SfM->Pairwise Matching -> Compute Specified Match”,不要使用 “SfM->Pairwise Matching->Compute Missing Match”(这个做的全匹配)
4.你可以自己多次指定额外的列表
例如:你可以计算下列3对匹配
a.jpg b.jpg
a.jpg c.jpg
b.jpg c.jpg
对于简单的视频序列,如果你想匹配指定范围里的每两帧的匹配,使用”SfM->Pairwise matching->Compute Sequence Match”。对于大的数据集,你可以使用重建方法(词汇树或GIST聚类)去找到图像对去匹配。
使用你自己的图像匹配:(这个的前提是假设你已经发现了特征)
1.写一个包含所有的特征匹配的txt文件;
2.加载带有特征的图像进visualSFM;
3.使用”SfM->Pairwise Matching->Import Feature Matches”;
4.你可以再次使用同样的方法增加特征匹配。
匹配文件的格式如下:
Match file = <List of Image-Match>
Image-Match = <image1_path> <image2_path> <# of matches>
<List of 0-based feature indices in image1>
<List of 0-based feature indices in image2>
例如:下面给定888.jpg 和 709.jpg的24对匹配
888.jpg 709.jpg 24
19 18 24 3651 1511 2899 71 115 201 202 199 1639 2595 210 189 1355 268 241 137 728 1899 193 192 325
139 143 181 261 342 349 373 433 622 623 686 700 745 812 868 951 987 990 1001 1016 1021 1046 1047 1069
(其中888.jpg 的特征19匹配709.jpg的特征139)
Make sure the 0-based feature indices are within the correct ranges!
使用你自己的特征提取:
Option 1. 你可以写一个类似于 Lowe的SiftWin32.exe的 二进制的特征提取( binary feature detector),或者你可以写一个有着类似siftGPU界面的共享库。
Option 2. 写一个 Lowe的ASCII格式的.sift文件,它将会自动的转换为visualSFM的二进制格式
Option 3. 写一个下面格式的二进制格式的 .sift文件:
[Header][Location Data][Descriptor Data][EOF]
[Header] = int[5] = {name, version, npoint, 5, 128};
name = ( ‘S’ + ( ‘I’ <<8)+( ‘F’ <<16)+( ‘T’ <<24));
version = (‘V’+(‘4′<<8)+(‘.'<<16)+(‘0′<<24)); or (‘V’+(‘5′<<8)+(‘.'<<16)+(‘0′<<24)) if containing color info
npoint = number of features.
[Location Data] is a npoint x 5 float matrix and each row is [x, y, color, scale, orientation].
Write color by casting the float to unsigned char[4]
scale & orientation are only used for visualization, so you can simply write 0 for them
* Sort features in the order of decreasing importance, since VisualSFM may use only part of those features.
* VisualSFM sorts the features in the order of decreasing scales.
[Descriptor Data] is a npoint x 128 unsigned char matrix. Note the feature descriptors are normalized to 512.
[EOF] int eof_marker = (0xff+(‘E'<<8)+(‘O'<<16)+(‘F'<<24));
调整参数用于更高的速度:
很多的参数是存储在nv.ini文件中,这个文件在第一次程序运行时自动生成。
特征提取的速度:
在GUI模式中,使用 “Menu->Tools->Enable GPU->Customized Param”。
在控制模式中,使用 “VisualSFM sfm[+pmvs] input output [SiftGPU parameters]”。
你需要检查siftGPU文档中这些参数,通常这么做是没有意思的,除非你运行超出了图像内存。
特征匹配的速度:
参数 “param_gpu_match_fmax”是用于特征匹配时每副图像的特征的个数。它的默认值是8192 ,在很多情况下4000应该是足够了,注意,特征是按规模分类的,所以带有最大规模的特征将会被使用。
如果你知道图像的相邻图像,例如视频中的相邻帧,你应该指定一个成对列表用于特征匹配而不是使用全匹配。
存储结果(特别是NFS时)会花费大量的时间,一个beta特征能够的在linux下可以默认的提高效率的, 它可以通过设置 param_asynchronous_write= 0 or unchecking “Pairwise Matching->Asynchronous Writes”来失效。
增加重建的速度:
这有两个参数可以决定重建的速度:参数 “param_bundle_full_iteration” 是当对整个模型进行光束平差时的BA迭代的数目。 参数”param_bundle_full_frequency”控制着光束平差法执行的频繁程度。
增加稠密重建的速度:
参数 “param_cmvs_max_images”是CMVS的类的大小。
摄影机模型和相关的系统:
注意它是轻微不同于其他SFM软件的(例如bundler)
内部的摄影机模型有8个参数(如果径向畸变是不可用的话是7个参数)
Given camera K[R T], K = [f, 0 0; 0 f 0; 0 0 1], radial distortion r, and a 3D point X.
The reprojection in the image is [x, y, z]’ = K (RX + T) -> (x/z, y/z)’
Let the measurement be (mx, my), which is relative to principal point (typically image center)
The distortion factor is r2 = r * (mx * mx + my * my)
The undistorted measurement is (1 + r2) * (mx, my)
Then, the reprojection error is (x/z – (1 + r2) mx, y /z – (1 + r2) my)
注意参数是保存在 NVM文件中的,该文件是稍微不同于内部的表示, NVM文件的为每个摄像机保存如下的文件。
f, R (as quaternion), C = – R’T, rn = r * f * f.
PBA代码包含了加载NVM文件的功能和转换摄影机参数的功能。
径向畸变的模型是不同于其他软件的:
* Dan Costin provides an efficient code for undistorting the images under this model.
至于图像坐标系统,x轴点在右边,y轴点在下面,z轴点在前面。
主要的点是被假定为图像中心,除了使用了一个单个固定标定,当使用一个固定的标定 [fx, cx, fy, cy],误差在一个转换图像坐标系统中被估算。
K = [fx 0 0; 0 fx 0; 0 0 1], Kc = [1 0 cx; 0 fy/fx cy; 1],
You can see that Kc * K = [fx 0 cx; 0 fy cy; 0 0 1];
Let (u, v, 1)’ be an original feature location (relative to top-left corner of images)
The measurement is defined as (mx, my, 1)’ = Inv(Kc) * (u, v, 1)’
注意:特征定位保存在NVM文件中,该文件是一直与图像中心相关的而不是与标定主要点 [cx, cy]相关。
焦距初始化:
在像素点的焦距是根据EXIF自动的被计算的,焦距和 FocalplaneXRes/FocalplaneYRes 而不是使用一个CCD数据库。
提示:如果你调整JPEGS的大小保持原始的EXIF.
假如EXIF不包含这些信息,焦距被设为 1.2 * max(width, height),这相当于视角的中值。
visualSFM也支持使用一个单个的固定的标定 [fx, cx, fy, cy] 用于所有的图像。 使用 “SfM -> More functions -> Set Fixed Calibration”。
特征和匹配:
visualSFM自动的把特征提取和特征匹配保存在盘中,为每副图像保存文件名为[name]的特征提取和特征匹配为[name].sift和[name].mat,[name].sift存储所有的检测到的SIFT特征,[name].mat存储特征匹配。
提示:当加进新的照片时(或关闭/重新打开),visualSFM将仅仅匹配丢失的。
如果你想改变特征提取的参数,并且重新运行重建,你需要删除所有相关的[name].sift和[name].mat文件。
如果你想去返回读取匹配的结果,检查匹配文件代码 here,或者你可以使用 “SfM->Pairwise Matching->Export F-Matrix Matches”
输出的格式:N-View(NVM)
visualSFM把SFM工作空间保存在NVM文件中,NVM文件包含输入图像的路径和多个3D的模型。下面是格式描述:
NVM_V3 [optional calibration] # file version header
<Model1> <Model2> … # 多个重建模型
<Empty Model containing the unregistered Images> # number of camera > 0, but number of points = 0
<0> # 0 camera to indicate the end of model section
<Some comments describing the PLY section>
<Number of PLY files> <List of indices of models that have associated PLY>
这个 [optional calibration] 如果你使用 “Set Fixed Calibration” 功能时才存在。
FixedK fx cx fy cy
每一个重建模型 <model> 包含下面的:
<Number of cameras> <List of cameras>
<Number of 3D points> <List of points>
摄像机和3D点被保存成下面的格式:
<Camera> = <File name> <focal length> <quaternion WXYZ> <camera center> <radial distortion> 0
<Point> = <XYZ> <RGB> <number of measurements> <List of Measurements>
<Measurement> = <Image index> <Feature Index> <xy>
在 Multicore bundle adjustment代码的util.h检查LoadNVM功能,这个LoadNVM仅仅读取第一个模型,并且你应该重复去获得所有的。在 <File name>的空白中用 ‘\”‘替换。
可视化:
使用菜单项view去选择一个显示模型或者改变参数。
使用鼠标,键盘快捷键或者工具条按钮快速的切换。
可以把当前的视图保存为JPEG文件或者复制到内存中。
鼠标控制和导航:
在3D点模式下双击右键点击摄像机去显示挑选的图像。
在缩略图 模式下对图像左键双击 去显示挑选的图像。
在单个图像模式下双击右键返回先前的显示模型。
快捷键:
‘Z’ 缩放二维视图;重置三维视图.
‘backspace’ 返回到缩略图视图
‘TAB’ 转换稠密3D模式和稀疏3D模式
‘TAB’ switch between original image and its undistorted view
‘Pause’ show only points seen by current camera
‘T’ Switch between 3D visualization mode: camera+point/camera/point
‘S’ switch SIFT display style in single image view mode
‘F’ show/hide features in single image view mode
‘F’ show/hide camera in Dense reconstruction mode
‘A’ show/hide coordinate axis in dense/sparse reconstruction
‘left/right’ switch to previous/next image/pair…
‘up/down’ switch to previous/next 3D model
…
使用visualSFM容易的显示动画:
通过点击F4键增加当前的视图到动画列表,在增加了几个视图(不同的视图或者不同的视图模式)之后,点击一次F5并且你将看到保存视图的转换动画。双击F5,动画将会循环的播放。
通过人工干预的重建:
在GUI模式中,你可以暂停或恢复增量重建。寻找下面按钮: >>+ Resume, || Pause
如果这有不正确的注册相机,你可以删除他们。
在3D N-View Points Mode下,右键点击相机就可以选择相机。通过点击按钮就可以从3D模型中删除相机。
你也可以人工的选择初始化对。
小GPU内存的潜在问题:
默认的,当需要时siftGPU试图通过下采样图像去适合内存限制。在小GPU内存的很可能获得很少的特征。在不同的机器上会产生不同的结果。
你可以试图禁用下采样和重新实验:
1.删除所有的[name].sift和[name].mat文件。
2.选择 “Tools -> Enable GPU -> Customized Param”,在参数列表中增加 “-nomc”,意思是没有内存限制。
3.重新运行匹配和重建。
*.由于内存不足这个不能保证工作。
*.这个可能工作,且可能由于使用了虚拟的内存变得特别慢。
visualSFM的限制:
1.基于关键点重建仅适用于纹理表面。如果提取的特征太少将不会工作。(例如:白墙,统一颜色的物体)
2.增量式的重建方法有很多的限制:循环不总是关闭;初始化变得敏感(你可能需要试着人工初始化);对于退化的运动(如前进)不稳定;不能利用视频的连续性的运动。
3.这仅仅有一个径向参数,对于日常照片这是足够了,但是如果你的摄像机有大的畸变的话可能不会工作。
4.32位版本由于操作系统的限制可能会很容易就耗尽内存。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/151306.html原文链接:https://javaforall.cn