본문 바로가기

개발자/Computer Vision

Libcbdetect Calibration 함수 분석 #1

반응형

함수는 입력 이미지(img)를 정규화하고, 이미지의 x, y 방향 미분(gradient), 각도(angle), 그리고 gradient의 크기(weight)를 계산하는 함수입니다. 주요 동작은 다음과 같습니다:

주요 동작 요약

  1. 이미지 정규화 (Normalization)
    • params.norm이 true일 경우, 박스 필터(box_filter)로 이미지를 블러링한 후 원본 이미지에서 빼서 정규화합니다.
    • 정규화된 이미지는 특정 범위로 스케일링됩니다.
  2. Sobel 마스크 생성
    • x, y 방향의 Sobel 마스크(du, dv)를 생성합니다.
  3. 이미지 미분 계산
    • cv::filter2D를 사용해 x, y 방향의 미분(img_du, img_dv)을 계산합니다.
  4. 각도 및 크기 계산
    • 각도(img_angle): atan2를 이용해 각 픽셀의 gradient 방향을 계산합니다.
    • 크기(img_weight): 각 픽셀의 gradient 크기를 계산합니다.
  5. 이미지 스케일링
    • 입력 이미지를 0~1 범위로 정규화합니다.

함수 시그니처

용도

  • 이미지의 특징점 검출, 엣지 검출 등에서 입력 이미지를 전처리하고, gradient 정보를 얻기 위해 사용됩니다.
  • OpenCV를 활용하여 효율적으로 구현되어 있습니다.

함수는 입력 이미지에서 체커보드(코너) 후보점을 검출하고, 각 후보점의 위치를 서브픽셀 단위로 정밀하게 보정하는 함수입니다.


주요 동작 요약

  1. 코너 검출 방식 선택
    • params.corner_type params.detect_method에 따라 코너 검출 방식을 결정합니다.
      • Template Matching: 여러 각도와 스케일의 템플릿을 이미지에 컨볼루션하여 코너 후보를 찾음.
  2. 비최대 억제(Non-Maximum Suppression)
    • 각 방식에서 얻은 응답 이미지에서 비최대 억제를 통해 코너 후보점을 추출합니다.
  3. 서브픽셀 위치 보정
    • 각 코너 후보점 주변의 gradient patch(img_du, img_dv)를 추출하여, 2x2 행렬 G와 벡터 b를 계산합니다.
    • G와 b를 이용해 새로운 코너 위치를 계산하고, 변화량이 반경의 2배 이내면 위치를 보정합니다.

함수 시그니처

용도

  • 카메라 캘리브레이션 등에서 체커보드 코너의 초기 위치를 검출하고, 위치를 정밀하게 보정하는 데 사용됩니다.
  • 다양한 검출 방법을 지원하며, OpenCV 기반으로 효율적으로 구현되어 있습니다.

비최대 억제(Non-Maximum Suppression, NMS)

목적

  • 응답 이미지(코너 강도 맵)에서 진짜 코너 후보만 남기고, 주변의 약한 응답(중복 검출)을 제거합니다.

동작 방식

  • 각 검출 방식(Template Matching, Hessian, Radon 등)에서 얻은 응답 이미지를 사용합니다.
  • non_maximum_suppression 함수가 호출됩니다.
    • 입력: 응답 이미지, 윈도우 크기(반경), 임계값, 반경, 결과를 저장할 corners
    • 과정:
      1. 각 픽셀을 중심으로 반경 r 내에서 가장 큰 값인지 확인합니다.
      2. 임계값(threshold) 이상인 경우만 코너 후보로 인정합니다.
      3. 중복되는 코너는 하나만 남기고 제거합니다.
  • 결과적으로, 강한 응답을 가진 위치만 코너 후보로 남게 됩니다.

NMS 실제 함수 코드 분석

함수는 코너 후보점 검출에서 **비최대 억제(Non-Maximum Suppression, NMS)**를 수행하는 함수입니다.
즉, 응답 이미지에서 진짜로 강한(최대) 응답을 가진 위치만 남기고, 주변의 약한 응답(중복 검출)을 제거합니다.

주요 동작

  1. 초기화
    • choose_img라는 0으로 채워진 mask 이미지를 만듭니다.
  2. 블록 단위 최대값 탐색
    • 이미지 전체를 (n+1)x(n+1) 블록 단위로 순회합니다.
    • 각 블록에서 최대값을 가진 픽셀의 위치(maxi, maxj)와 값(maxval)을 찾습니다.
  3. 진짜 최대값인지 확인
    • 최대값 후보 픽셀을 중심으로 반경 n 내에 더 큰 값이 있는지 한 번 더 확인합니다.
    • 만약 더 큰 값이 있으면 해당 후보는 버립니다.
  4. 임계값 이상만 선택
    • 최대값이 임계값(tau)보다 크면, choose_img에 표시합니다.
  5. 코너 정보 저장
    • 마지막으로, choose_img에서 1로 표시된 위치를 corners에 저장합니다.

요약

  • 비최대 억제란?
    주변보다 값이 큰(최대) 픽셀만 남기고, 나머지는 제거하는 과정입니다.
  • 이 함수의 역할
    응답 이미지에서 진짜 코너 후보만 남기고, 중복 검출을 방지합니다.
  • 결과
    corners에 비최대 억제된 코너 위치와 반경 정보가 저장됩니다.

이 함수 덕분에 코너 검출 결과가 더 정확하고, 중복이 적어집니다.

 

