您的位置:首页 > 科技 > IT业 > 【代码详解】点云融合dypcd方法

【代码详解】点云融合dypcd方法

2024/12/23 12:37:38 来源:https://blog.csdn.net/YuhsiHu/article/details/139870931  浏览:    关键词:【代码详解】点云融合dypcd方法

MVS深度图估计之后,需要融合成点云提交给benchmark来评测,而融合方式和实现版本多种多样,参数也丰俭由人,所以一直是trick高发区。今天来详解一下其中的dypcd融合。

该方法最初应该是由D2HC-RMVSNet提出,这篇文章是ECCV 2020的spotlight。该方法在tanks and temples上效果不错,后续逐渐被广泛使用。

这个融合主要有两个函数,一个是filter_depth,一个是check_geometric_consistency。本文会省去读取深度图保存点云等操作的解读,主要讲每个超参数被如何使用,它们怎样影响到点云融合结果。

这套融合方法,细究之下,其实有这些参数:

  • s,指从几开始迭代
  • e,指迭代到几结束
  • dist_base绝对距离误差
  • rel_diff_base相对距离误差

filter_depth

读取深度图,但是不是所有pixel都valid,需要判断超过conf置信度的才使用,所以我们首先有这么个光度一致性的mask。

confidence = read_pfm(os.path.join(out_folder, 'confidence/{:0>8}.pfm'.format(ref_view)))[0]
photo_mask = confidence > args.conf

接下来要有几何一致性了。

        # compute the geometric maskgeo_mask_sum = 0dy_range = egeo_mask_sums = [0] * (dy_range - s)for src_view in src_views: # 10 views# camera parameters of the source viewsrc_intrinsics, src_extrinsics = read_camera_parameters(os.path.join(scan_folder, 'cams/{:0>8}_cam.txt'.format(src_view)))# the estimated depth of the source viewsrc_depth_est = read_pfm(os.path.join(out_folder, 'depth_est/{:0>8}.pfm'.format(src_view)))[0]masks, geo_mask, depth_reprojected, x2d_src, y2d_src, x2d_reprojected, y2d_reprojected = check_geometric_consistency(ref_depth_est, ref_intrinsics,ref_extrinsics, src_depth_est,src_intrinsics, src_extrinsics, confidence)geo_mask_sum += geo_mask.astype(np.int32)for i in range(s, dy_range):geo_mask_sums[i - s] += masks[i - s].astype(np.int32)

注意这里开始出现超参数了。对于每一个src视角,都会得到一个geo_mask,这个变量的含义是该像素在该视角的时候是不是几何一致的,而geo_mask_sum在不断的添加geo_mask,其实是在统计,这么些src视角当中,这个像素,在多少个视角哪是几何一致的。

这个最后从s到dy_range的循环当中,其实就是我们前面所说的从几开始迭代到几结束,因为dy_range=e在前面赋值了。这里的含义是,在某阶段i,有前i个view都满足条件。

再看后面的代码,会发现:

        geo_mask = geo_mask_sum >= dy_rangefor i in range(s, dy_range):geo_mask = np.logical_or(geo_mask, geo_mask_sums[i - s] >= i)final_mask = np.logical_and(photo_mask, geo_mask)

这里geo_mask第一次赋值得到的是在mask累加之后要所有视角下都能满足几何一致性,这个条件是很严格的,如果只有这一步,那满足条件的点就太少了。因此,紧接着开始放宽松条件,逐步把更多的点纳入进来。这个逻辑或当中添加的像素,似乎在说如果前i个view能满足某种条件的数量足够多那也是可以的。那我们不禁好奇,这个check_geometric_consistency函数返回来的masks和geo_mask到底分别表示什么含义。于是我们顺理成章地进入到这一个函数中查看。

check_geometric_consistency

    depth_diff = np.abs(depth_reprojected - depth_ref)relative_depth_diff = depth_diff / depth_refmask = Nonemasks = []for i in range(s, e):mask = np.logical_and(dist < i * dist_base, relative_depth_diff < math.log(max(i, 1.05), 10) * rel_diff_base)masks.append(mask)

在这里,我们发现,出现了新的超参数dist_base和rel_diff_base,这两个变量涉及到了重投影误差的threshold,即到底小于多少的绝对误差和相对误差才是可以被接受的。

通过循环我们发现,从s开始到e,base的倍数在不断加大,只有绝对误差和相对误差同时小于阈值的像素,才会被视为有效。而masks变量在不断记录的是:在当前i这个倍数下,哪些像素是符合该要求的。

观察返回值我们发现包括masks与mask,刚好对应了filter_depth里面的masks和geo_mask。可见,geo_mask对应的是:在最宽松的约束下(i为e-1的时候),哪些像素是可靠的;masks对应的是,在第i次迭代的时候(条件更严格的时候),哪些像素是可靠的。这些针对每个src view的统计最终被汇聚到了geo_mask和geo_mask_sums中,来表征在各个条件下,有多少个视角认为该像素可靠。

总结

通过这个分析,我们发现,该融合方法的整体思路是:在每个视角下,都按照从严格到宽松来不断纳入新的点,并且对每次迭代放宽条件之后的mask进行记录,最后把所有视角的mask综合到一起来判断。并且,综合判断的思路是,如果该像素在很严苛的范围内(比如绝对误差和相对误差都很小,i=2就满足了)满足条件,那它并不需要所有视角都赞同,相反地,如果误差越大,那么就需要更多的src view都支持它有效,才可以被纳入考虑。

除了距离base之外,迭代的起始与终止也会影响到融合。大体上描述的话,s设得越小,就越宽松,也对异常值越敏感,比如有2个view觉得啊对对对,但是其他view都觉得不行,也会被纳入有效;end设得越小,就越严格,虽然给予的base空间更大了,但是需要大多数都同意有效才可以。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com