[DiffusionDrive][nuscenes] visualization

ad_official·2025년 2월 8일

diffusion planning

목록 보기
10/19
python tools/visualization/visualize.py \
	projects/configs/diffusiondrive_configs/diffusiondrive_small_stage2.py \
	--result-path work_dirs/diffusiondrive_small_stage2/results.pkl



사용법

  • ipdb는 파이썬 인터랙티브 디버거(Interactive Python Debugger)라서, 해당 위치에서 코드 실행이 멈춘 뒤 명령을 기다리는 상태
  • 보통 디버깅을 위해 잠시 코드를 멈추는 용도로 쓰이는데, 당신이 원치 않는다면 이 상태를 빠져나와서 프로그램을 계속 실행시키면 됩니다.
  • 가장 간단한 방법은 c 혹은 continue 명령어를 입력하고 엔터를 치는 것입니다.
    • 그러면 디버거가 다시 실행을 이어가며, 이후의 시각화 코드를 마저 진행하게 됩니다.
  • 현재 ipdb가 멈춘 지점에서 c 라고 입력 후 엔터를 치면, 프로그램이 계속 돌아가며 시각화가 완료되고
    • 결과 이미지를 vis/bev_gt 등 지정된 폴더에 저장
    • 그 뒤 생성된 PNG/JPG 파일을 열어보거나, script가 마지막에 묶어준 video.mp4 등을 확인해보시면 됩니다.

만약 디버깅이 전혀 필요 없을 때

  • bev_render.py 내부에 import ipdb; ipdb.set_trace()로 설정된 부분을 직접 주석 처리하거나 해당 코드를 삭제하면,
    • 더 이상 디버거가 걸리지 않고 곧바로 시각화 과정이 진행


ipdb에서 자주 쓰는 명령어

  • c / continue: 계속 실행(디버거 모드 종료 후 다음 breakpoint나 프로그램 종료 시점까지 진행)
  • n / next: 다음 줄로 이동
  • s / step: 함수 내부로 들어가며 디버깅
  • q / quit: 디버거 완전히 종료(프로그램도 바로 종료)
  • exit: Python 인터랙티브 상태에서 빠져나오기



코드 내용

python tools/visualization/visualize.py \
    projects/configs/diffusiondrive_configs/diffusiondrive_small_stage2.py \
    --result-path work_dirs/diffusiondrive_small_stage2/results.pkl

를 실행하면, 3D 자율주행(검출·트래킹·플래닝 등) 결과를 시각화하여 이미지/동영상으로 만들어내는 작업을 수행

요약: 전체 파이프라인 정리

  1. 데이터셋 준비 & 추론 결과 불러오기:

    • Config 파일(diffusiondrive_small_stage2.py)을 통해 설정을 읽고,
      • 해당 데이터셋(주로 NuScenes)과 결과(results.pkl)를 준비합니다.
  2. BEV / 카메라 시각화:

    • GT 박스, 예측 박스, 맵, 플래닝 궤적 등 다양한 정보를 불러와서,
      • 2D/3D 변환 및 matplotlib(OpenCV, PIL)로 그립니다.
    • BEV: 위에서 내려다보는 형태의 차량/차선/박스/궤적 시각화
    • Camera View: 실제 카메라 이미지 위에 3D 박스를 투영해서 그린 2D 박스 혹은 예측 궤적 표시
  3. 이미지 합성 & 영상 생성:

    • BEV와 카메라 이미지를 합쳐 한 장짜리 그림을 만들어 저장
    • 모든 프레임을 순회하며 .jpg/.png 파일을 만든 후, 이를 한데 모아 .mp4 동영상을 생성

딥러닝·자율주행 관점에서의 의의

  • Object Detection 뿐만 아니라, Motion Forecasting(미래 트래젝터리 예측), Planning(경로 계획) 결과까지 한 번에 확인
  • 코드를 보면 DDIMScheduler 같은 diffusion 관련 클래스도 쓰이고 있어서,
    • Diffusion 모델로 생성된 미래 궤적/플래닝을 여러 샘플로 그려주거나,
    • 그 샘플을 BEV 위에 시각화해 어떻게 분포되어 있는지 확인하는 용도

결론

  • 위 명령어를 실행하면
  1. 설정 파일결과 파일을 불러와,
  2. 데이터셋의 각 샘플마다 GT(3D 박스, 맵, 궤적)모델 예측(검출/추적/플래닝) 정보를
  • BEV, 카메라 시점으로 각각 시각화하고,
  1. 결과 이미지를 저장한 뒤, 원하는 경우 이를 하나의 동영상으로까지 생성


1. Config 파일 로드 및 데이터셋 초기화

