
Fisheye Camera (어안 카메라) 관련 정리
2023, Apr 26
- 사전 지식 : 카메라 모델 및 카메라 캘리브레이션의 이해와 Python 실습
- 사전 지식 : 카메라 모델과 렌즈 왜곡 (lens distortion)
- 참조 : https://arxiv.org/abs/2205.13281
- 참조 : https://plaut.github.io/fisheye_tutorial/#pinhole-camera-distortion
- 참조 : https://kr.mathworks.com/help/vision/ug/camera-calibration.html
- 참조 : http://jinyongjeong.github.io/2020/06/19/SLAM-Opencv-Camera-model-%EC%A0%95%EB%A6%AC/
- 참조 : http://jinyongjeong.github.io/2020/06/15/Camera_and_distortion_model/
- 이번 글에서는
Fisheye Camera
에 관한 전반적인 내용에 대하여 다루도록 하겠습니다. 글의 내용을 이해하려면 사전 지식에 해당하는 2개의 글을 반드시 읽고 오시길 권장 드립니다. - 글의 전반적인 내용은
Fisheye Camera
가 가지는 의미나 필요했던 내용 그리고Kumar
의survey
논문에 대한 내용을 다룹니다. - 본 글에서 다루는 데이터셋은 woodscape 데이터셋 이거나 개인적으로 구매한
Fisheye Camera
를 이용하여 촬영한 데이터셋입니다. 제가 자체적으로 취득한 데이터셋들은 아래 링크에 공개하오니 자유롭게 쓰셔도 됩니다.Woodscape
(Public Dataset) : https://woodscape.valeo.com/datasetFisheye Mono Camera
(Custom Dataset) : https://drive.google.com/drive/u/0/folders/16kPNXPaBFMogi8xt3fm6jhKp4jO6wB-HFisheye Stereo Camera
(Custom Dataset) : https://drive.google.com/drive/u/0/folders/1Q4f8bAD0lypEXgqvqehrgbAtEGzC6jOX
- Custom Dataset의
Fisheye Camera
는 다음 링크에서 구매하였습니다.Fisheye Mono Camera
: https://ko.aliexpress.com/item/4000333240423.htmlFisheye Stereo Camera
: https://astar.ai/collections/astar-products/products/stereo-camera
목차
-
Fisheye Camera의 특징과 Pinhole Camera와의 차이점
-
Fisheye Camera의 Vignetting 영역 인식 방법
-
Generic Camera 모델의 Fisheye Camera의 유효 영역 확인 방법
-
Fisheye Camera 왜곡 보정 방법 : Multiple rectifications
-
Fisheye Camera 왜곡 보정 방법 : Cylindrical Images
-
Surround-view Fisheye Camera Perception for Automated Driving 리뷰
Fisheye Camera의 특징과 Pinhole Camera와의 차이점
Pinhole Camera
는 렌즈의 왜곡이 없는 이상적인perspective view
형태의 카메라를 의미합니다.

Pinhole Camera
는 위 그림과 같이 바늘 구멍으로 빛이 입사되어 실제 상에 해당하는 3D 공간 상의 점과 2D 이미지에 투영된 점이 직선으로 1대1 대응이 된 형태를 뜻합니다. 이와 같은 형태의 경우 빛이 직진하게 되므로 빛이 굴절되는 왜곡 현상은 나타나지 않고 이미지 내에서 물체들이 선형적인 관계를 가지기 때문에 선형 변환 등을 적용하여 알고리즘을 설계하기 용이합니다.- 하지만 카메라 렌즈가 없다면 빛을 효율적으로 모을 수 없기 때문에, 투영된 이미지가 매우 어둡고 볼 수 있는 영역도 매우 제한적이게 되어 사실상 사용할 수 없습니다.
- 이와 같은 이유로 대부분의 카메라는 카메라 렌즈를 사용하게 되며 렌즈의 굴곡 정도에 따라서 원거리를 선명하게 볼 수 있으나 좁은 각도만 볼 수 있는 협각 카메라, 근거리만 선명하게 볼 수 있으나 넓은 영역을 볼 수 있는 광각 카메라와 같은 형태로 사용이 됩니다.
- 본 글에서 다루는 카메라는 광각 카메라 중 180도 화각 정도를 다루는
Fisheye Camera
에 대한 내용입니다.
Pinhole Camera의 Perspective Projection
Pinhoe Camera
는Perspective Projection
이라는 성질을 따릅니다.Perspective Projection
의 특징은 입사각 그대로 투영된다는 점입니다. 아래 그림을 살펴보도록 하겠습니다.

Pinhole Camera
의 경우 각Ray
는Pinhole
을 그대로 통과하여Image Coordinate
에 투영됩니다.- 위 그림에서 핵심은
Pinhole
을 기점으로 \(\theta\) 가 그대로 유지된다는 점입니다. 따라서Ray
의 입사각이 결정되면Image Coordinate
에 투영되는 지점인 \(r\) 을 다음과 같이 계산할 수 있습니다.
- \[r = f \cdot \tan{(\theta)}\]
- 이와 같은 성질을
Perspective Projection
이라고 합니다. 결국Ray
가 입사되는 각도 \(\theta\) 와 \(\tan{(\cdot)}\) 에 의해 투영되는 위치가normalized
된 좌표에서 결정된 후 \(f\) 만큼 비례하여 투영되면 최종적으로Image Coordinate
에 투영되게 됩니다.
Fisheye Camera의 Equidistance Projection
- 반면
Fisheye Camera
는Equidistance Projection
이라는 성질을 따르도록 카메라 모델링을 많이 합니다.Pinhole Camera
의 경우Perspective Projection
을 따른다고 생각하면 되지만Fisheye Camera
는Equidistance Projection
을 따른다고 가정하고 모델링 합니다. 따라서 다른Projection
모델을 사용할 수 도 있습니다. 하지만 대부분의Fisheye Camera
는Equidistance Projection
을 따라 모델링하므로 이 글에서도Equidistance Projection
만 다루고자 합니다. Equidistance Projection
의 특징은Ray
에 대하여 입사각 \(\theta\) 와Image Coordinate
에서의 Pinciple Axis와 투영된 점의 거리(Distance)가 같은 비율을 가진다는 점입니다.

