Orbeez-SLAM
2023-11-18 23:07:14 0 举报
AI智能生成
对Orbeez-slam代码中orbslam2和instant-ngp结合部分的一个解读
作者其他创作
大纲/内容
NerfMapping.cumpMap->frame();
mpTestbed->load_training_data(strSlamTransform);//在这里会对一些数据进行加载,主要加载了images.resize(result.n_images); result.xforms.resize(result.n_images); result.metadata.resize(result.n_images); result.pixelmemory.resize(result.n_images); result.depthmemory.resize(result.n_images); result.raymemory.resize(result.n_images);// 这个包括上面的容器大小都为0 result.info.depth_scale result.camera_distortion.params result.camera_distortion.mode = ECameraDistortionMode::Iterative; result.principal_point result.aabb_scale result.sharpness_data
m_network_config = load_network_config(m_network_config_path);// 就加载了base.json里的数据
分别创建了3个对象的模型:1、失真图模型:m_distortion2、普通训练模型:m3、贴图(背景)训练模型:m_envmap
reset_network();
mpTestbed->reload_network_from_file(network_config_path);// network_config_path = \"./Thirdparty/instant-ngp-kf/configs/nerf/base.json\"
mpTestbed->m_train = true;// 这里要求进行训练
mpTestbed->m_nerf.training.optimize_extrinsics = bTrainCameraWithPhotometric;// 是否要将光度误差加入到训练监督中
SetAcceptKeyFrames(false);// 首先不再接受关键帧
mpCurrentKeyFrame = mlNewKeyFrames.front();// 取出列表中最前面的关键帧,作为当前要处理的关键帧mlNewKeyFrames.pop_front();// 取出最前面的关键帧后,在原来的列表里删掉该关键帧
mpCurrentKeyFrame->ComputeBoW();// 计算该关键帧特征点的词袋向量,用于后续特征匹配
pMP->UpdateNormalAndDepth();// 获得该点的平均观测方向和观测距离范围
pMP->ComputeDistinctiveDescriptors();// 更新地图点的最佳描述子
if(!pMP->IsInKeyFrame(mpCurrentKeyFrame))// 如果地图点不是来自当前帧的观测
mlpRecentAddedMapPoints.push_back(pMP); // 将上述地图点放入mlpRecentAddedMapPoints,等待后续MapPointCulling函数的检验
else// 若地图点来自当前帧的观测(这些地图点可能来自双目或RGBD在创建关键帧中新生成的地图点,或者是CreateNewMapPoints 中通过三角化产生)
if(!pMP->isBad())
for(size_t i=0; i<vpMapPointMatches.size(); i++)// 对当前处理的这个关键帧中的所有的地图点展开遍历
mpCurrentKeyFrame->UpdateConnections();// 更新关键帧间的连接关系(共视图)
传入nerf的数据:稀疏点云,rbga图
font color=\"#ec7270\
ngp::TrainingXForm *pXform = std::get<0>(t);
int index = std::get<1>(t);
mpMap->AddKeyFrame(mpCurrentKeyFrame);// 将该关键帧插入到地图中
ProcessNewKeyFrame();// 处理缓冲队列第一个关键帧
规则1:已经是坏点(pMP->isBad()),直接从队列中剔除
规则2:跟踪到该地图点的帧数相比预计可观测到该地图点的帧数的比例小于25%(跟踪到地图点的帧数太少),把点设置为坏点,直接从队列中剔除
规则3:从该点建立开始,到现在已经过了不小于2个关键帧,同时观测到该点的相机数却不超过阈值cnThObs,把点设置为坏点,直接从队列中剔除
规则4:从建立该点开始,已经过了3个关键帧而没有被剔除,则认为是高质量的点,仅从队列中剔除
剔除地图点的规则:
MapPointCulling();// 剔除劣质地图点
CreateNewMapPoints();// 创建新地图点
SearchInNeighbors();// 融合当前关键帧和共视关键帧的MaoPoint(融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点)
if(!CheckNewKeyFrames())// 若新关键帧为空
KeyFrameCulling()// 如果至少存在三帧的地图点比当前共视关键帧pkf的质量好,会记录这些地图点的数量,只要这个地图点的数量超过了总有效地图点数的90%,就会剔除当前共视关键帧
原ORB-slam2执行了关键帧剔除的操作,Orbeez-slam没有执行,可能是为了获取更多的点进行nerf重建
if(mpMap->KeyFramesInMap()>2)// 只要地图中的关键帧数量大于2
if(!CheckNewKeyFrames() && !stopRequested())// 若新关键帧非空,同时不停止建图
mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);// 将当前帧加入到闭环检测队列中
if(CheckNewKeyFrames())// 若新关键帧非空
else if(Stop())// 若要终止当前线程,就终止当前线程
mpMap->update_transformsGPU();// 可能将地图点投射到另一个坐标系
map_points.push_back(map_point);
mpMap->frame();// 在这里会构建稀疏点云
ResetIfRequested();// mbResetRequested=false;
SetAcceptKeyFrames(true);// 开始接受关键帧
SetFinish();
while(1)
void NerfMapping::Run()
System.cu
m_nerf.sparse_map_points_positions_gpu.resize_and_copy_from_host(m_nerf.sparse_map_points_positions);// 应该是把cpu上的数据迁移到gpu上 m_nerf.sparse_ref_map_points_positions_gpu.resize_and_copy_from_host(m_nerf.sparse_ref_map_points_positions);// 将稀疏点数据分别存在m_nerf.sparse_map_points_positions_gpu和m_nerf.sparse_ref_map_points_positions_gpu上
m_nerf.sparse_map_points_positions.push_back(m_nerf.training.dataset.slam_point_to_ngp(map_point));// 加点操作,应该是把点放入了m_nerf.training.dataset中,但并没有放入颜色信息
clear_density_grid_sample_ct_msb();// 用于将体素网格中的占据信息全部置0
update_density_grid_sample_ct_sparse_point_cloud();// 这个和上面那个一样,只不过是检测的是参考点云中的体素网格是否被占用(ref_map_points)
generate_grid_map_points_nerf_nonuniform();// 满足一定条件则对某个体素网格的计数器进行加1操作,并记录这个网格中的所有点云数据其中,m_nerf.density_grid_sample_ct.data()这个数据应该是个多位二进制数,某一位表示的是这个体素位置是否存在点云数据density_grid_sample_ct[idx+grid_mip_offset(mip)] |= 0x80;其他位的数据可能包含着点云的坐标啥的,因为要加以区分,其中某一位应该还包含了体素的权重值,后面判断了权重值和阈值128的大小关系out = map_points_positions 只存储了体素网格中大于一定权值的点云,而这个点云在后续会送去构建稠密点云
最终添加的新的地图点是放在m_nerf.nerf_triangulation_map_points_positions中的,会先判断这里面的大小(因为一开始并没有往里面加点,所以数量应该是0),只要没加到300000个点,就会执行下面的操作(if(m_nerf.nerf_triangulation_map_points_positions.size() < 300000))
generate_grid_samples_nerf_nonuniform();// density_grid_positions存储了相对于边界框aabb的新的点云坐标,同时包含了一个进行了归一化或映射操作后的时间步长density_grid_indices存储了key的索引
update_density_grid_mean_and_bitfield(stream);// 处理密度网格的数据,并最终计算其均值以用于后续处理
if (m_training_step < 256)
后续分支和上面一致
else
if (m_training_step % n_prep_to_skip == 0)
查找叶子优化器并更新其设置
generate_training_samples_nerf// 这一步用于生成训练的样本,即要执行体素跳过策略,着重注意一下m_nerf.training.metadata_gpu这个变量
compute_loss_kernel_train_nerf// 计算颜色、深度损失来训练nerf
update_density_grid_sample_ct
bool train_camera = m_nerf.training.optimize_extrinsics || m_nerf.training.optimize_distortion || m_nerf.training.optimize_focal_length;// train_camera = false;
train_and_render(skip_rendering);// skip_rendering = true
子主题
bool Testbed::frame(){} //该函数内部用来训练NeRF网络
testbed.cu
对const uint32_t i = threadIdx.x + blockIdx.x * blockDim.x;的解释
变量解读
共视图
./build/rgbd_replica Vocabulary/ORBvoc.txt configs/RGB-D/Replica/office0.yaml Replica/office0/
{ \"loss\": { \"otype\": \"Huber\
Orb-slam2创建稀疏点云,instant-ngp利用稀疏点云训练NeRF,并产生稠密地图
收藏
0 条评论
回复 删除
下一页