1) Config 로드

cfg = Config.fromfile(args.config)
  • projects/configs/diffusiondrive_configs/diffusiondrive_small_stage2.py 같은 설정(config) 파일을 불러옵니다.
  • 이 설정 파일에는 모델 구조, 데이터셋 경로, 전처리 파이프라인, 학습/검증 파라미터 등이 정의되어 있습니다.
  • 예컨대 어느 경로에 NuScenes 데이터셋이 있는지, 어떤 데이터 augmentations를 쓰는지, 몇 개의 클래스를 학습했는지 등의 정보가 들어 있습니다.

2) 데이터셋 빌드

self.dataset = build_dataset(cfg.data.val)
  • MMDetection3D(MMDet3D) 프레임워크의 build_dataset 함수를 통해, cfg.data.val 설정대로 검증용(혹은 시각화를 위한) 데이터셋 객체를 만듭니다.
  • 여기서는 NuScenes 같은 자율주행용 3D 벤치마크의 밸리데이션셋을 불러오는 경우가 많습니다.
  • 이 데이터셋 객체는 get_data_info(index) 등을 통해
    • 특정 프레임에 대한 (레이더/라이다/카메라) 센서 정보,
    • annotation(레이블) 정보 등을 조회할 수 있습니다.

2. 추론 결과(Detection, Planning 등) 로드

self.results = mmcv.load(args.result_path)
  • work_dirs/diffusiondrive_small_stage2/results.pkl에서 추론 결과를 불러옵니다.
  • pkl 파일에는 모델이 검증 세트 전체에 대해 예측한
    • 3D bounding box,
    • 트래킹 정보,
    • 운동 예측(trajectory),
    • 플래닝 결과
  • 예를 들면, result[i]가 i번째 샘플(시퀀스/프레임)에 대한 예측 정보(라벨, 3D 박스 좌표, 점수, 트랙 아이디, 예측 궤적 등)를 포함하게 됩니다.

3. 시각화 객체(BEVRender, CamRender) 생성

self.bev_render = BEVRender(plot_choices, self.out_dir)
self.cam_render = CamRender(plot_choices, self.out_dir)
  • Bird's-Eye View(탑다운 시점) 시각화 담당 객체와 카메라 뷰 시각화 담당 객체를 생성합니다.
  • plot_choices는 어떤 항목을 그릴지에 대한 Boolean 설정(예: det=True, motion=True, map=True, planning=True 등)을 담고 있습니다.
    • 이 설정을 토대로 “검출 박스만 그리겠다”, “맵(차선 등)도 그리겠다”, “플래닝 결과도 그리겠다”와 같은 플래그를 제어합니다.
  • 시각화 결과를 저장할 디렉터리(out_dir)도 설정합니다.
    • 내부적으로 bev_gt, bev_pred, cam_pred 등의 폴더가 자동 생성되어 이미지를 저장합니다.

4. 샘플별 시각화 진행(visualizer.add_vis(idx))

  • 코드의 핵심 루프 부분에서, 지정된 범위(START=0, END=81, INTERVAL=1) 동안 각 인덱스별로 시각화를 수행합니다. 즉, 0번째부터 80번째까지 프레임(혹은 시퀀스 단위)을 순회하며 다음 일을 합니다.

4.1 데이터/결과 가져오기

data = self.dataset.get_data_info(index)
result = self.results[index]['img_bbox']
  • dataset에서 index에 해당하는 샘플(프레임)에 대한 정보(data)를 불러옵니다.
    • 예: LiDAR->Camera 변환행렬, 각 카메라 이미지 경로, GT 라벨/박스, 맵 라인 정보 등등
  • 추론 결과(result)도 results.pkl에서 같은 인덱스로 가져옵니다. 여기엔 3D 바운딩박스와 점수, 트랙 정보, 플래닝 경로 등이 포함되어 있을 수 있습니다.

4.2 Bird's-Eye View 시각화

bev_gt_path = self.bev_render.render(data, result, index)

