sghong977 / Daily_AIML

Computer Vision, Deep Learning, 그외 MLOps 찍먹 등. 매일 새롭게 배운 것을 정리합니다.
0 stars 0 forks source link

[2023.01.02~04] NeRF 시도: NeuMan #17

Open sghong977 opened 1 year ago

sghong977 commented 1 year ago

2022.01.02 Progress

Survey 현황

Code

TO-DO

[과정] NeuMan 셋업

주의사항: GPU 기종에 따른 CUDA 버전 문제

[2023.01.11 추가] 하.......... 해결이 아니었음. preprocessing이 안돌아서 중간에 추가함. detectron2 이런거 다 깔리고 conda env도 만든줄 알았는데 아니었음. neuman_env만 있네??

  1. IDC에 도커 빌드중. 뭐가 잘 안되던데... 걍 기다리면 되는거였음. 94%에서 오래 걸린다. 아무튼 만들었음 (ddde5018e348)
  2. 도커 이미지에는 ROMP, detectron2, mmpose, miniconda 등 셋업 되어있음. 도커 컨테이너 생성하기.
  3. conda 환경 셋업: conda env create -f environment.yml or cuda 버전 다르게 약간 수정
  4. conda activate neuman_env
  5. ** NeuMan Dataset: pretrained.zip, dataset.zip 다운받아서 옮겨주자 (이건 그냥 스크립트 실행해도 됨)
  6. * SMPL Models: SMPL weights 다운받기: uv map은 .obj 파일로 되어있음 (SMPL -> Download UV map in OBJ format) Neutral SMPL weights 다운받기: (Smplify -> SMPLIFY_CODE_V2.ZIP)
  7. ** NeuMan Github 페이지에 있는 것 처럼 render, train 코드 돌아가나 체크하기

canonical pose render 실행

[과정] 새로운 포즈 빌드해보기

AMASS (ICCV19)

Telegathering

무슨 warning이지... 암튼 돌아감
image 카메라 포즈와 사람들의 춤 동작이 바뀌었다.

image

[Optional] ZJU Mocap dataset

sghong977 commented 1 year ago

코드를 대충 뜯어보자.

TO-DO

NeuMan 데이터, pre-trained model

pretrained models: out/ (.pth.tar)

