-
[논문 리뷰] Unsupervised Monocular Depth Estimation with Left-Right Consistency컴퓨터 비전/Monocular Depth Estimation 2021. 9. 23. 17:03
학부생 레벨의 컴퓨터 비전 기초 수업을 들어보신 분이라면 거의 반드시 stereo depth estimation에 대해 들어보셨을 것입니다. 사람의 눈처럼 렌즈가 두 개 달려 있는 카메라를 스테레오 카메라라고 부르는데, 왼쪽과 오른쪽 영상에서 공통적으로 보이는 물체들의 위치 차이(disparity)를 이용해서 물체까지의 3차원 거리를 계산할 수 있다~ 하는 부분이 바로 그것입니다. 보통은 이 개념을 제시한 이후 SIFT, SURF, ORB 등의 feature detector와 descriptor들을 사용해서 왼쪽과 오른쪽 이미지의 공통된 픽셀을 찾고, focal length와 baseline등의 수치를 사용해서 그 픽셀까지의 거리를 구하는 등의 연습을 합니다.
그런데 이 방법을 실제로 로봇 등에 사용하려고 구성을 해 보면 문제가 한 두 가지가 아닙니다. 특징점이 없는 영역(textureless regions)에서는 특징점을 못 찾으니 왼쪽-오른쪽 매칭이 안 돼서 거리를 구할 수가 없고, 특징점 몇 개 말고 영상 전역에서의 깊이 정보를 얻으려면 프레임 1개당 한 10분은 걸릴 것 같고, 거리가 너무 멀면 disparity가 너무 작아서 깊이 추정값이 엄청 부정확해지고, 왼쪽 카메라에서는 보이는데 오른쪽에서는 안 보이는 물건들이 있고... 이런 문제들은 별도의 수학적 기법들을 이용해 하나씩 해결해 주어야 합니다.
그런데 생각해 보면 사람은 한쪽 눈을 감고 돌아다녀도 엄청 큰 문제가 생기지는 않습니다. 물론 가까이 있는 물체들을 자세히 관찰할 때는 잘 안 되지만, 일상적인 공간에서는 거리를 추정하고 머릿속에 공간을 재구성하는 데 전혀 문제가 없습니다. 이것은 사람이 조명 환경, 물체의 크기, 원근법 등의 "주변 정보"를 사용해서 원래 기하학적으로는 불가능할 단안(monocular) 거리 추정을 한 눈만으로도 대강 할 수 있기 때문입니다. 단안 카메라를 사용한 깊이 추정 기법은 보통 Monocular Depth Estimation이라고 부르며 영상에 관련된 많은 것들이 그러하듯 기계학습의 발전과 더불어 큰 성능 개선을 보인 분야입니다.
Monodepth의 depth map 본 논문은 Monodepth라는 이름으로 잘 알려져 있는, 기계학습 기반의 단안 깊이 추정 방법론을 제시하고 있습니다. 이전의 기계학습 기반 단안 깊이 추정 알고리즘들은 스테레오 또는 RGB-D 카메라 등으로 얻은 depth에 대한 ground truth 데이터를 사용해서 뉴럴넷이 단안 이미지를 입력으로 받아 깊이 이미지를 출력하도록 훈련하는 방식이 주를 이루었습니다. Monodepth의 저자들은 ground truth data 는 얻기도 귀찮을 뿐더러 일반화(generalization) 능력이 떨어진다고 지적하며, true depth data 대신에 스테레오 이미지 2장만을 가지고 self-supervised learning을 할 수 있도록 잘 설계된 loss function을 만들어 Monodepth를 훈련시켰습니다. 이 방법은 추후 등장하는 많은 Monocular Depth Estimation논문들과 Visual Odometry, SLAM등의 분야에 많은 영향을 미쳤습니다. 이제 Monodepth에 대해 자세히 소개해 보겠습니다.
일단 네트워크의 구조부터 한 번 이해해 보겠습니다. 이 네트워크는 입력으로 단 한 장의 이미지를 받으며(왼쪽 이미지를 사용합니다), 훈련 시에는 왼쪽과 오른쪽에 해당하는 stereo image pair들이 필요합니다.
- 일단 입력된 이미지는 CNN을 거쳐 2개(왼쪽 및 오른쪽)의 disparity map을 생성합니다(Disparity map은 각 픽셀마다 왼쪽/오른쪽 이미지까지의 거리가 얼마나 차이나는지 라벨링해 놓은 이미지라고 보시면 됩니다). 위 그림에서 $ d^{l} $과 $ d^{r} $이 disparity map에 해당합니다.
- 이제 disparity map 중 하나($ d^{r} $)를 사용하여(왼쪽 이미지를 오른쪽 이미지로 매핑하는 map이겠죠??) 왼쪽 이미지로부터 오른쪽 이미지를 생성합니다. 이 생성된 오른쪽 이미지를 $ \widetilde{I^{r}} $ 이라고 합니다.
- 이제 이 이미지와 $ d^{l} $을 이용해서 왼쪽 이미지를 생성합니다. 이 생성된 왼쪽 이미지를 $ \widetilde{I^{l}} $이라고 합니다.
- 이제 원래의 왼쪽 이미지와 $ \widetilde{I^{l}} $이 비슷해지도록 네트워크를 훈련시키면 됩니다!! 왼쪽과 오른쪽 disparity가 제대로 만들어져야 원래 이미지와 생성된 이미지가 비슷할 테니까, 이미지들이 비슷해지도록 훈련시킨다는 것을 disparity를 정확하게 계산한다는 것과 같은 의미가 됩니다. Disparity를 알면 픽셀까지의 깊이를 아는 것과 다름없으므로, 결과적으로 이 네트워크는 단안 이미지로부터 depth map을 출력할 수 있게 된 것입니다!!
아주 clever한 방법이라고 하지 않을 수 없습니다. Ground truth depth data 없이도 깊이를 추정하도록 네트워크를 훈련시킬 수 있는 구조를 만들었고, temporal 정보 없이도 훈련이 가능합니다. 위의 과정 중 1. 을 수행하는 CNN은 autoencoder와 비슷한 encoder-decoder 구조로 이루어져 있으며, disparity map을 한 쌍만 출력하는 게 아니라 4단계의 이미지 스케일에 대해 4쌍의 disparity map을 출력합니다(Object detector 등에서 볼 수 있는 Feature Pyramid Network와 비슷한 면이 있네요). 해상도가 낮은 이미지는 디테일한 부분을 담고 있지 않은 대신 전체적인 그림의 consistency를 묘사하므로, 이미지 스케일을 나누는 목적은 큰 그림과 작은 디테일을 모두 고려하겠다는 의미로 볼 수 있습니다.
위의 4단계를 잘 읽어 보면, 가장 애매하게 넘어간 부분은 4. 단계의 "비슷해지도록 네트워크를 훈련" 부분이라는 것을 느끼실 수 있습니다. 이미지 2장이 비슷하다는 것을 수치적으로 어떻게 표현해야 할까요?? 저자들은 이를 위해 3종류의 loss function을 고안하고 이것들을 합쳐 하나의 loss function으로 제시합니다. 아래의 세 가지 loss function들은 모두 왼쪽과 오른쪽 버전이 있습니다(아래 그림에서는 왼쪽 버전만 표현).
- Appearance Matching Loss - 위의 식 (2)번에 해당합니다. 이 loss는 우리가 일반적으로 생각하는 "두 이미지가 얼마나 유사한가"를 나타내는 loss function으로, $ N $은 픽셀의 개수, $ i, j $는 픽셀 좌표입니다. 오른쪽의 $ 1 - \alpha $가 붙은 부분은 단순히 두 이미지의 차영상을 뜻합니다. 왼쪽의 $ \alpha $가 붙은 부분은 SSIM이라는 이미지 평가 지표(Image Quality Assessment Metric)으로, 두 이미지를 픽셀 단위로 비교하는 대신 이미지의 기하학적 구조의 유사성을 평가합니다. 자세한 설명은 bskyvision님의 블로그에 잘 되어 있습니다. $ \alpha $를 0과 1 사이에서 조절해 두 가지 loss function의 가중치를 조정할 수 있습니다(논문에서는 0.85 사용).
- Disparity Smoothness Loss - 위의 식 (3)번에 해당합니다. 이 글의 초반에 잠깐 언급했듯, textureless region에서는 depth를 추정하기 힘듭니다. 이를 해결하기 위해 저자들은 일단 disparity map이 locally smooth하도록(들쭉날쭉하지 않도록) 큰 disparity gradient에 대해 페널티를 먹이되, image gradient가 큰 영역(물체의 경계 영역)에서는 실제로 depth가 크게 변화하므로 disparity map의 smoothness가 깨진다는 점을 고려하여 image gradient(위 식에서 $ I_{ij}^{l} $)가 큰 영역에서는 페널티를 적게 주는 loss function을 제작하였습니다.
- Left-Right Disparity Consistency Loss - 위의 식 (4)번에 해당합니다. 말로 설명하기는 좀 애매한데, 왼쪽과 오른쪽의 disparity map이 좌우대칭이도록 유도하는 loss function이라고 보시면 되겠습니다(기하학적으로 그래야겠죠??).
이제 이 loss funciton들을 모두 모으고 각각에 대해 적당한 가중치를 부여하면 최종적인 loss function이 완성됩니다.
이 loss function을 가지고 뉴럴넷을 훈련시킵니다. 3만 장의 이미지를 가지고 Titan X GPU로 50 epoch를 훈련시키는 데 25시간 정도가 소요되었다고 합니다.
이 논문을 베이스로 2018년에 Monocular Visual Odometry의 SOTA논문인 DVSO가 발표되었습니다. SLAM 논문 리뷰에서 다루어 보도록 하겠습니다.