1. 입력 파라미터

  • n = 1 : 블록 및 최대값 확인 영역의 반경(1픽셀)
  • tau = 0.01 : 임계값(최소 응답값)
  • margin = 5 : 이미지 테두리에서 5픽셀은 코너 검출에서 제외

2. 알고리즘 동작

(1) 블록 시작점 순회

(2) (n+1)x(n+1) 영역에서 최대값 찾기

  • 각 시작점 (i, j)에서
    • 2x2 영역(i,i+1, j,j+1) 내에서 최대값(maxval)과 그 위치(maxi, maxj)를 찾음

(3) (2n+1)x(2n+1) 영역에서 진짜 최대값인지 확인

  • 찾은 최대값 후보(maxi, maxj)를 중심으로
    • 3x3 영역(maxi-1<del>maxi+1, maxj-1</del>maxj+1)에서
    • 더 큰 값이 있으면 후보에서 제외

(4) 임계값 이상만 선택

  • 최대값이 tau=0.01보다 크면
    • choose_img에 해당 위치를 1로 표시

(5) margin 영역 제외하고 코너 저장


3. 결과

  • 이미지 테두리 5픽셀은 무시
  • 2x2 블록(시작점 기준)에서 최대값 후보를 찾고, 3x3 영역에서 진짜 최대값인지 확인
  • 응답값이 0.01보다 큰 위치만 코너로 인정
  • 중복 검출이 줄고, 신뢰도 높은 코너만 남음

요약 예시

  • 예를 들어, 1920x1080 이미지라면
    • (5,5)~(1914,1074) 영역에서만 코너 후보가 나옴
    • 각 2x2 블록마다 최대값 후보를 찾고, 3x3에서 진짜 최대값인지 확인
    • 0.01보다 큰 응답만 코너로 저장




2. 서브픽셀 위치 보정(Subpixel Refinement)

목적

  • 코너 후보의 위치를 픽셀 단위보다 더 정밀하게(서브픽셀 수준) 보정합니다.

동작 방식

  • 각 코너 후보점에 대해 다음 과정을 반복합니다.

1) 코너 주변 패치 추출

2) 2x2 행렬 G와 2x1 벡터 b 계산

  • 패치 내 각 픽셀의 gradient(o_du, o_dv)를 사용해 G와 b를 누적 계산합니다.
  • G와 b의 의미:
    • G: 주변 gradient 방향의 분산(방향성 정보)
    • b: gradient와 위치 정보를 결합한 벡터
  • 중심 픽셀(코너 자체)은 제외하고, gradient 크기가 너무 작은 픽셀도 제외합니다.

3) 새로운 위치 계산

  • 선형 방정식 G * new_pos = b를 풀어 새로운 위치 new_pos를 구합니다.
    • cv::Mat new_pos = G.inv() * b;
  • 새 위치와 기존 위치의 차이가 반경의 2배 이내면, 코너 위치를 보정합니다.

요약

  • 비최대 억제: 응답 이미지에서 진짜 코너만 남기고 중복 제거.
  • 서브픽셀 보정: gradient 정보를 활용해 코너 위치를 더 정확하게 계산.

이 두 과정 덕분에 코너 검출의 정확도와 신뢰도가 크게 향상됩니다.

 

2) 2x2 행렬 G와 2x1 벡터 b 계산

개념적 배경

  • 코너의 정확한 위치를 찾으려면, 코너 주변의 gradient(기울기) 정보를 활용해
    "이론적으로 gradient가 가장 잘 만나는 점"을 계산합니다.
  • 이 과정은 최소자승법(Least Squares) 기반의 위치 보정이며,
    실제로는 gradient 방향의 분산과 위치 정보를 결합해서
    "gradient가 가장 잘 교차하는 점"을 수식적으로 구하는 것입니다.

G와 b의 수식적 의미

G: 2x2 행렬 (gradient 방향의 분산, 구조 텐서)

  • 각 픽셀의 gradient 벡터 ([o_{du}, o_{dv}])를 사용해
    주변 패치의 gradient 방향 분포를 누적합니다.
  • 수식:
    •  
    •  
    •  
    •  
  • 의미:
    • G는 패치 내 gradient 벡터들의 방향성과 크기 분포를 담고 있습니다.
    • G가 클수록, 해당 위치가 gradient가 많이 모이는(즉, 코너일 가능성이 높은) 곳임을 의미합니다.
    • 흔히 "구조 텐서(structure tensor)"라고도 부릅니다.

b: 2x1 벡터 (gradient와 위치 정보 결합)

  • 각 픽셀의 gradient와 그 위치를 결합해서 누적합니다.
  • 수식:
    •  
    •  
    •  
    •  
    여기서 (x, y)는 패치 내 픽셀의 실제 좌표입니다.
  • 의미:
    • b는 gradient 방향과 위치 정보를 결합해서
      "gradient가 가리키는 방향으로 이동했을 때 만나는 점"을 통계적으로 모은 값입니다.

최종적으로 하는 일

  • G와 b를 모두 누적한 뒤,
    선형 방정식 G * new_pos = b를 풀어서
    **gradient가 가장 잘 만나는 점(new_pos)**을 계산합니다.
  • 이 점이 바로 서브픽셀 정밀도로 보정된 코너 위치가 됩니다.

요약

  • G: 패치 내 gradient 방향의 분산(방향성 정보, 구조 텐서)
  • b: gradient와 위치 정보를 결합한 벡터
  • G와 b로 선형 방정식을 풀어
    코너의 서브픽셀 위치를 계산합니다.

이 방식은 Harris, Shi-Tomasi 등 여러 코너 검출 알고리즘의 위치 보정 단계에서 널리 쓰이는 원리입니다.

반응형