데이터셋: data/{video_name}/*

다운 받으면 NeuMan Dataset은 아래와 같이 구성되어있다.

image

우선, 폴더는 비디오 클립 기준으로 나뉘어있다. 아래 내용은 'bike'를 예시로 봤다.

preprocessing data 구성

학습에 필요한 것들. 모든 프레임에 대해 아래 내용들이 있다.

Depth Map

학습할때는 이렇게 불러온 값에 scale 곱하는 듯..?

KeyPoints & Pose

Segmentation

SMPL

아래 내용은 비디오별로 파일 하나만 있는 것.

파일 각각이 뭘 의미하는지는 Preprocessing 과정을 보면 좀더 알 수 있을 것 같다.

[OPTIONAL] Preprocessing 과정?

NeuMan Dataset 안에 있긴 하지만 새 비디오에 대해서 학습하고 싶을때는 다음과 같은 과정이 필요하다.

과정 설명

  1. 비디오 -> 프레임 자름 (save_video_frames.py 참고) out: 최종 프레임 아님. 뒤에서 뭐 처리함 (raw_720p/*)
  2. Segmentation Mask 생성: Detectron2 사용 instance segmentation 돌림. out: (raw_masks/*) 최종 마스크 아님! SIFT 돌리는데 쓰는 것.
  3. Sparse Scene Reconstruction: colmap 사용 SIFT Feature 뽑음 (여기서 raw_mask 사용!) -> SIFT Feature Matching함 (recon/db.db 생성) 1의 raw frame과 위에서 뽑은 feature 이용해서 -> colmap mapper를 사용함 (recon/sparse/ 생성) 1의 raw frame과 위에서 뽑은 (recon/sparse/0) 이용해서 -> colmap의 image_undistorter 돌림. (recon/dense/ 생성) 방금 뽑은 dense를 이용해서 -> colmap의 patch_match_stereo를 돌림 model_converter 돌림 out: 결과적으로 recon/dense/ 안에 images, depth_maps, sparse가 들어있는데, 얘넨 최종 결과물임. 중간 파일은 recon/에 있음.
  4. Rectified image에 대해 Mask 구하기 (Segmentation) 2랑 똑같이 돌림. 여기엔 방금 만든 images 넣음 (rectified) out: 최종 결과물 segmentations
  5. DensePose apply_net.py 실행. out: 비디오마다 densepose/output.pkl 생성. 최종 결과물 아님. 이미지별로 자르나...? 뭐지
  6. mmpose 실행: 2D Keypoints detector mmpose의 demo/bottom_up_img_demo.py 실행해서 키포인트 뽑음 (rectified) 이미지만 있으면 됨. out: keypoints 생성, 최종 결과물.
  7. Monocular Depth Estimation: BoostingMonocularDepth 사용 (rectified) 이미지만 있으면 됨. out: mono_depth 생성, 최종 결과물.
  8. SMPL Parameter 구하기: ROMP 사용 ROMP (논문 링크)는 RGB 이미지 있으면 거기서 사람 여러명에 대해 3d mesh를 추정할 수 있는 알고리즘. (rectified) 이미지만 있으면 됨. out: smpl_pred 생성, 최종 결과물.
  9. Scale 보정: 추정한 SMPL mesh(ROMP, 8에서 구한 것)와 sparse scene reconstruction (COLMAP, 3에서 구했던 sparse) 한것을 alignment해서 구함 export_alignment.py 실행해서 구함. input: (rectified) image, scene은 sparse, raw_smpl인 smpl_pred. (smpl_estimator 옵션에 romp를 주던데 이건 뭐지) smpl_pred 폴더에 있는 결과물(이미지 각각에 대한 넘파이 파일)들 읽어와서 일단 *.pkl파일 만듦. 그리고 바닥 닿는거 구한다음에 solve_translation(), solve_scale()해서 alignments.npy 구하는 것임. solve_translation은, translation parameter를 Adam optimizer 써서 1천 iter돌림. 3d점(여기에 translation 파라미터 들어감) -> 2d점으로 projection 한다음에 실제 2d점과의 mse_loss로 학습. solve_scale은 ray-plane intersection problem으로 정의해서 푼다고함. 주석으로 설명은 많이 되어있는데 그냥 간단하게 좌표값으로 사칙연산해서 간단하게 구하는 듯...? out: alignments.npy, smpl_output_romp.pkl 생성. 최종 결과물, 비디오마다 하나씩 구함.
  10. silhouette을 사용한 SMPL Optimization optimize_smpl.py을 실행하여 생성. input: scene_dir로 지금까지 생성된 output path를 다 넣어버려서, 정확히 어떻게 돌아가는지 몰겠음. 코드 봐야함 out: smpl_output_optimized.pkl 생성, 최종 결과물, 비디오마다 하나씩 구함.

Q. 9번에서 smpl_cap에 카메라 내부, 외부 파라미터 있던데 어떻게 구하지

읽어볼 자료?

preprocessing에서 딴건 대충 알겠는데 pose를 안해봐서 모르겠음. densepose로 뽑은건 왜 이미지 사이즈랑 똑같지? OpenPose 보면 관절 keypoint 좌표 어딘지만 저장하지 않나..?

Pose Estimation OpenPose, DensePose 설명

sghong977 commented 1 year ago

아 졸려...

joblib.open()

smpl_output_romp.pkl ['verts', 'joints3d', 'joints2d_img_coord', 'pose', 'betas']

smpl_output_optimized.pkl ['pose', 'betas'] 모든 프레임에 대해 있음

Render 과정?

render_360.py로 scene or human 360도 생성하는구나.

main_canonical_360()

  1. scene 읽음. neuman_helper.NeuManReader.read_scene()

~~

-------아무말ㄹㄹ 렌더링 결과 보니까 camera pose랑 human pose 계속 바뀌네? camera pose도 같이 바뀌는구나 reposing 어떻게 되는지 한번 보자

motion_name={speedvault, ...} <- 이거 지정된 모션만 할 수 있나? 딴거 못하나 코드 중간에 보면 raw_verts, Ts를 직접 지정해도 되고, predefined 값을 써도 되는 것 같은데

sghong977 commented 1 year ago

train 코드를 볼게요

train_mode가 bkg면 scene nerf 학습, 아니면 human nerf 학습. (smpl only, smpl and offset으로 나뉨. 읭?)

Scene NeRF

가장 먼저 Scene NeRF만 따로 학습하잖아. loss 2개였어. RGB랑 밀도에 대한 regularizer. mask를 보고 사람 없는데서만 ray 뽑을거니까 좌표는 알겠어. 근데 viewing direction은 어디서 가져오는거야?

train.py의 train_background() coarse_net, fine_net = vanilla.build_nerf(opt) train_scene = neuman_helper.NeuManReader.read_scene() vanilla_nerf_trainer.NeRFTrainer의 train()으로 학습

trainers/vanilla_nerf_trainer.py NeRFTrainer의 train_batch()를 볼게요 delay_iter만큼 돌기 전이면 rgb loss만 발생, 그 이후에는 empty_space_loss도 같이 발생시킴. coarse_rgb_loss, coarse_empty_space_loss, fine_rgb_loss, fine_empty_space_loss = self.loss_func(batch, device)

학습 중 validation? 방금 얘기한 loss들 찍고 render한 이미지 저장함. render_utils.render_vanilla()가지고 생성하는데, output은 render, depth 이렇게 두가지. 이 함수에서 coarse_net, fine_net 따로 받는데 딱히 없으면 coarse_net으로 통일

Human NeRF

이거 지금 논문내용(- ppt에 정리)이랑 와리가리 하면서 보고있는데 이어서 쓰겠음. train_human()에 뭐가 많아서 잠깐 튕겨져나옴

smpl에서 static joint 3d랑 joint 3d가지고 먼 threshold를 계산했어 image 이게 나눠진거

betas는 학습은 안되는거구 그냥 모델에 넣기만 하는건가?

ray 데이터 따로 나눠놨네 봐야지

sghong977 commented 1 year ago

Preprocessing 관련

컨테이너 하나 좀비되고 뭔가 불길한데..... 컨테이너 안 만들어지기 시작함 악..

아래 글 참고. https://dancefirst.tistory.com/entry/SMPL-%ED%9C%B4%EB%A8%BC-%EB%AA%A8%EB%8D%B8-%EB%B0%8F-%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

전처리 비디오 주의사항

  1. 비디오 퀄리티 전반적으로 중요함. 당연한 소리...
  2. 카메라 움직임 -> 없으면 안됨. 3/10에서 막힘 (camera intrinsic)
  3. 배경에 여러 사람의 등장 -> mask에서는 1명만 잘 인식하더라 해도, ROMP에서 2명 이상 간혹 나올 수 있음. 그러면 SMPL 인식 아예 안되는 프레임이 있거나 2명 이상 뽑히는 프레임 존재 -> 8/10부터 막히게됨