1. 방사 왜곡(radial distortion)
1.1. 정의
이미지를 촬영할 때 직선이 휘어져 보이는 현상
- 이 왜곡은 특히 렌즈의 중심에서 멀어질수록 더 뚜렷하게 나타남
- 이를 보정하기 위해서는
정확한 모델링과 최적화 기법을 사용하여 왜곡 계수를 추정
하고, 이를 통해 이미지를 보정
1.2. 발생 원인
- 방사 왜곡은
렌즈의 구조와 설계
와 빛의 굴절 원리
에 의해 발생하는 비선형 왜곡 현상
- 렌즈는 빛을 굴절시켜 센서에 이미지를 형성하는데, 이 과정에서 다음과 같은 이유로 왜곡이 발생합니다:
- 렌즈의 곡률:
- 모든 렌즈는 일정한 곡률을 가지고 있습니다.
- 렌즈의 중심부에서는 빛이 비교적 직선으로 통과하지만, 렌즈의 가장자리로 갈수록 빛의 경로가 더 크게 굴절
- 이로 인해 중심에서 멀어질수록 빛이 굴절되어 이미지가 왜곡
- 비구면 렌즈 사용:
- 대부분의 렌즈는 제조 비용과 기술적 한계로 인해 완벽한 비구면 형태를 가지지 않습니다.
- 이로 인해 빛이 비선형적으로 굴절되며 왜곡이 발생
1.3. 방사 왜곡의 종류
- 방사 왜곡은 크게 두 가지로 분류됩니다:
- 배럴 왜곡 (Barrel Distortion):
- 이미지가 볼록하게 휘어지는 현상(아래 사진의 2번쨰)으로, 이미지의 중심에서 멀어질수록 직선이 바깥쪽으로 휘어집니다.
- 주로
광각 렌즈
에서 나타납니다.
넓은 화각과 깊은 심도를 제공
하며, 넓은 장면을 담는 데 적합
- 핀쿠션 왜곡 (Pincushion Distortion):
- 이미지가 오목하게 휘어지는 현상(위 사진 3번째)으로, 이미지의 중심에서 멀어질수록 직선이 안쪽으로 휘어집니다.
- 주로
망원 렌즈
에서 나타남
- 좁은 화각과 얕은 심도를 제공하며, 먼 거리의 피사체를 클로즈업하고 강조하는 데 적합
1.4. 보정 방법 : 위 수학적 모델
- 방사 왜곡을 보정하기 위해 다음과 같은 절차를 따릅니다:
- 캘리브레이션 이미지 획득:
- 체스보드 패턴과 같은 알려진 3D 구조를 다양한 각도와 위치에서 촬영하여 왜곡된 이미지를 얻음
- 왜곡 모델 피팅:
- 수학적 모델을 사용하여 왜곡 계수 ( k_1, k_2, k_3 )를 추정
- 이는 보통 비선형 최적화 알고리즘을 통해 이루어짐
2. 접선 왜곡 (Tangential distortion)
- 렌즈와 이미지 센서가 완벽하게 평행하지 않을 때 발생
- 탄젠트 왜곡(Tangential Distortion)은 렌즈와 이미지 센서가 정확하게 정렬되지 않았을 때 발생하는 왜곡
- 이 왜곡은
렌즈 요소의 비정렬
또는 렌즈의 제조 공차
로 인해 발생
- 주로 렌즈의 축이 이미지 센서의 평면과 정확하게 수직을 이루지 않을 때 나타납니다.
- 이 식에서 p1과 p2는
캘리브레이션 과정에서 추정되는 파라미터들
로,
- 이 값들은
렌즈와 센서 간의 기하학적 불일치를 설명
3. 왜곡 전체의 수학적 모델 설명
- 일반적으로 렌즈 왜곡의 수학적 모델:
카메라 내부 파라미터의 영향이 제거된 normalized image plane에서 정의
- 아래 식은, distorted normalized image plane의 값을 -> image plane으로 변환하는 과정이다.
4. TODO: (아직 읽지 마세요)영상 왜곡 보정
- 왜곡된 영상을 보정하기 위해서는 먼저 카메라 캘리브레이션을 통해 카메라 내부 파라미터(intrinsic parameter)를 구해야 합니다.
- 카메라 캘리브레이션에 대해서는 아래 링크 참조
- 왜곡 보정을 실전에서 활용하는 방법은 두 가지가 있습니다.
- 첫 번째: 전체 이미지에 대한 보정을 수행한 후 다른 작업을 이어나가는 것이고,
- 두 번째: 후에 사용될 특징점들을 미리 feature detection and matching 과정을 거쳐 선별한 후
- 해당 점들에 대해 보정을 수행하는 방법입니다.
- 전자의 경우 코드 복잡도가 낮은 대신 특징점만을 이용해 후속 동작들을 진행할 경우 불필요한 연산이 왜곡 보정 과정에서 들어가게 됩니다.
- 반면에 후자는 코드 복잡도가 조금 증가하는 대신 성능 측면에서 약간의 이득을 얻을 수 있습니다.
left_image = cv2.imread("original_images/left.png", cv2. COLOR.
_BGR2GRAY)
right_image = cv2.imread("original_images/right.png", cv2.COLOR_BGR2GRAY)
undistort_left = cv2.undistort(image_left, K_left, D_left)
undistort_right = cv2.undistort(image_right, K_right, D_right)
- 후자: 전체 이미지가 아닌 특징점들에 대한 보정을 다루는 코드입니다. Feature matching 하는 함수의 경우 이미 구현되어 있다는 가정으로 작성
left_image = cv2.imread("original_images/left.png", cv2.COLOR_BGR2GRAY)
right_image = cv2.imread("original_images/right.png", cv2. COLOR_BGR2GRAY)
matched
_left, matched
I right = obtainCorrespondingPoints(
image_left.astype(np.uint8), image_right.astype(np.uint8), 50, show=False
undistorted_left = cv2.undistortImagePoints(matched_left, K_left, D_left)
undistorted_right = cv2.undistortImagePoints(matched_right, K_right, D_right)