Knowhow/Vision

Stereo image rectification

침닦는수건 2023. 3. 16. 18:26
반응형

Stereo camera setting을 다룰 때 기본이 되는 것은 이미지의 rectification이다. 같은 기종의 카메라를 쓰더라도 intrinsic parameter가 조금씩 다르고, 정확히 조립해도 extrinsic parameter (특히 rotation)가 다르기 때문에 필수적으로 해야한다.

 

단순해보이지만 homography와 3d translation을 고려해야 하고 이미지 warping이 포함되기 때문에 직접 구현하는데는 번거로움이 많아 OpenCV의 함수를 활용하는 것이 일반적이다. 

 

OpenCV document를 보면 그만이라고 할 수 있지만 따로 적어 기록해두는 이유는 rectification된 이미지를 얻기까지 3개의 함수를 조합해야 하는데 매번 3개의 document를 보는 것이 귀찮고 return 값들이 의미하는 것이 무엇인지 매번 헷갈려서이다. 

 

그리고 첫 함수인 cv2.stereoRectify를 이용하고 나면 카메라 2대에서 나오는 fx, fy 총 4개의 값이 단 하나의 f로 통합되는데 이 새로 생성된 f를 이용해 뒤 cv2.initUndistortRectifyMap 함수를 써야 이론 상 정확한 rectification이 된다. 하지만 document만 봐서는 이러한 내용을 알 수 없어 함수로 묶어두기로 했다. 

 

def rectified_images(limg, rimg, K_l, dist_l, K_r, dist_r, T_rl):
    img_h, img_w = np.shape(limg)
    img_dim = (img_w, img_h)

    R1, R2, P1, P2, Q, _, _ = cv2.stereoRectify(K_l, dist_l, K_r, dist_r, img_dim, T_rl[:3, :3], T_rl[:3, -1])
    f = Q[2, 3]
    b = 1 / Q[3, 2]

    K_lnew = P1[:3, :3]
    K_rnew = P2[:3, :3]

    mapx_l, mapy_l = cv2.initUndistortRectifyMap(K_l, dist_l, R1, K_lnew, img_dim, cv2.CV_32FC1)
    mapx_r, mapy_r = cv2.initUndistortRectifyMap(K_r, dist_r, R2, K_rnew, img_dim, cv2.CV_32FC1)

    limg_rect = cv2.remap(limg, mapx_l, mapy_l, interpolation=cv2.INTER_LINEAR)
    rimg_rect = cv2.remap(rimg, mapx_r, mapy_r, interpolation=cv2.INTER_LINEAR)

    return limg_rect, rimg_rect, f, b

입력이 되는 T_lr은 4 x 4 transformation matrix로 통칭 left camera to right camera transformation이다. notation이 헷갈리 경우, 2022.07.13 - [Knowhow] - 3D transformation(R, t) matrix notation 글을 참고하면 되겠다.

 

위에 언급했듯이 주목할 점은 중간에 새로운 f로 new K matrix들을 만들고 이것을 이용해서 이미지 warping을 수행해야 한다는 것이다.

 

나중에 disparity를 depth로 역산해야 할 일이 분명 있을테니 그 때 사용할 focal length, f와 baseline length, b도 얻을 수 있게 해두었다. 

 

Note

간혹 위 함수로 rectification을 했는데 그냥 김 (검정 이미지)이 나올 때가 있는데, 그때는 left camera와 right camera가 정렬이 제대로 되어있는지 확인해야 한다. 둘 간의 rotation이 너무 심할 경우, 억지로 stereo setting으로 변경하기 위해 전혀 엉뚱한 방향으로 정렬될 수 있는데, 이상한 방향으로 이미지 warping이 되기 때문에 검정색만 보이는 것이다. 

 

굳이 stereo setting으로 바꾸고 싶으면 대충이라도 사전에 rotation + 이미지 warping을 한 번 해두고 나서 위 함수를 써서 2차 가공하는 것이 낫다. 

반응형