반응형
안녕하세요! ✨
앞서 Day 11에서는 카메라 모델(Pinhole Camera Model) 을 통해 카메라 투영의 기본 원리를 배웠습니다.
오늘은 실제 카메라가 가진 왜곡(distortion)을 보정하는 방법, 즉 카메라 캘리브레이션(Camera Calibration) 을 Python OpenCV로 실습해보겠습니다.

🔍 왜 카메라 캘리브레이션이 필요한가?
실제 카메라는 완벽한 핀홀 모델과 달리 여러 가지 왜곡이 존재합니다.
- 방사형 왜곡(Radial Distortion): 화면이 둥글게 휘는 현상 (배럴, 핀쿠션 왜곡)
- 접선 왜곡(Tangential Distortion): 렌즈와 센서 정렬 불량으로 이미지가 기울어짐
👉 이 왜곡을 보정해야 정확한 차선 인식, 객체 탐지, SLAM 등이 가능해집니다.
⚙️ OpenCV를 활용한 캘리브레이션 절차
1. 체커보드(Checkerboard) 패턴 준비
- 흑백 격자 무늬(예: 9x6 체커보드)를 출력해 카메라로 여러 장 촬영합니다.
- 다양한 각도와 거리에서 촬영해야 정확도가 높아집니다.
2. OpenCV 코드 예제
python
import cv2
import numpy as np
import glob
# 체커보드 크기
CHECKERBOARD = (9, 6)
# 3D 점 (체커보드 기준 좌표계)
objp = np.zeros((CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
objpoints = [] # 3D 점 저장
imgpoints = [] # 2D 점 저장
images = glob.glob('calibration_images/*.jpg') # 촬영 이미지 경로
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 체커보드 코너 검출
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, None)
if ret:
objpoints.append(objp)
imgpoints.append(corners)
# 코너 표시
cv2.drawChessboardCorners(img, CHECKERBOARD, corners, ret)
cv2.imshow('Corners', img)
cv2.waitKey(100)
cv2.destroyAllWindows()
# 카메라 캘리브레이션
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
print("카메라 행렬:\n", mtx)
print("왜곡 계수:\n", dist)
import numpy as np
import glob
# 체커보드 크기
CHECKERBOARD = (9, 6)
# 3D 점 (체커보드 기준 좌표계)
objp = np.zeros((CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
objpoints = [] # 3D 점 저장
imgpoints = [] # 2D 점 저장
images = glob.glob('calibration_images/*.jpg') # 촬영 이미지 경로
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 체커보드 코너 검출
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, None)
if ret:
objpoints.append(objp)
imgpoints.append(corners)
# 코너 표시
cv2.drawChessboardCorners(img, CHECKERBOARD, corners, ret)
cv2.imshow('Corners', img)
cv2.waitKey(100)
cv2.destroyAllWindows()
# 카메라 캘리브레이션
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
print("카메라 행렬:\n", mtx)
print("왜곡 계수:\n", dist)
3. 보정된 이미지 확인
python
img = cv2.imread('test.jpg')
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
# 보정 적용
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
cv2.imshow('Original', img)
cv2.imshow('Undistorted', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
# 보정 적용
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
cv2.imshow('Original', img)
cv2.imshow('Undistorted', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
🛠 활용 포인트
- 차선 인식: 왜곡 없는 영상으로 차선 검출 정확도 향상
- 객체 인식: 보행자·차량 탐지 신뢰도 개선
- 3D 재구성: SLAM, 스테레오 비전에서 필수
📌 정리
- 카메라 캘리브레이션은 렌즈 왜곡을 보정하는 과정
- OpenCV에서 체커보드 이미지를 활용해 손쉽게 구현 가능
- 자율주행차의 영상 인식 정확도를 높이는 핵심 과정
반응형
🚀 다음 글 예고
다음 글에서는 [Day 13: 영상 처리 기초 (Canny Edge, Hough Transform)] 을 다룹니다.
영상에서 윤곽선과 직선을 검출하는 기법을 소개하고, 차선 인식의 기초를 실습해보겠습니다.
✅ 오늘 글이 도움이 되셨다면 좋아요와 공유 부탁드립니다.
반응형
'자율주행' 카테고리의 다른 글
| 🛣️ Day 14: 차선 검출 실습 (OpenCV) (0) | 2025.09.10 |
|---|---|
| 🎥 Day 13: 영상 처리 기초 (Canny Edge, Hough Transform) (0) | 2025.09.09 |
| 📸 Day 11: 카메라 모델 (Pinhole Camera Model) (0) | 2025.09.07 |
| 🚗 Day 10: ROS2에서 Radar 센서 플러그인 다뤄보기 (0) | 2025.09.06 |
| 🚗 Day 9: Radar와 LiDAR 데이터 비교 (0) | 2025.09.05 |