经过densify后生成的scene数据保存有point对应的image信息,在densify过程中,reference imgae与neighboring image 做过尺度统一的处理(可参考作者另一篇博文??),因此需要reset solution
scene.pointcloud.pointWeights.Release()
bUseConstantWeight //considers all view weights 1 instead of the available weight
bool Scene::ReconstructMesh(float distInsert, bool bUseFreeSpaceSupport, unsigned nItersFixNonManifold,
float kSigma, float kQual, float kb,
float kf, float kRel, float kAbs, float kOutl,
float kInf
)
Exploiting Visibility Information in
Surface Reconstruction to Preserve Weakly Supported Surfaces
代码阅读笔记见作者另一篇博文 :链接
Incrementally
O && 已构建的DT的顶点P的重投影距离—阈值( 代码中为:distInsert^2)比较:
若不满足,则不添加该点,但visibility info更新(alpha(3D point) +1;
若不满足,则insert该点,visibility info初始化(alpha(3D point)=1)
重投影: 将O与P重投影到所有与o相关的视图上,
只要有一个视图
满足条件far enough即可
---------------------搜寻需要与O判断的P------------------------------
1). locate O –cell(DT)
const cell_handle_t c(delaunay.locate(p, lt, li, lj, hint->cell()));
---------------------------------
// Returns the (finite or infinite) cell p lies in.
// Starts at cell "start".
// If lt == OUTSIDE_CONVEX_HULL, li is the index of a facet separating p
// from the rest of the triangulation
// In dimension 2 :
// returns a facet (Cell_handle,li) if lt == FACET
// returns an edge (Cell_handle,li,lj) if lt == EDGE
// returns a vertex (Cell_handle,li) if lt == VERTEX
// If lt == OUTSIDE_CONVEX_HULL, li, lj gives the edge of c separating p
// from the rest of the triangulation
// lt = OUTSIDE_AFFINE_HULL if p is not coplanar with the triangulation
exact_locate(const Point& p, Locate_type& lt, int& li, int& lj,
Cell_handle start, bool *could_lock_zone)
2). cell 中离O最近的vertex –P(1个)
nearest = delaunay.nearest_vertex_in_cell(p, c);
---------------------搜寻需要与O判断的P------------------------------
3). 重投影判断
if (!IsDepthSimilar(pn.z, pe.z) || normSq(Point2f(pn)-Point2f(pe)) > distInsertSq)
4). 更新visibility info
hint->info().InsertViews(pointcloud, idx);
InsertViews()
函数内部实现 (二选一):
- view_t初始化:
views.InsertAt(idx, view_t(viewID, weight)); //将3D point O 的可见视图深入到view_t( 带有weight)
- view_t自增:
views[idx].weight += weight;//weight = 1
struct view_t {
PointCloud::View idxView; // view index
Type weight; // point's weight
……}
delaunay.insert( p)
PRE:
- DT生成过程,vertex只包含3D point,生成的DT包括有限DT +无限DT,通过相机视锥体与无限DT所决定的有限face,以及store the finite facet of the infinite cells,使整个face覆盖的空间为3D point + Camera
(对应操作如下1 && 2)
- 同时,将包含相机的DT视作outside,初始化该DT的s-edge weight
(对应操作如下:3)
//store the finite facet of the infinite cells
hullFacets.push_back(facet);
// Given a cell and a camera inside it, if the cell is infinite,
// find all facets on the convex-hull and inside the camera frustum,
// else return all four cell's facets
template <int FacetOrientation>
void fetchCellFacets(const delaunay_t& Tr, const std::vector<facet_t>& hullFacets, const cell_handle_t& cell, const Image& imageData, std::vector<facet_t>& facets)
// link all cells contained by the camera to the source ---outside!!!
infoCells[f.first->info()].s = kInf; ----DT-s 的权重已经在此设置,为常数kInf
重要:
- 并不是所有DT都与需要设置DT-s权重,只有
由camera fetch得到的face,与其相关的DT(代码如下)
设置该权重本质:
部分置信度极低的DT-s edge已经剔除,置信度较高的DT才生成DT-s edge
camCell.cell = delaunay.locate(MVS2CGAL(camera.C));
media
遍历(c,p)间或者延长线间的DT face,核心函数intersect(),会输出out_face,即 所有in_face的邻接DT的其他face,从而实现遍历作用
const edge_cap_t alpha_vis(view.weight);
//view.weight 在DT三角化过程中计算得到(见上)
const edge_cap_t w(alpha_vis*(1.f-EXP(-SQUARE((float)inter.dist)*inv2SigmaSq)))
在graph构建的过程中,只有DT间face所代表的edge的权重,需要引入surface quality,与可视性权重加权【kQual】相加---与参考论文一致
endCell
)相关的权重(L_DT的定义见参考论文)const cell_handle_t endCell(delaunay.locate(segEndPoint.source(), vi->cell()));
alpha_vis
累加t += alpha_vis;
//代码实现,基于f(face),核心函数如下:
// Given a cell, compute the free-space support for it
edge_cap_t freeSpaceSupport(const delaunay_t& Tr, const std::vector<cell_info_t>& infoCells, const cell_handle_t& cell)
const edge_cap_t q((1.f - MINF(computePlaneSphereAngle(delaunay, facet_t(ci,i)), computePlaneSphereAngle(delaunay, facet_t(cj,j))))*kQual);
graph.AddEdge(ciID, cjID, ciInfo.f[i]+q, cjInfo.f[j]+q);
相关概念见链接