zju3dv / EasyVolcap

[SIGGRAPH Asia 2023 (Technical Communications)] EasyVolcap: Accelerating Neural Volumetric Video Research
Other
577 stars 41 forks source link

在custom dataset上 L3MHET 训练效果不好 #26

Closed 463f closed 3 months ago

463f commented 4 months ago

Thks for sharing your amazing work !! 作者你好,我仿照actor1_4_seq自建数据集,并使用 SCHP 进行分割:

extri.yml
intri.yml
images
  - 00
    - 000000.jpg
    - ....
  - 01
mask

并尝试复现 README 中 L3MHET->volume_fusion->GaussianT 这一过程,命令和 README 给出的一致;并根据 custom_dataset.md 中的指导,仿照 renbodyneaurl3dv 编写配置文件。但 L3MHET 训练效果比较差,使用 test 输出渲染的 novel_view 感觉没有拟合:

image

我想问这是下面的配置文件不太合理导致的吗?或是有别的可能的原因呢?相机(8台)标定参数是准确的。 另外请问bounding box、near,far 这些的单位是什么呢?是如何确定的呢?比如是物理测量出多少米吗?

一些配置信息:

# configs/datasets/hangzhou/hangzhou.yaml
dataloader_cfg: # we see the term "dataloader" as one word?
    dataset_cfg: &dataset_cfg
        data_root: data/hangzhou/20231014093437
        use_masks: True
        use_vhulls: False
        immask_crop: True
        imbound_crop: True
        masks_dir: mask # seg with SCHP
        ratio: 0.5 # scale images down during loading (thus affects rendering and testing)

        # near: 12
        # far: 40
        bounds: [[-10.0, -10.0, -10.0], [10.0, 10.0, 10.0]]
        dist_opt_K: false # whether to resize the image so that after distortion, no black pixels will remain
        use_aligned_cameras: True

        frame_sample: [0, 45, 1] # [begin, end, step]. # 15(fps) * 3(sec) = 45 frames per camera, 200 or so is best, otherwise will OOM 
        view_sample: [0, 8, 1]

val_dataloader_cfg:
    dataset_cfg:
        <<: *dataset_cfg
        use_vhulls: False
        frame_sample: [0, 45, 15] # make rendering faster, controls which of the views and frames to load
    sampler_cfg:
        view_sample: [0, 8, 2] # make rendering faster, if doing IBR, change the view_sample in sampler_cfg to control which view to render

model_cfg:
    sampler_cfg:
        bg_brightness: 0.0
    renderer_cfg:
        bg_brightness: 0.0
    supervisor_cfg:
        msk_loss_weight: 0.001

viewer_cfg:
    use_window_focal: True
    camera_cfg:
        world_up: [0, -1, 0] # this dataset uses a strange camera system, align it when using the viewer
# configs/exps/l3mhet/l3mhet_hangzhou.yaml
configs:
    - configs/base.yaml # default arguments for the whole codebase
    - configs/models/l3mhet.yaml # network model configuration
    - configs/datasets/hangzhou/hangzhou.yaml # dataset usage configuration
    - configs/specs/optcam.yaml
    - configs/specs/transient.yaml

# prettier-ignore
exp_name: {{fileBasenameNoExtension}}
rexainn commented 4 months ago

同样的问题,我发现我无论怎么改bounds,l3mhet结果都不收敛,且psnr很低。

之前作者对near、far、bounds的解释:“near和far就是相机到场景的最近和最远距离,nerf方法会根据这个值去sample,enerf会根据这个值去建立cost volume。

bounding box就是世界坐标系下的场景的aabb(axis-aligned bounding box),用最小和最大xyz两个位置值表示,看一下我们提供的其他config,例如neural3dv.yaml应该就能知道如何在config里写bounds和near far了。”

xbillowy commented 4 months ago

