반응형
함수는 입력 이미지(img)를 정규화하고, 이미지의 x, y 방향 미분(gradient), 각도(angle), 그리고 gradient의 크기(weight)를 계산하는 함수입니다. 주요 동작은 다음과 같습니다:
주요 동작 요약
- 이미지 정규화 (Normalization)
- params.norm이 true일 경우, 박스 필터(box_filter)로 이미지를 블러링한 후 원본 이미지에서 빼서 정규화합니다.
- 정규화된 이미지는 특정 범위로 스케일링됩니다.
- Sobel 마스크 생성
- 이미지 미분 계산
- 각도 및 크기 계산
- 각도(img_angle): atan2를 이용해 각 픽셀의 gradient 방향을 계산합니다.
- 크기(img_weight): 각 픽셀의 gradient 크기를 계산합니다.
- 이미지 스케일링
- 입력 이미지를 0~1 범위로 정규화합니다.
함수 시그니처
용도
- 이미지의 특징점 검출, 엣지 검출 등에서 입력 이미지를 전처리하고, gradient 정보를 얻기 위해 사용됩니다.
- OpenCV를 활용하여 효율적으로 구현되어 있습니다.
함수는 입력 이미지에서 체커보드(코너) 후보점을 검출하고, 각 후보점의 위치를 서브픽셀 단위로 정밀하게 보정하는 함수입니다.
주요 동작 요약
- 코너 검출 방식 선택
- params.corner_type과 params.detect_method에 따라 코너 검출 방식을 결정합니다.
- Template Matching: 여러 각도와 스케일의 템플릿을 이미지에 컨볼루션하여 코너 후보를 찾음.
- params.corner_type과 params.detect_method에 따라 코너 검출 방식을 결정합니다.
- 비최대 억제(Non-Maximum Suppression)
- 각 방식에서 얻은 응답 이미지에서 비최대 억제를 통해 코너 후보점을 추출합니다.
- 서브픽셀 위치 보정
함수 시그니처
용도
- 카메라 캘리브레이션 등에서 체커보드 코너의 초기 위치를 검출하고, 위치를 정밀하게 보정하는 데 사용됩니다.
- 다양한 검출 방법을 지원하며, OpenCV 기반으로 효율적으로 구현되어 있습니다.
비최대 억제(Non-Maximum Suppression, NMS)
목적
- 응답 이미지(코너 강도 맵)에서 진짜 코너 후보만 남기고, 주변의 약한 응답(중복 검출)을 제거합니다.
동작 방식
- 각 검출 방식(Template Matching, Hessian, Radon 등)에서 얻은 응답 이미지를 사용합니다.
- non_maximum_suppression 함수가 호출됩니다.
- 결과적으로, 강한 응답을 가진 위치만 코너 후보로 남게 됩니다.
NMS 실제 함수 코드 분석
함수는 코너 후보점 검출에서 **비최대 억제(Non-Maximum Suppression, NMS)**를 수행하는 함수입니다.
즉, 응답 이미지에서 진짜로 강한(최대) 응답을 가진 위치만 남기고, 주변의 약한 응답(중복 검출)을 제거합니다.
주요 동작
- 초기화
- choose_img라는 0으로 채워진 mask 이미지를 만듭니다.
- 블록 단위 최대값 탐색
- 진짜 최대값인지 확인
- 최대값 후보 픽셀을 중심으로 반경 n 내에 더 큰 값이 있는지 한 번 더 확인합니다.
- 만약 더 큰 값이 있으면 해당 후보는 버립니다.
- 임계값 이상만 선택
- 최대값이 임계값(tau)보다 크면, choose_img에 표시합니다.
- 코너 정보 저장
- 마지막으로, choose_img에서 1로 표시된 위치를 corners에 저장합니다.
요약
- 비최대 억제란?
주변보다 값이 큰(최대) 픽셀만 남기고, 나머지는 제거하는 과정입니다. - 이 함수의 역할
응답 이미지에서 진짜 코너 후보만 남기고, 중복 검출을 방지합니다. - 결과
corners에 비최대 억제된 코너 위치와 반경 정보가 저장됩니다.
이 함수 덕분에 코너 검출 결과가 더 정확하고, 중복이 적어집니다.
1. 입력 파라미터
- n = 1 : 블록 및 최대값 확인 영역의 반경(1픽셀)
- tau = 0.01 : 임계값(최소 응답값)
- margin = 5 : 이미지 테두리에서 5픽셀은 코너 검출에서 제외
2. 알고리즘 동작
(1) 블록 시작점 순회
- 이미지의 (i, j) 좌표를
- i = n + margin 부터 img.cols - n - margin까지
- j = (range.start * (n+1)) + margin - 1 부터 range.end * (n+1) + margin - 1까지
- 즉, (n+1)=2 픽셀 간격으로, margin(5) 이후부터 테두리 5픽셀 전까지만 순회
(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 영역 제외하고 코너 저장
- 마지막으로
- margin=5<del>img.rows-margin, margin=5</del>img.cols-margin 범위 내에서
- choose_img가 1인 위치만 코너로 저장
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와 그 위치를 결합해서 누적합니다.
- 수식:
- 의미:
- b는 gradient 방향과 위치 정보를 결합해서
"gradient가 가리키는 방향으로 이동했을 때 만나는 점"을 통계적으로 모은 값입니다.
- b는 gradient 방향과 위치 정보를 결합해서
최종적으로 하는 일
- G와 b를 모두 누적한 뒤,
선형 방정식 G * new_pos = b를 풀어서
**gradient가 가장 잘 만나는 점(new_pos)**을 계산합니다. - 이 점이 바로 서브픽셀 정밀도로 보정된 코너 위치가 됩니다.
요약
- G: 패치 내 gradient 방향의 분산(방향성 정보, 구조 텐서)
- b: gradient와 위치 정보를 결합한 벡터
- G와 b로 선형 방정식을 풀어
코너의 서브픽셀 위치를 계산합니다.
이 방식은 Harris, Shi-Tomasi 등 여러 코너 검출 알고리즘의 위치 보정 단계에서 널리 쓰이는 원리입니다.
반응형
'개발자 > Computer Vision' 카테고리의 다른 글
Dense Optical flow by block matching (0) | 2024.08.10 |
---|---|
Camera Geometry #0(Calibration) (0) | 2024.03.11 |
[Tracking] 딥러닝 DNN 기반 트래킹 정리(2편 DeepSORT 알고리즘) - 작성중 (0) | 2023.11.24 |
[Tracking] 딥러닝 DNN 기반 트래킹 정리(1편 SORT 알고리즘) (3) | 2023.11.24 |
YUV Image 관련 정리 (0) | 2022.09.01 |