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 명령어를 입력하고 엔터를 치는 것입니다. c 라고 입력 후 엔터를 치면, 프로그램이 계속 돌아가며 시각화가 완료되고 vis/bev_gt 등 지정된 폴더에 저장video.mp4 등을 확인해보시면 됩니다.bev_render.py 내부에 import ipdb; ipdb.set_trace()로 설정된 부분을 직접 주석 처리하거나 해당 코드를 삭제하면, 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 자율주행(검출·트래킹·플래닝 등) 결과를 시각화하여 이미지/동영상으로 만들어내는 작업을 수행
데이터셋 준비 & 추론 결과 불러오기:
diffusiondrive_small_stage2.py)을 통해 설정을 읽고, results.pkl)를 준비합니다.BEV / 카메라 시각화:
2D/3D 변환 및 matplotlib(OpenCV, PIL)로 그립니다.차량/차선/박스/궤적 시각화예측 궤적 표시이미지 합성 & 영상 생성:
.jpg/.png 파일을 만든 후, 이를 한데 모아 .mp4 동영상을 생성DDIMScheduler 같은 diffusion 관련 클래스도 쓰이고 있어서,설정 파일과 결과 파일을 불러와, GT(3D 박스, 맵, 궤적)와 모델 예측(검출/추적/플래닝) 정보를 cfg = Config.fromfile(args.config)
projects/configs/diffusiondrive_configs/diffusiondrive_small_stage2.py 같은 설정(config) 파일을 불러옵니다.self.dataset = build_dataset(cfg.data.val)
build_dataset 함수를 통해, cfg.data.val 설정대로 검증용(혹은 시각화를 위한) 데이터셋 객체를 만듭니다.get_data_info(index) 등을 통해 self.results = mmcv.load(args.result_path)
work_dirs/diffusiondrive_small_stage2/results.pkl에서 추론 결과를 불러옵니다. pkl 파일에는 모델이 검증 세트 전체에 대해 예측한 result[i]가 i번째 샘플(시퀀스/프레임)에 대한 예측 정보(라벨, 3D 박스 좌표, 점수, 트랙 아이디, 예측 궤적 등)를 포함하게 됩니다.self.bev_render = BEVRender(plot_choices, self.out_dir)
self.cam_render = CamRender(plot_choices, self.out_dir)
plot_choices는 어떤 항목을 그릴지에 대한 Boolean 설정(예: det=True, motion=True, map=True, planning=True 등)을 담고 있습니다. out_dir)도 설정합니다. bev_gt, bev_pred, cam_pred 등의 폴더가 자동 생성되어 이미지를 저장합니다.visualizer.add_vis(idx))START=0, END=81, INTERVAL=1) 동안 각 인덱스별로 시각화를 수행합니다. 즉, 0번째부터 80번째까지 프레임(혹은 시퀀스 단위)을 순회하며 다음 일을 합니다.data = self.dataset.get_data_info(index)
result = self.results[index]['img_bbox']
dataset에서 index에 해당하는 샘플(프레임)에 대한 정보(data)를 불러옵니다.result)도 results.pkl에서 같은 인덱스로 가져옵니다. 여기엔 3D 바운딩박스와 점수, 트랙 정보, 플래닝 경로 등이 포함되어 있을 수 있습니다.bev_gt_path = self.bev_render.render(data, result, index)
(bev_render.py 내부를 참조)
canvas 초기화
self.reset_canvas()
matplotlib의 figure/axes를 초기화하고, 중심 좌표계를 세팅합니다.GT(혹은 예측) 요소를 그림
draw_detection_gt(data): 라이다/3D 라벨 박스(ground truth) 그리기 gt_bboxes_3d 좌표를 가지고 박스를 BEV 상에 사각형(혹은 마름모) 형태로 표시합니다(4개 코너 점).draw_map_gt(data): draw_diffusing_gt(data) 또는 draw_planning_gt(data): data['gt_ego_fut_trajs']를 누적합해 (0, 0)에서부터의 누적 이동량으로 변환해 곡선을 시각화.DDIMScheduler)를 써서 노이즈를 추가한 다양한 샘플을 그린 사례도 보입니다. self._render_sdc_car(): sdc_car.png)을 중앙에 그려, “이 뷰가 자차를 중심으로 보는 탑다운 시점임”을 표시합니다.이미지 저장
save_path_gt = os.path.join(self.gt_dir, str(index).zfill(4) + '.png')
self.save_fig(save_path_gt)
.png로 저장합니다.bev_gt 등 서브폴더에 이미지를 저장하게 됩니다.위 과정을 통해 BEV(Top-down) 시점에서 “GT와 예측 박스, 맵, 차량 궤적, 플래닝 결과” 등이 합쳐진 시각화 이미지를 얻을 수 있습니다.
실제로는
draw_detection_pred,draw_planning_pred등이 활성화되어 있으면, 예측 박스나 예측 플래닝 경로까지 같이 그릴 수 있습니다. 현재 예시 코드에는draw_pred=True로 설정되어 있어, GT와 모델 예측을 모두 시각화할 수도 있습니다.
cam_pred_path = self.cam_render.render(data, result, index)
(cam_render.py 내부를 참조)
CAM_FRONT, CAM_BACK 등 6개 카메라 뷰를 순회합니다.Image.open으로 읽고, OpenCV/Matplotlib으로 표시합니다. image = np.array(Image.open(data_path))lidar2cam(Extrinsic) + cam_intrinsic(Intrinsic)을 사용해 3D->2D 변환을 수행합니다. box.render로 박스를 그려주거나(NuScenesBox), 직접 view_points 함수를 사용해 폴리곤을 그리고, 점을 scatter 등으로 표시합니다.cam_pred 폴더에 카메라 시각화 결과를 저장합니다.코드 맨 아래엔 combine() 함수가 있어, BEV 시각화 결과 + 카메라 시각화 결과를 하나의 큰 이미지로 합치는 부분도 보입니다.
merge_image = cv2.hconcat([cam_image, bev_image, bev_gt])
.jpg로 저장할 수 있습니다.실제 코드 상에서는
visualizer.add_vis(idx)가 세 개의 이미지를 각각 저장한 뒤,combine()함수로 세 개 이미지를 읽어서 좌우로 hconcat하여 최종 합성을 만들 수 있습니다.
마지막으로:
visualizer.image2video()
.jpg(또는 .png)들을 하나씩 불러와서, OpenCV의 cv2.VideoWriter를 이용해 .mp4로 묶어줍니다. fps=12로 설정되어 있으면 12프레임씩 묶어 재생하는 식의 영상을 video.mp4로 만들어냅니다.