感谢关注!

  1. 关于 near, far, bounds 的单位,这是由标定参数的单位决定的。如果你采用了 EasyMocap 中的标定方法,也就是使用了棋盘格来标定的话,那么只要你在标定过程中输入的棋盘格长度是真实测量的米为单位,那么标定得到的结果就是米为单位,在设置 near, far, bounds 这些参数时也是米为单位;如果你是根据 Dense Calibration of custom_dataset.mdscripts/colmap/run_colmap.py 标定的,也就是拍摄的场景中没有棋盘格标定板,你可能需要打开原始标定的点云,选取两个特征点得到标定距离(可以用 meshlab 的卷尺看),然后和真实场景长度算一个 scale,最后用 correct_colmap_scale() 函数调整标定参数的尺度。

  2. 关于 near, far, bounds 的设置建议我们在 Dataset Configuration section of custom_dataset.md 中有说明,简单来说,near, far 设置成相机到场景的大致最近和最远距离,然后 bounds 设置成以标定所得的世界坐标系中心为原点,一个大致能包含场景的 bounding box,原则上所有的光线的采样范围都是统一的 [near, far],然后会在此基础上计算每条光线和 bounding box 的交点,如果近处交点大于 near 就会更新 near,远处交点小于 far 就会更新 far

rexainn commented 4 months ago

感谢关注!

  1. 关于 near, far, bounds 的单位,这是由标定参数的单位决定的。如果你采用了 EasyMocap 中的标定方法,也就是使用了棋盘格来标定的话,那么只要你在标定过程中输入的棋盘格长度是真实测量的米为单位,那么标定得到的结果就是米为单位,在设置 near, far, bounds 这些参数时也是米为单位;如果你是根据 Dense Calibration of custom_dataset.mdscripts/colmap/run_colmap.py 标定的,也就是拍摄的场景中没有棋盘格标定板,你可能需要打开原始标定的点云,选取两个特征点得到标定距离(可以用 meshlab 的卷尺看),然后和真实场景长度算一个 scale,最后用 correct_colmap_scale() 函数调整标定参数的尺度。
  2. 关于 near, far, bounds 的设置建议我们在 Dataset Configuration section of custom_dataset.md 中有说明,简单来说,near, far 设置成相机到场景的大致最近和最远距离,然后 bounds 设置成以标定所得的世界坐标系中心为原点,一个大致能包含场景的 bounding box,原则上所有的光线的采样范围都是统一的 [near, far],然后会在此基础上计算每条光线和 bounding box 的交点,如果近处交点大于 near 就会更新 near,远处交点小于 far 就会更新 far

请问到场景的距离是到场景边界吗?我一直以为near就是bounds中绝对值最小的数,far就是绝对值最大的数。

xbillowy commented 4 months ago

感谢关注!

  1. 关于 near, far, bounds 的单位,这是由标定参数的单位决定的。如果你采用了 EasyMocap 中的标定方法,也就是使用了棋盘格来标定的话,那么只要你在标定过程中输入的棋盘格长度是真实测量的米为单位,那么标定得到的结果就是米为单位,在设置 near, far, bounds 这些参数时也是米为单位;如果你是根据 Dense Calibration of custom_dataset.mdscripts/colmap/run_colmap.py 标定的,也就是拍摄的场景中没有棋盘格标定板,你可能需要打开原始标定的点云,选取两个特征点得到标定距离(可以用 meshlab 的卷尺看),然后和真实场景长度算一个 scale,最后用 correct_colmap_scale() 函数调整标定参数的尺度。
  2. 关于 near, far, bounds 的设置建议我们在 Dataset Configuration section of custom_dataset.md 中有说明,简单来说,near, far 设置成相机到场景的大致最近和最远距离,然后 bounds 设置成以标定所得的世界坐标系中心为原点,一个大致能包含场景的 bounding box,原则上所有的光线的采样范围都是统一的 [near, far],然后会在此基础上计算每条光线和 bounding box 的交点,如果近处交点大于 near 就会更新 near,远处交点小于 far 就会更新 far

请问到场景的距离是到场景边界吗?我一直以为near就是bounds中绝对值最小的数,far就是绝对值最大的数。

是的,near 就是相机平面到场景中最近的物体表面的距离,far 就是相机平面到场景中大致最远物体表面的距离,near, far 的设置和 bounds 并没有关系,默认都会用 near, far,然后 bounds 可以理解成 refine 你统一设置的 near, far 的。

