Konsla Hobby

konsla99 님의 블로그 입니다.

Computer Vision/캘리브레이션

카메라 모델과 캘리브레이션 -캘리브레이션

Konsla99 2025. 10. 22. 00:10

카메라 캘리브레이션 (Camera Calibration) 이론)

카메라 모델과 캘리브레이션-카메라모델)

캘리브레이션

cv::calibrateCamera(); 활용
  • OpenCV가 카메라 파라미터를 자동 계산한다.
  • 여러 각도에서 촬영 -> 이미지마다 변하는 상대적 위치, 방향, 내부 파라미터 계산

여러각도에서 보기 위해서 대상을 회전, 평행이동이 필요하다.

                    X_o                      Y_o                      Z_o                  O_o                               R              t⃗              (     ,     )                          X_c                      Y_c                      Z_c                  O_c          좌표계 변환: Object → Camera        회전 행렬 R과 평행이동 벡터 t⃗로 변환

회전행렬

$$R_x(\psi) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\psi & -\sin\psi \\0 & \sin\psi & \cos\psi\end{bmatrix}R_y(\varphi) = \begin{bmatrix}\cos\varphi & 0 & \sin\varphi \\0 & 1 & 0 \\-\sin\varphi & 0 & \cos\varphi\end{bmatrix} R_z(\theta) = \begin{bmatrix}\cos\theta & -\sin\theta & 0 \\\sin\theta & \cos\theta & 0 \\0 & 0 & 1\end{bmatrix}$$

$$R = R_x(\psi) R_y(\varphi) R_z(\theta)$$ $$R\cdot R^T = I$$

평행 이동 벡터

$$\vec{T} = \vec{O}_{\text{obj}} - \vec{O}_{\text{cam}}$$

최종 좌표 이동

$$\vec{P}_c = R(\vec{P}_o - \vec{T})$$


캘리브레이션 보드

카메라 파라미터를 추정하기 위해 3D공간의 점이 2D이미지에서 어떻게 보이는지 대응점이 필요하다. 이를 위해 캘리브레이션 패턴을 활용한다.

  • 체스보드
  • 원형 그리드
  • QR코드

이러한 패턴은 이미지상의 좌표를 알기 쉽기 때문에 사용된다.

체스 보드 : findChessboardCorners()

참고자료

bool cv:findChessboardCorners(
	cv::InputArray image,  //8비트 체스판 이미지
	cv::size PatternSize,  //행, 열당 코너의 수
	cv::OutputArray corners,// 검출된 코너를 저장
	//보조 옵션
	int flags = cv::CALIB_CB_ADAPTIVE_THRSH
			  + cv::CALIB_CB_NOMALIZE_IMAGE
)
  • 코너란 내부의 코너를 좌표로 저장
  • 기본적으로 평균 밝기에 따라 이미지의 임계값을 지정
  • 플레그 사용시 적응형 임계값을 사용
    • NOMALIZE_IMAGE : 임계값 도달전 equalizeHist로 정규화
    • FILTER_QUADS: 검은 사각형의 투영도에서 얻은 사각형을 찾는다.
      • 근사법이며, 방사 왜곡 존재시 이방법은 참이 아님
    • FAST_CHECK: 빠른 스캔후 코너가 없으면 이미지 스킵
      • (체스판이 없는 이미지가 있다면 사용)
cv::cornerSubPix()
//findChessboardCorners()가 대략적인 위치만 얻음
//상대적인 위치 보정을 위해 사용
bool cv:drawChessboardCorners(
	cv::InputArray image,   //입출력할 이미지(8UC3)
	cv::size PatternSize,   //행, 열당 코너의 수
	cv::OutputArray corners,// 검출된 코너를 저장
	bool patternWasFound     // find함수의 반환값 
)
  • 코너는 색상있는 원으로 표기
  • 따라서 8UC3이미지 필요

원형 그리드 : findCirlcesGrid()

  • findChessboardCorners() 와 같은 방식으로 처리
  • 사용하는 이미지가 다를 뿐이다.
  • 이때 코너대신 검출된 원의 중심 좌표를 반환한다.
  • 이미지와 같은 비대칭형 그리드를 많이 사용한다.

비대칭형 그리드

  • 행과 열을 기억하는것이 중요하다.
  • 반복 수행 결과에서 안정성, 결과의 질이 체스판보다 우수하다.

호모그래피

  • 한 평면에서 다른 평면 까지의투영 매핑
  • 2차원 평면상의 한 점을 카메라의 촬영센서에 매핑하는것

$$\vec{q} = \begin{bmatrix} x \\ y \\ w \end{bmatrix}, \vec{Q} = \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}$$

$$\vec{q}=s \cdot H \cdot \vec{Q}$$

여기서 H는 실제좌표를 이미지 평면에 옮기는 과정으로 내부 파라미터* (회전+ 평행이동) 임을 알 수 있다.

Q = 3차원 좌표의 이미지 평면의 2차원 동차좌표다. 따라서 Z = 0 이 되므로 다음과 같은 수식이 성립한다.

$$q = K \begin{bmatrix} r_1 & r_2 & r_3 & t \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}$$

$$=> q = K \begin{bmatrix} r_1 & r_2 & t \end{bmatrix} \begin{bmatrix} X \\ Y \\ 1 \end{bmatrix}$$ $$\vec{q} = s \cdot H \cdot \vec{Q}일 때 H = M \cdot [r_1 r_2 t]$$

cv::findHomography(
	cv::InputArray srcPoints,   //2차원 소스 점
	cv::InputArray dstPoints,   //2차원 결과점
	cv::size method = 0         //
	double ransacReprojThreshold =3 //최대 재투영 오차
	cv::OutputArray mask = cv::noArray,//0이 아닌 점에 대해서만 사용
)
  • InputArray 는 원본 평면, 대상 평면의 점
  • 2차원의 점이므로 CV_32FC2 요소인 Nx2, Nx1 배열
  • method = 0 이면 모든 점을 고려해 재투영 오차 최소화
  • 재투영 오차는 원본의 점과 대상의 점 사이를 H배한 유클리드 거리의 제곱 합
  • ransacReprojThreshold : RANSAC 에서만 사용됨
  • mask : robust 방식에서만 사용,어떤점이 H계산에 사용됐는지 표기

Noise가 많은 경우

method에서 알고리즘을 수정할 수 있다. 3가지 robust 방식을 제공

RANSAC방식

  • 입력된 점의 부분집합을 무작위 선택
  • 해당 집합의 호모그래피 행렬 계산
  • 초기추정과 대략일치하는 점을 찾는다.
  • 가장 많은 정상치를 갖는 경우를 찾는다.

LMeds 알고리즘

  • 제곱의 최소 중간값 이ㅏㄹ고리즘
  • 기존의 평균 제곱 오차 최소화가아닌 중간값 오차 최소화
  • 정상치가 50%이상인 경우 사용

RHO

  • Ransac에 PROSAC 가중치 적용
  • 이상치가 많은 경우 더 빠르다
반응형
END