이 프로젝트는 Segmentation 마스크와 MiDaS 상대 깊이 맵을 활용하여, 물체의 2D 크기(픽셀 단위)와 이를 바탕으로 실제 거리/크기를 추정하는 방법을 적용합니다.
특히, Contour(윤곽선)와 RotatedRect(기울어진 사각형)을 사용하여 물체의 폭·높이를 정밀히 측정하는 방식을 활용합니다.
- 단순히 축에 평행한 Bounding Box(BBox)를 구해 폭·높이를 측정.
- 마스크가 기울어져 있으면 정확도가 떨어짐.
- Contour(윤곽선)를 찾아 OpenCV
cv2.minAreaRect()
로 기울어진 사각형(RotatedRect)을 생성.- 마스크가 기울어져 있어도, 2D 상에서 가장 긴 축(width)과 그에 수직인 축(height)을 정확히 계산 가능.
-
Segmentation 마스크 처리
measure_2d_size_from_mask()
를 통해 마스크로부터 Contour를 찾고, RotatedRect로 2D 크기(픽셀 단위 폭·높이)를 측정.
-
참조 물체 세그멘테이션
- 마스크로부터 참조물체의 2D 크기와 MiDaS 상대 깊이 맵의 평균값 계산.
- 핀홀 카메라 공식을 사용해 참조 물체까지 거리와 전역 스케일 추정:
s = Z_object / d_ref
-
장면 전체 깊이 계산
- 전역 스케일을 적용해 절대 깊이 맵 생성:
real_depth_map = relative_depth_map * s
- 전역 스케일을 적용해 절대 깊이 맵 생성:
-
측정 대상 세그멘테이션
- 텀블러의 2D 크기(픽셀 단위 폭·높이)와 절대 깊이 맵을 결합하여 실제 크기 추정:
Width = (픽셀 폭 * 평균 깊이 Z_tumbler * 센서 폭) / (focal_length * 이미지 폭)
- 텀블러의 2D 크기(픽셀 단위 폭·높이)와 절대 깊이 맵을 결합하여 실제 크기 추정:
- 입력: 0/1 이진화 마스크
- 처리:
- OpenCV
cv2.findContours()
로 마스크에서 윤곽선을 추출. - 가장 큰 Contour를 선택해
cv2.minAreaRect()
로 기울어진 사각형 생성. - 사각형의 폭·높이를 정렬:
width >= height
.
- OpenCV
- 출력:
(width_px, height_px)
(픽셀 단위).
- 입력:
- 물체의 픽셀 크기, 실제 크기, 카메라 초점 거리, 센서 크기, 이미지 해상도.
- 처리:
- 핀홀 카메라 공식으로 물체까지의 거리 추정:
Z = (focal_length * 실제 크기 * 이미지 해상도) / (픽셀 크기 * 센서 크기)
- 핀홀 카메라 공식으로 물체까지의 거리 추정:
- 출력: 물체까지 거리
Z
(mm 단위).
공식
핀홀 카메라 모델의 물체 거리 계산 관계는 아래와 같습니다:
Z = (focal_length * 실제 크기 * 이미지 해상도) / (픽셀 크기 * 센서 크기)
Z
: 물체까지의 거리(깊이).focal_length
: 카메라의 초점 거리(센서 기준, mm 단위).실제 크기
: 물체의 실제 크기(현실 세계에서, mm 단위).픽셀 크기
: 이미지에서 측정된 물체의 크기(픽셀 단위).센서 크기
: 카메라 센서 크기(가로 또는 세로, mm 단위).이미지 해상도
: 이미지의 가로 또는 세로 픽셀 해상도.
-
3D 기울어짐 보정의 한계
- 단일 이미지는 2D 투영 결과만 제공하므로, 3D 공간에서의 실제 크기와 차이가 있을 수 있음.
-
Segmentation 품질 의존
- 세그멘테이션이 정확하지 않으면 크기·깊이 계산의 정확도도 떨어짐.
-
MiDaS 깊이 추정 오차
- MiDaS 모델 자체의 한계로 인해 반사, 투명체, 복잡한 배경에서 깊이 추정 오차 발생 가능.