463f commented 4 months ago

谢谢回复! 修改了坐标系的尺度后变好了些。但是我如果直接用预训练模型+ ENeRFi 来测试,发现在已知视角之间新视角效果不太好。

  1. 因为我的数据集只有8个相机,可能和这个有关吗?
  2. 如果 ENeRFi 的测试效果不好,那么 L3MHET 训练后能带来更好的效果吗?

相机点位图: image

exps/enerfi.yaml 文件

# Configuration for ENeRF
configs:
    - configs/base.yaml # default arguments for the whole codebase
    - configs/models/enerfi.yaml # network model configuration
    - configs/datasets/hangzhou/hangzhou.yaml # dataset usage configuration
    - configs/specs/static.yaml # test for only one frame

# prettier-ignore
exp_name: {{fileBasenameNoExtension}}
xbillowy commented 4 months ago
  1. Ei 是 IBR 算法,所以在视角比较稠密的情况下表现会更好,你的这个数据看起来是 8 个相机覆盖了 360° 的范围,这对于 E 来说已经是比较稀疏的情况了,所以有可能导致 inference 效果不好。
  2. 导致效果不好还有一个可能的原因是相机参数不准,如果是这种情况的话,训练一个 l3mhet 模型并导出优化之后的相机参数可能会对效果有帮助,具体做法可以参考 Dense Calibration 小节中最后一部分。
  3. 你也可以尝试用你自己的数据集来 finetune Ei 的 pretrained model,文档 Train from Pretrained Model 中有提到如何 finetune ENeRF。
rexainn commented 4 months ago
  1. Ei 是 IBR 算法,所以在视角比较稠密的情况下表现会更好,你的这个数据看起来是 8 个相机覆盖了 360° 的范围,这对于 E 来说已经是比较稀疏的情况了,所以有可能导致 inference 效果不好。
  2. 导致效果不好还有一个可能的原因是相机参数不准,如果是这种情况的话,训练一个 l3mhet 模型并导出优化之后的相机参数可能会对效果有帮助,具体做法可以参考 Dense Calibration 小节中最后一部分。
  3. 你·也可以尝试用你自己的数据集来 finetune Ei 的 pretrained model,文档 Train from Pretrained Model 中有提到如果 finetune ENeRF。

请问对于类似(甚至更少)的稀疏相机布置,有什么算法更好呢?

xbillowy commented 4 months ago

对于更稀疏的相机阵列,我们正在进行相关算法的研究。关于已有的算法,不知道您指的是泛化的方法还是单场景的算法?

463f commented 4 months ago

感谢回复!我还是有两个问题:

  1. 比如 ENeRF_Outdoor 数据集,在大概180度的范围放置了18个相机,这种稠密的构型是否才能保证渲染时新视点切换的效果;如果变成了 360度范围内18个相机,因为相邻视角间共视区域变少了,是否在切换时效果可能也会不好?
  2. configs/model/l3mhet.yaml 是否需要随着数据集的不同而变化呢?还是只需要写好 dataset 和 exps 的配置文件即可?
xbillowy commented 4 months ago

感谢回复!我还是有两个问题:

  1. 比如 ENeRF_Outdoor 数据集,在大概180度的范围放置了18个相机,这种稠密的构型是否才能保证渲染时新视点切换的效果;如果变成了 360度范围内18个相机,因为相邻视角间共视区域变少了,是否在切换时效果可能也会不好?
  2. configs/model/l3mhet.yaml 是否需要随着数据集的不同而变化呢?还是只需要写好 dataset 和 exps 的配置文件即可?
  1. 对于 IBR 方法来说,一般视角越稠密,相邻视角的共视关系越多效果会越好,当相机变稀疏时是会有效果下降的;
  2. configs/model/l3mhet.yaml 一般不需要更改,最主要的是根据自己的数据集确定 dataset config,当然你也可以在 exp config 中修改一些 l3mhet.yaml 中默认的参数,exp 中的参数会覆盖 l3mhet.yaml 中的参数;