본문 바로가기

딥러닝/MonoDepth estimation

Image Reconstruction은 어떻게?? 코드 분석 및 예시 결과

728x90
SMALL

안녕하세요 오늘은 Image Reconstruction을 어떻게 하는지를 간략히 설명하려고 합니다!

해당하는 코드는 https://github.com/OniroAI/MonoDepth-PyTorch/blob/master/loss.py

여기에 들어가면 확인할 수 있습니다. 

 

OniroAI/MonoDepth-PyTorch

Unofficial implementation of Unsupervised Monocular Depth Estimation neural network MonoDepth in PyTorch - OniroAI/MonoDepth-PyTorch

github.com

아래는 Image Reconstruction에 가장 중요한 핵심이 되는 apply_disparity함수입니다.

먼저 위의 함수에서 image와 disparity를 파라미터로 입력 받습니다.

예를 들어 left image, right disparity값을 입력으로 주면 left image에서 right image를 reconstruction을 사용해 새로 만들어내는 것입니다. 

또, right image, left disparity값을 입력으로 주면 right image에서 left image를 만들어냅니다.

 

그럼 코드 설명을 하나하나 시작해보도록 하겠습니다.

 

여기서 가장 먼저 사용되는 torch.linspace 함수에 대해서 설명 하도록 하겠습니다.

위의 예시와 같이 torch.linspace(a,b,c)를 하면 a부터 b까지의 값을 동일한 간격을 가진 수 c개가 나오도록 해주는 함수입니다. 즉, torch.linspace(0,1,width) 같은 경우 0부터 1까지의 값을 동일한 간격을 가진 수 width개가 나오도록 해주는 것입니다.

 

그리고 뒤에 linspace().repeat(batchsize, height, 1)는 예를 들어, 위에서 a = linspace(0,1,width)를 사용해서 0-1사이의 값을 동일한 간격을 가진 수 width개로 나오도록 한 것으로, a의 shape는 [width]가 됩니다.

 

그런데 여기에서 , linspace(batchsize, height, 1).repeat(batchsize, height, 1)을 해주면, a의 shape가 [width]에서 [batch, height, 1*width]로 나오게 됩니다. 즉 batch, height에 대해서 repeat하게 값을 준 것이 됩니다. 

 

이해가 어려울 수도 있을 것 같아 제가 예시를 첨부하려고 합니다. 

다음과 같이 코드를 작성하고 실행하면 

위와 같이 0-1사이의 값이 10개가 동일한 간격으로 출력되도록 tensor가 생성이 됩니다. 해당하는 것의 shape 또한 [10]이고요, 여기서 a의 값에 repeat 함수를 추가로 사용했을 때 결과가 어떤지 확인해보겠습니다.

 

다음과 같이 코드를 작성한 후 실행시켜주면

위와 같이 결과가 나오게 됩니다. a의 값들이 batch와 height, 1만큼 repeat되서 나온다고 생각하시면 됩니다. 그래서 a를 repeat한 p의 shape는 [4,10,20]으로 된 것을 확인할 수 있습니다. 

 

따라서 torch.linspace와 repeat 함수를 사용해서 x_base, y_base를 생성했습니다. x_base와 y_base를 만드는 이유는 original pixel의 좌표를 나타내기 위해서 입니다. 그러니까 기본 값을 세팅해주는 것이라고 생각하면 될 것 같습니다.

 

그 다음으로는 apply shift in x direction과 관련된 코드 입니다. disparity를 기준으로 image를 새로 만드는 것이기 때문에 height에는 변화가 없습니다. 즉!! width를 기준으로 옆으로 disparity 만큼 이동해서 image를 reconstruction하는 것이기 때문에!!! x_shifts만 있습니다. y_shifts는 없습니다.

 

여기서 disparity는 [batch,channel,height,width]로 되어있습니다. 여기서의 channel은 1입니다. 따라서 x_shifts = disp[ : , 0 , : , : ]는 [batch,channel,height,width]로 되어있던 disparity를 [batch,height,width]로 바꾸어주는 과정입니다. 안에 있는 disp 값은 변하지 않습니다.

 

그리고 나서 flow_field는 위에서 기본 값 x,y 세팅한 것에 y값은 변화가 없고, x 값에만 변화가 있기에 x_base에 위의 x_shifts 즉, disparity를 더해서 stack에 쌓아주는 것입니다. 여기서 dim = 3이라고 되어있는데, 그것은 dimension 3을 기준으로 쌓겠다는 말입니다. 즉, height를 기준으로 쌓는 다는 말이겠죠.

 

마지막으로!

F.grid_sample이라는 함수에 image와 위에서 구한 flow_field에 2를 곱하고 1을 빼준 값을 넣습니다. 여기서 위에서 구한 flow_field에 *2 - 1을 하는 이유는 위의 flow_field 즉, disparity의 범위가 0-1사이의 값이기 때문입니다. F.grid_sample의 함수를 보시면 두번째 파라미터의 값이 -1에서 1사이의 값이여야 하기 때문에 0-1사이의 값인 flow_field에 *2-1을 해주어 [-1,1] 사이의 값으로 만들어 주는 것 입니다.

 

그래서 결국, image에 원하는 이동 값 2*flow_field-1을 넣어주면, F.grid_sample 함수가 알아서 원하는 image에 우리가 넣어준 0-1사이의 disparity에 *2-1한 값을 이용해 잘 warping을 해주어 새로운 이미지를 생성해내는 것입니다!!!!

 

이상 Image reconstruction 코드를 이해하고 실제로 적용한 결과를 보았습니다.

 

혹시 image reconstruction을 구현 하는데 어려움을 겪고 계신다면 언제든 댓글로 질문해주세요!

728x90
LIST

'딥러닝 > MonoDepth estimation' 카테고리의 다른 글

KITTI DataLoader 구현하기!  (5) 2021.01.02
Mono Depth Estimation에 대한 간단한 설명!  (5) 2020.03.10