logo

[computer-vision] 카메라 교정

 

카메라 왜곡

  • 카메라 렌즈의 효과로 생기는 왜곡: 볼록하면 배럴(barrel), 오목하면 핀쿠션(pincushion)
  • 교정 방법
    • 교정 패턴(Calibration pattern): 다양한 관점에서 알려진 차원의 패턴의 이미지를 여러 장 캡처 (체커보드 패턴, 원형 패턴 등)
    • 기하학적 단서(Geometric clues): 직선과 소실점과 같은 기하학적 단서를 사용
    • 딥러닝 기반: 다양한 렌즈의 이미지를 딥러닝으로 학습시켜 보정 (한 장만 있어도 사용할 수 있음, 학습된 모델이 필요)
 

체커보드 패턴 다운로드 받기

 

체커보드 패턴의 교차점 찾기

src = cv.imread('fisheye01.jpg')
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) # 흑백으로
patternSize = 7, 10 # + 모양 교차점의 개수(7행 10열)
flags = (cv.CALIB_CB_ADAPTIVE_THRESH | cv.CALIB_CB_FAST_CHECK | 
cv.CALIB_CB_NORMALIZE_IMAGE)
# 교차 찾기(찾는데 성공하면 retval == True)
retval, corners = cv.findChessboardCorners(gray, patternSize, flags=flags)
 

교차점을 더 정확하게

# 11x11 범위에서 더 정확하게 찾기. (-1, -1)은 제외하는 범위가 없다는 뜻.
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners2 = cv.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
# 찾은 교차점을 원본 이미지에 추가
img_corner = cv.drawChessboardCorners(src, patternSize, corners2, retval)
 

교정 준비

# fisheye 로 시작하는 jpg 파일 모두 찾기 (*은 "아무 글자들"을 뜻함)
import glob
filenames = glob.glob('fisheye*.jpg')

# 좌표들
objpoints = [] # 3차원 좌표
imgpoints = [] # 2차원 좌표
objp = np.zeros((1, patternSize[0] * patternSize[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:patternSize[0], 0:patternSize[1]].T.reshape(-1, 2)
 

모든 이미지에서 교차점 좌표 찾기

for fname in filenames: # 모든 파일에 대해
    gray = cv.imread(fname, cv.IMREAD_GRAYSCALE)
    retval, corners = cv.findChessboardCorners(gray, patternSize,flags=flags)
    if retval: # 교차점을 찾았으면
        objpoints.append(objp) # 3차원 좌표 추가
        corners2 = cv.cornerSubPix(gray, corners, (11,11),(-1,-1), criteria)
        imgpoints.append(corners2) # 2차원 좌표 추가
 

카메라 교정

ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(
    objpoints, imgpoints, gray.shape[::-1], None, None)
  • mtx: 카메라에서 3차원 이미지를 2차원으로 만드는 행렬
  • dist: 렌즈의 왜곡
  • rvecs: 카메라의 회전
  • tvecs: 카메라의 수평이동
 

이미지에서 렌즈 왜곡 교정

src = cv.imread('fisheye01.jpg') # 이미지 열기
# 왜곡 제거를 위한 교정치 얻기
h,w = gray.shape[:2]
newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
dst = cv.undistort(src, mtx, dist, None, newcameramtx) # 교정치 적용
 

ArUco 마커

  • Augmented Reality University of Cordoba의 약자
  • 흑백 정사각형 패턴 + 내부 이진 코드 (QR 코드와 비슷)
  • 단일 마커만으로도 6DoF pose (위치 + 자세) 추정 가능
  • 검출 속도가 빠르고 구현이 쉬움
  • 마커 크기만 정확히 알면 실공간 좌표 계산 가능
  • 일부가 가릴 경우 식별이 안됨
 

ArUco 마커의 응용

  • ArUco 보드(왼쪽): 여러 개의 마커로 보드를 구성, 일부가 가려도 식별 가능
  • ChArUco 보드 (가운데, Chessboard + ArUco): 정밀한 카메라 교정에 사용
  • 다이아몬드 마커(오른쪽): ArUco 마커를 다이아몬드 형태로 배치하여 좌표와 방향을 더 정확히 탐지
Previous
기하학적 변환