(bev_render.py 내부를 참조)

  1. canvas 초기화

    self.reset_canvas()
    • matplotlib의 figure/axes를 초기화하고, 중심 좌표계를 세팅합니다.
  2. GT(혹은 예측) 요소를 그림

    • draw_detection_gt(data): 라이다/3D 라벨 박스(ground truth) 그리기
      • gt_bboxes_3d 좌표를 가지고 박스를 BEV 상에 사각형(혹은 마름모) 형태로 표시합니다(4개 코너 점).
      • 진행 방향(forward)를 나타내는 선을 별도로 그려, 객체가 어느 쪽이 front인지 시각적으로 알 수 있게 합니다.
    • draw_map_gt(data):
      • 차선/도로의 GT 맵 폴리곤(라인 세그먼트) 그리기
    • draw_diffusing_gt(data) 또는 draw_planning_gt(data):
      • 플래닝 궤적(자차가 앞으로 어떻게 움직일지), 또는 diffusion을 이용해 생성된 임시 궤적들을 그립니다.
      • 예: data['gt_ego_fut_trajs']를 누적합해 (0, 0)에서부터의 누적 이동량으로 변환해 곡선을 시각화.
      • diffusion 스케줄러(DDIMScheduler)를 써서 노이즈를 추가한 다양한 샘플을 그린 사례도 보입니다.
        • 즉, 확률적 예측/샘플링된 다양한 경로를 한 그림에 여러 개로 찍어볼 수 있게 한 것입니다.
    • self._render_sdc_car():
      • 자차(자율주행 차량) 아이콘(sdc_car.png)을 중앙에 그려, “이 뷰가 자차를 중심으로 보는 탑다운 시점임”을 표시합니다.
  3. 이미지 저장

    save_path_gt = os.path.join(self.gt_dir, str(index).zfill(4) + '.png')
    self.save_fig(save_path_gt)
    • 그려진 figure를 .png로 저장합니다.
    • bev_gt 등 서브폴더에 이미지를 저장하게 됩니다.

위 과정을 통해 BEV(Top-down) 시점에서 “GT와 예측 박스, 맵, 차량 궤적, 플래닝 결과” 등이 합쳐진 시각화 이미지를 얻을 수 있습니다.

실제로는 draw_detection_pred, draw_planning_pred 등이 활성화되어 있으면, 예측 박스예측 플래닝 경로까지 같이 그릴 수 있습니다. 현재 예시 코드에는 draw_pred=True로 설정되어 있어, GT와 모델 예측을 모두 시각화할 수도 있습니다.


4.3 Camera View 시각화(선택적)

cam_pred_path = self.cam_render.render(data, result, index)

(cam_render.py 내부를 참조)

  1. 각 카메라 이미지를 로드
    • NuScenes 예시로 CAM_FRONT, CAM_BACK 등 6개 카메라 뷰를 순회합니다.
    • 각 이미지를 Image.open으로 읽고, OpenCV/Matplotlib으로 표시합니다.
      image = np.array(Image.open(data_path))
    • 그 후 “CAM_FRONT_LEFT” 같은 카메라 이름을 화면에 텍스트로 오버레이합니다.
  2. 추론된 3D 박스나 플래닝 궤적을 2D 이미지에 투영
    • 3D 바운딩박스를 카메라 뷰로 투영하려면 lidar2cam(Extrinsic) + cam_intrinsic(Intrinsic)을 사용해 3D->2D 변환을 수행합니다.
    • box.render로 박스를 그려주거나(NuScenesBox), 직접 view_points 함수를 사용해 폴리곤을 그리고, 점을 scatter 등으로 표시합니다.
    • 예측된 플래닝(자차 미래 궤적)도 마찬가지로 3D 좌표를 투영해 2D 이미지에 점 형태로 표시할 수 있습니다.
  3. 이미지 저장
    • BEV와 마찬가지로, cam_pred 폴더에 카메라 시각화 결과를 저장합니다.

4.4 결과 이미지 합성 & 저장(선택적)

코드 맨 아래엔 combine() 함수가 있어, BEV 시각화 결과 + 카메라 시각화 결과를 하나의 큰 이미지로 합치는 부분도 보입니다.

merge_image = cv2.hconcat([cam_image, bev_image, bev_gt])
  • 순서대로 좌(카메라), 중간(BEV 예측), 오른쪽(BEV GT)로 합쳐서 하나의 .jpg로 저장할 수 있습니다.

실제 코드 상에서는 visualizer.add_vis(idx)세 개의 이미지를 각각 저장한 뒤, combine() 함수로 세 개 이미지를 읽어서 좌우로 hconcat하여 최종 합성을 만들 수 있습니다.


5. 시각화 결과를 하나의 동영상으로 생성

마지막으로:

visualizer.image2video()
  • 시각화된 .jpg(또는 .png)들을 하나씩 불러와서, OpenCV의 cv2.VideoWriter를 이용해 .mp4로 묶어줍니다.
  • fps=12로 설정되어 있으면 12프레임씩 묶어 재생하는 식의 영상을 video.mp4로 만들어냅니다.

6. 에러 수정하기

  • tools/visualization/visualize.py
  • tools/visualization/bev_render.py
  • tools/visualization/cam_render.py

profile
ad_official

0개의 댓글