더 이상 tistory 블로그를 운영하지 않습니다. glanceyes.github.io에서 새롭게 시작합니다.

새소식

AI/AI 실습

COP(Center of Projection)에서 Image plane의 각 pixel을 향하는 vector 구하기

  • -
이 글은 미완성된 글이며, 곧 마무리할 예정입니다.

 

일반적으로 머신러닝을 사용하는 모델을 구현하는 논문에서 PyTorch로 코드를 보면 meshgrid라는 함수를 종종 볼 수 있다. 이 함수는 scalar 값 또는 1차원 tensor로 된 $n$개의 input을 받아서 좌표계의 grid를 생성한다. 이 함수에 관한 설명은 pytorch 공식 문서에 잘 나와있다. 자세한 내용은 PyTorch 공식 문서의 meshgrid 함수 페이지를 참고하면 된다.

 

 

torch.meshgrid — PyTorch 2.0 documentation

Shortcuts

pytorch.org

 

그런데 개인적으로 이 함수가 언제 자주 쓰이는지, 그리고 언제 사용하는 게 유용한지 감이 잘 잡히지 않았다. 그러나 컴퓨터비전 또는 그래픽스 논문 구현 코드를 찾아보면 종종 사용하는 함수이다. 어떨 때 쓰일 수 있는지를 한 번 정리해두면 나중에 실제로 모델을 구현할 때 참고할 수 있을 것 같아서 몇 가지 예시로 간단하게 정리해보려고 한다.

 

 

 

1. 이미지의 각 픽셀마다 뻗어나가는 ray의 방향 벡터 계산

 

NeRF(Neural Radiance Fields)에서 카메라 좌표계의 중심에서 이미지의 각 픽셀로 뻗어나가는 ray의 방향 벡터를 구하는 과정에서 쓰일 수 있다. 아래는 그 내용을 구현한 함수이다.

 

# 하나의 image에 관해 각각의 모든 픽셀을 지나는 ray의 origin과 viewing direction(pose)
def get_rays(h: int, w: int, focal_length: float, pose: torch.Tensor):
  # Pixel coordinate
  i, j = torch.meshgrid(
      torch.arange(w, dtype=torch.float32).to(pose),
      torch.arange(h, dtype=torch.float32).to(pose),
      indexing='ij')

  i, j = i.transpose(-1, -2), j.transpose(-1, -2)
  # Pixel coordinate에서의 각각의 픽셀이 이미지의 중점(w와 h의 각각의 2분의 1)으로부터 얼마나 떨어져 있는지
  rays_d = torch.stack([(i - w * .5) / focal_length, 
                        -(j - h * .5) / focal_length, 
                        -torch.ones_like(i)
                        ], dim=-1)
  
  # Pixel별 ray의 viewing direction을
  # world coordinate에서의 camera rotation 방향으로 align 시킨다.
  # shape of rays_d: (width, height, 3) = (width, height, 1, 3) * (3, 3)
  '''
  계산 과정에서 broadcasting이 된다는 걸 고려하자.
  (width, height, 1, 3) * (3, 3) => (width, height, 3, 3) * (width, height, 3, 3)
  sum[(width, height, 3, 3), dim=-1] => (width, height, 3)
  '''
  rays_d = torch.sum(rays_d[..., np.newaxis, :] * pose[:3,:3], dim=-1)

  # shape of rays_o: (width, height, 3)
  # (3) => (width, height, 3)
  rays_o = pose[:3,-1].expand(rays_d.shape)
  return rays_o, rays_d

 

위의 코드에서 torch.meshgrid 함수를 써서 2차원 이미지에서 각 픽셀의 좌표를 grid로 계산하는 과정이다. 2차원 좌표계를 다룰 때는 대체로 인자의 순서를 어떻게 주는지가 중요해진다. $xy$ coordinate으로 다루는지 아니면 $yx$ coordinate으로 다루는지에 따라서 말이다. 위의 예시에서는 첫 번째 인자를 width, 두 번째 인자를 height으로 줌으로써 $x$값을 좌표의 앞쪽에 오게 한 것이다.

 

 

그런데 width는 오른쪽 방향으로 늘어나야 하고 height는 아래 방향으로 늘어나야 하므로 transpose를 취한다. 이후 stack을 사용하여 $x$축 좌표 값과 $y$축 좌표 값을 $z$축 좌표 값인 -1과 같은 차원의 원소로 묶는다. 여기서 주의할 점은 $y$축은 위의 방향으로 증가하므로 그전에 아래 방향으로 증가하는 $y$축 좌표 값에 -1을 곱해서 $y$축의 증가 방향과 일치하도록 한다. 위의 그림에서 설명한 과정을 따라가 보면 이해하기 쉽다. 

 

NeRF의 다른 코드도 함께 참고하고 싶다면 아래 링크를 확인하면 된다.

 

GitHub - Glanceyes/ML-Paper-Review: Implementation of ML&DL models in machine learning that I have studied and written source co

Implementation of ML&DL models in machine learning that I have studied and written source code myself - GitHub - Glanceyes/ML-Paper-Review: Implementation of ML&DL models in machine learnin...

github.com

 

 

 

2. Bounding Box를 예측하기 위한 Anchor 생성

 

작성 예정

Contents

글 주소를 복사했습니다

부족한 글 끝까지 읽어주셔서 감사합니다.
보충할 내용이 있으면 언제든지 댓글 남겨주세요.