- 앞에서 설명한
Pinhole
모델과 다르게Fisheye Camera
에서는Ray
가 입사하면Image Coordinate
에 그대로 입사각이 유지된 상태로 투영되는 것이 아니라 위 그림처럼 왜곡이 발생되어Image Coordinate
로 투영되게 됩니다. 왜곡이 되었기 때문에Distorted
라는 단어를 추가하여 표현하기도 합니다. Equidistance Projection
에서의 가정은 \(\theta / r\) 의 비율이 일정하다는 것을 이용합니다. 따라서 \(\theta\) 가 정해지면 어떤 모델링된 식에 따라서 \(\theta / r\) 을 만족하도록 \(r\) 이 정해지게 됩니다. 이와 같은 가정을Equidistance Projection
이라고 합니다.Equidistance Projection
을 사용하는 모델링 식 중 보편적으로 사용 카메라 모델링Generic Camera Model
이며 아래 링크에서 내용을 참조할 수 있습니다.- 위 오른쪽 그림을 살펴보면 \(p\) 와 \(p'\) 가 하나의
ray
상에 존재하되 \(r\) 값이 조정되어 투영된 것으로 나타납니다. 기존에Perspective Projection
에서 \(r = f \cdot \tan{(\theta)}\) 을 만족하기 위해서는 \(p'\) 에 투영되는 것이 맞지만 \(\theta / r\) 을 만족하기 위해서는 \(r\) 값이 조정되어 \(p\) 에 투영되어야 한다는 것이 핵심입니다. 이러한 이유로 Projection의 이름이Equidistance
가 됩니다.

- 따라서 위 그림과 같이 입사각 \(\theta\) 에 의해 \(r\) 이 결정되고 각 방향에서 같은 입사각 \(\theta\) 에 대하여 같은 \(r\) 을 가지므로 위 그림과 같이 동심원을 그리는 형태로 \(r\) 이 형성됨을 알 수 있습니다. 이와 같은 형태의 렌즈 왜곡을
Barrel Distortion
이라고 합니다.
Fisheye Camera의 Vignetting 영역 인식 방법
- 아래는
Fisheye Camera
의vignetting
영역을 인식하는 방법입니다. Vignetting
영역은 상이 맺히지 않아 일반적으로 검은색으로 나타나며grayscale
형태로 이미지를 나타냈을 때, 0에 가까운 값을 가지게 됩니다.- 아래 코드는 이미지의 상단부터 하단 까지 좌/우 양끝에서
vignetting
영역이 아닌 픽셀 까지 찾은 다음에least square
를 통하여circle
을 찾습니다.circle
은center point
와radius
를 - 마지막으로 안전하게
radius
값을margin
만큼 줄이면 안전하게 내부 영역을 찾을 수 있습니다.
from scipy.optimize import leastsq
# Function to calculate the residuals for least squares circle fit
def calculate_residuals(c, x, y):
xi = c[0]
yi = c[1]
ri = c[2]
return ((x-xi)**2 + (y-yi)**2 - ri**2)
# Initialize lists to store the coordinates of the first non-black pixels from left and right for each row
x_coords = []
y_coords = []
non_vignetting_threshold = 20
inner_circle_margin = 10
img = cv2.imread("image.png")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Scan each row of the image
for i in range(img_gray.shape[0]):
# Scan from the left
for j in range(img_gray.shape[1]):
if np.any(img_gray[i,j] > non_vignetting_threshold):
x_coords.append(j)
y_coords.append(i)
break
# Scan from the right
for j in range(img_gray.shape[1]-1, -1, -1):
if np.any(img_gray[i,j] > non_vignetting_threshold):
x_coords.append(j)
y_coords.append(i)
break
# Convert the lists to numpy arrays
x = np.array(x_coords)
y = np.array(y_coords)
# Initial guess for circle parameters (center at middle of image, radius half the image width)
c0 = [img_gray.shape[1]/2, img_gray.shape[0]/2, img_gray.shape[1]/4]
# Perform least squares circle fit
c, _ = leastsq(calculate_residuals, c0, args=(x, y))
img_color = img.copy()
# Draw the circle on the original image
cv2.circle(img_color, (int(c[0]), int(c[1])), int(c[2])-10, (0, 255, 0), 2);
# Fill in the inside of the circle
mask_valid = np.zeros((img.shape[0], img.shape[1])).astype(np.uint8)
cv2.circle(mask_valid, (int(c[0]), int(c[1])), int(c[2])-inner_circle_margin, 1, -1);

- 위 그림과 같이 내부
circle
을 찾을 수 있으며circle
내부의 영역만 실제 유효한RGB
값이 존재하는 영역임을 알 수 있습니다.

circle
내부 영역을 표시하면 위 그림과 같습니다.