2017년 7월 11일 화요일

나만의 3차원 스캐너 만들기 (2)

- 주제 : 카메라 2개와 Line 레이저를 사용한 광학식 3차원 스캐너

- 개발 범위 : 카메라로 데이터 획득 --> Reconstruction (3D point cloud)

  앞에서 레이저 포인터를 이용하여 3차원 데이터를 획득 하였을 때의 단점을 계선하기 위해 
  레이저 포인터를 Line 레이저로 바꿔본다.

  레이저 포인터를 사용하면 대응점 검출을 매우 간단한 방법으로 할 수 있었다.
  

  Line 레이저를 사용하면 왼쪽 카메라에서 대응되는 점을 오른쪽에서 어떻게 찾을 수 있을까?
  
  두 카메라의 위치를 알고있다면 왼쪽 카메라에서의 한 점은 두 카메라의 위치에 따른 제약에 따라 오른쪽 카메라에서 선으로 투영이 된다.
  그 내용은 Epipolar Geometry에 대하여 검색을 해보면 알 수 있다.
Epipolar geometry is the geometry of stereo vision. When two cameras view a 3D scene from two distinct positions, there are a number of geometric relations between the 3D points and their projections onto the 2D images that lead to constraints between the image points. These relations are derived based on the assumption that the cameras can be approximated by the pinhole camera model.

출처 : Wikipedia https://en.wikipedia.org/wiki/Epipolar_geometry
  
  위키피디아에서 에피폴라기하에 대하여 검색을 해보면 위와같이 그림이 잘 나와있다. 
  왼쪽 뷰에서 3차원 객체 X를 바라볼때 X가 OL로 이어지는 선으로 객체가 투영이 되는데 이 선은 오른쪽 뷰에서 빨간선으로 보이게된다.
  왼쪽 뷰의 한 픽셀에 대한 오른쪽 뷰에서의 선을 계산하기 위해서는 Fundamental matrix를 사용하는 것이 편하다.
  
  F는 기존에 수행했던 cv::stereoCalibration에서 결과 값으로 계산을 해준다.
C++: double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Size imageSize, OutputArray R, OutputArray T, OutputArray E, OutputArray F, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6), int flags=CALIB_FIX_INTRINSIC )
  
  위의 이미지에서. 왼쪽 뷰에서 Line 레이저에 의해 인식된(빨간색) 점 중 하나를 고르면 오른쪽 뷰에서 주황색 선을 따라 투영이 된다. 
  이때 Line 레이저를 통해 인식된 빨간 선과 교차하는 부분을 계산하면 대응점을 쉽게 구할 수 있다.

  다시 Line 스캔의 순서를 정리해보면
  1. Line을 인식한다.(빨간색)
  2. Epipolar 제약에 따른 선을 계산하여 교점을 계산한다. (=대응점 계산) 

  1. 대응점에 대한 Ray를 계산한다. 
  1. 두 Ray의 교점을 계산한다.(triangulation)
  2. 위 [2~5]과정을 모든 Pixel을 반복한다.
  

- 결과
  레이저 Line에 대한 3차원 데이터를 매우 빠르게 얻을 수 있다.
 

 

댓글 없음:

댓글 쓰기