728x90

아웃라이어의 영향을 제거하거나 약화시키는 방법이 필요

 

-> M 추정, 최소 제곱 중앙법이 있음

 

 

 

최소제곱법으로 구한 추정량을 아래와 같이 정의할때

 

 

M 추정 M estimator

 

m 추정을 활용한 식은 아래와 같음.

 

 

rho(r_i) = r_i^2이면 최소제곱법과 동일.

 

하지만 r_i가 일정 값 이상(오차가 크다면)이면 함수의 크기를 줄임.

 

이때 함수 rho()는 huber 함수로,

 

 

r이 임계값보다 작은 경우 2차 곡선 사용.(오차가 작으므로)

 

r이 임계값보다 큰경우 1차 곡선을 사용하여 오차의 영향력을 보다 줄임(오차가 크므로)

 

 

 

 

 

 

 

 

 

최소 제곱 중앙값 LMeds: Least median of Squared

 

최소 제곱 중앙값을 활용한 식은 아래와 같음.

 

 

n개의 특징점 중 중앙값을 취함.

 

중앙값인 매칭쌍의 오차를 최소로 하는 기하 변환 행렬 T의 매개변수들을 찾는 방법

 

 

 

 

붕괴점 breakdown point

 

더 이상 추정 알고리즘이 동작하지 않는 아웃라이어 비율.

 

최소제곱법은 붕괴점이 0%

 

최소제곱중앙값은 50%

 

 

 

 

 

 

 

 

RANSAC을 이용한 기하변환 추정

 

입력 : 대응쌍 집합 X, 반복 회수, 인라이어 판단 임계치 t, 인라이어 집합 크기 d, 적합오차 e

출력 : 기하 번환 행렬 T

 

 

Q = []

for i in range(k):
    X에서 임의의 대응쌍 3개 선택.
    세 대응쌍으로 최소제곱법으로 T_j 추정
    세 대응쌍은 인라이어로 판단
    
    m = X에서 세 대응쌍을 제외한 대응쌍 집합)
    for p in m:
        # T_j로 첫번째 대응쌍 요소를 변환시킨 p.1'와 p.2의 오차가 t보다 작은경우
        # 인라이어로 판단
        if  (p.2 - T_j*p.1) < e:
           p를 인라이어에 추가
           
    # 인라이어의 개수가 d이상이 되면
    if |inlier| >= d:
        인라이어 요소(대응쌍)들로 새 T_j 계산
    
    # 구한 T_j의 적합 오차가 e보다 작은경우 Q에 추가
    if T_j 적합 오차 < e:
        T_j를 Q에 추가
 
 Q에 있는 것들 중에서 가장 좋은 변환행렬 T를 선정

 

 

 

 

 

 

300x250
728x90

기하 정렬/기하 관계의 필요성

 

앞서 살펴본 매칭 과정은

 

지역 정보. 특징점의 기술자만을 사용하여 대응점들을 찾았다.

 

하지만 동일한 물체끼리는 기하 변환 관계를 가치는데, 이 기하 정렬 geometrical alignment조건 을 고려할 필요가 있음.

 

 

www.cc.gatech.edu/~hays/compvision/proj2/

 

 

 

 

기하 변환을 위한 최소 제곱 법

 

그동안 선형 모델을 구할때 최소 제곱법을 자주 사용했었는데,

 

컴퓨터 비전 문제에 최소 제곱법을 사용해보자.

 

위와 같은 두 영상에서 대응쌍 구했다고 하자

 

X = {(a1, b1), (a2, b2), . . ., (a_n, b_n)}

 

이 대응 쌍들은 기하 변환을 통해 얻었을탠대

 

회동, 이전, 크기 변환을 포함한 기하 변환 행렬 T로 나타내자

 

 

 

기하 변환 행렬 T로 a_i들 맵핑하여 b_i'를 얻을수 있게 된다.

 

 

 

 

실제 b_i와 a_i를 변환하여 얻은 b_i'사이에는 오차가 존재할텐대

 

이 오차를 최소화 하는 변환 행렬 T를 구하는게 목표가 되겠다.

(변환 행렬의 파라미터 6개를 구한다)

 

 

오차 E(T)를 기하 변환 행렬 T의 각 요소들로 편미분한 것을 0으로 하여 식을 얻고

 

행렬식을로 표현하면 아래와 같이 정리할 수 있다.

 

 

 

 

최소 제곱법의 한계

 

하지만 최소 제곱법은 오차가 정규 분포를 따르는 경우 정상적으로 동작한다.

 

그래서 아웃라이어의 영향을 크게 받는데,

 

아웃라이어를 제거하거나 이에 강인한 기하 변환 행렬을 구할 수 있는 방법이 필요하다.

 

https://slideplayer.com/slide/2342847/

 

 

 

 

 

 

 

 

 

 

 

300x250
728x90

나이브 최근접 이웃 방법, 단순 최근접 이웃 매칭

 

기본적인 매칭쌍 탐색 방법은 두 영상 사이 모든 점들을 매칭시켜 보는 것으로

 

1번 영상 특징이 m개, 2번 영상의 특징이 n개인 경우 mn번을 수행함.

 

 

대강 이런 식이 되지 않을까 싶다..

 

아래의 경우 최근접 이웃으로 했는데 조금 수정해서 최근접 거리 비율로 고칠수도 있겠다.

m = len(keypoints1)
n = len(keypoints2)


mlist = []

for i in range(m):
    shortest = inf
    idx_lst = []
    for j in range(n):
        dist = get_dist(keypoints1[i], keypoints2[j])
        if dist < smallest:
            shortest = dist
            if shortest < T:
                ids_lst.append(j)
     
     match = [i, min(idx_lst)]
     mlist.append(match)

 

하지만 이 방법은 가능한 모든 특징 쌍들에 대해 계산하므로 너무 오랜 시간이 걸리게 된다.

 

이 외 방법으로 이진 검색 트리를 개조한 kd 트리나 해싱을 이용할수 있겠다.

 

 

 

 

 

이진 검색 트리 binary search tree

 

이진 검색 트리는 특정 노드를 기준으로 왼쪽은 작은 값 오른쪽은 큰 값을 가지는 트리를 말한다.

 

아래의 그림을 보면 값이 8인 루트 노드를 기준으로 왼쪽으로는 8보다 작고, 우측으로는 8보다 큰 값을 노드들이 갖는다.

 

 

검색 키를 4라고 지정하면,

 

1. 8보다 4가 작으므로 왼쪽 노드, 노드 값이 다르므로 한번 더

 

2. 3보다 4가 크므로 우측 노드, 노드 값이 다르므로 한번 더 

 

3. 6보다 4가 작으므로 좌측 노드, 탐색 완료

 

이진 검색 트리를 이용해 3번만에 4를 찾을수 있었다.

 

 

https://en.wikipedia.org/wiki/Binary_search_tree

 

 

이를 슈도 코드로 나타내면 아래와 같이 정리할수 있겟다.

 

트리의 깊이는 log(n)이므로 빅오 표기법으로 O(log(n)) 시간에 검색 마침

 

t = binary_search(T, v):
if (t = Null):
    v가 존재하지 않음
else:
    키가 v인 노드 t를 반환

def binary_search(t, v):
    if t == Null:
        return Null
    if t.key == v:
        return t
    else:
        if (v < t.key): # 탐색 값, 키가 현재 노드의키보다 작으면 왼쪽 노드 탐색
            return binary_search(t.leftchild, v)
        else: # 아니면 우측 자식 노드 탐색
            return binary_search(t.rightchild, v)

 

 

 

 

 

 

 

 

 

 

 

 

 

빠른 특징 기술자 탐색을 위한 자료구조 - kd 트리

 

이진 트리 탐색 방법을 생각해보면

 

특징 벡터를 기반한 트리를 만들어 탐색함으로써

 

모든 특징벡터의 거리를 구해서 비교하는 기존 방법보다 빠르게 탐색할수 있겠다.

 

 

 

 

 

하지만 특징 벡터는 이진 트리처럼 1개의 값을 가지는게 아니라

 

SIFT 기술자는 128차원을 가지니 이에 맞는 트리 생성 알고리즘이 필요하다.

 

1975년 벤트리는 kd 트리를 제안함.

 

k dimension을 다루므로 kd 트리라 부르는것 같다.

 

 

kd 트리 분할 기준 2가지

 

1. 분할 축 선택

 

각 차원 분산 중 최대 분산을 가지는 차원 k를 분할 축으로 선정

 

2. 분할 기준 선정하기

 

차원 k 기준 정렬, 중앙값을 분할 기준으로 사용

 

 

X = [x_1, x_2, ...]

T = get_kdtree(X)

def get_kdtree(X):
    if X == Null:
        return Null
    else if X == 1: #단일 노드이면
        node.vector = X.m
        node.leftchild, node.rightchilde = Null
        return node
    
    else:
         k = 주어진 특징 벡터의 차원들 중에서 최대 분산을 갖는 차원
         X_sorted = sort(X, k)
         X_left, X_median, X_right = get_divided(X_sorted)
         
         node.dim = k
         node.vector = X_median
         node.leftchild = get_kdtree(X_left)
         node.rightchild = get_kdtree(X_right)
         return node
    

 

 

 

kd 트리를 이용한 최근접 이웃 탐색

 

새 특징 벡터 x가 주어질 때, 최근접 이웃을 탐색해보자

 

1. 루트 노드의 분할기준 차윈 k을 확인하다.

 

2. 입력 벡터의 k차원 값과 루트노드의 기준값을 비교하여 좌측 혹은 우측 자식 노드의 입력으로 보낸다.

 

위 1과 2를 단일 노드에 도착할때까지 판복한다.

 

 

이렇게 탐색한 단일 노드는 항상 최근접이라는 보장은 없음.

 

다른 트리 가지에 찾아낸 노드 보다 가까운 벡터가 존재할수 있기 때문

 

 

 

 

개선된 최근접 이웃 탐색

 

위 방법에서는 반대편 노드를 확인하지 못해, 분명하게 최근접인지 확인할수 없음.

 

현재까지 탐색한 노드들을 스택에 저장 -> 깊이 방향 탐색 수행

 

리프 노드 도착시 백트래킹 수행 -> 입력 벡터 x와 스택에서 꺼낸 노드 t의 특정 차원 오차가 최근접 거리보다 작은경우

 

=> 노드 t의 반대편에 더 가까운 노드가 존재할 가능성이 있음. 재귀 탐색 수행

 

 

이 방법은 노드가 많더라도 log(n)으로 빠른 탐색이 가능,

 

하지만 특징 벡터의 차원이 10차원 이상일 경우 모든 특징벡터를 수행하는것과 비슷해져 성능이 떨어짐.

 

#지나온 노드를 저장할 스택 생성
stack s = null;

# 현재 최근접 거리
current_best = inf
# 현재 최근접 노드
nearest = Null

search_kdtree(T, x)



def search_kdtree(T, x):
    t = T
    # 리프 노드가 아니면
    while is_leaf(t) == False:
        # 현재 차원기준, x가 현재노드보드 작다
        # 오른쪽 자식 노드는 스택에 대입
        # 왼쪽 자식노드는 t에 대입
        if x[t.dim] < t.vector[t.dim]
            s.push(t, "right")
            t = t.leftchild
        else
            s.push(t, "left")
            t=t.rightchild
    # 현재 노드 t와 x 거리 계산
    d = dist(x, t.vector)
    if d < current_best:
        current_best = d
        nearest = t
    
    #거쳐온 노드에 대해 최근접 가능성 여부 확인
    while s != null:
        t1, other_side = s.pop()
        #입력 벡터 x와 거쳐온 벡터 t1의 거리 계산
        d = dist(x, t1.vector)
        
        #거쳐왔던 벡터 t1이 최적이라면, 현재 최근접 거리와 벡터 변경
        if d < current_best
            current_best = d
            nearest = t1
        
        # (벡터 x의 어느 차원의 값 - t1의 어느 차원 값) < current_best
        # t1의 반대편 t_other에 보다 가까운 점이 존재할 가능성이 있음.
        if (x, t1.vector)의 분할 평면까지 거리 < current_best:
            t_other = t1의 other_side 자식 노드
            search_kdtree(t_other, x)

 

 

 

 

 

 

 

 

 

 

 

 

 

kd 트리를 이용한 근사 최근접 이웃 탐색

 

최근접 이웃이거나 가까운 이웃(근사 최근접 이웃 approximate nearest neighbor)을 찾는 방법

 

위 방법에서 스택 대신 우선 순위 큐인 힙을 사용

 

x로부터 거리가 우선순위로 이용됨.

 

-> 거쳐온 순서대로 백트래킹을 수행한 스택과 달리, 가장 거리가 가까운 노드부터 수행

 

추가로 try_allowed로 조사 횟수제한

 

 

#지나온 노드를 저장할 힙 생성
heap s = null;

# 현재 최근접 거리
current_best = inf
# 현재 최근접 노드
nearest = Null

# 비교 횟수
try = 0


search_kdtree(T, x)

def search_kdtree(T, x):
    t = T
    # 리프 노드가 아니면
    while is_leaf(t) == False:
        # 현재 차원기준, x가 현재노드보드 작다
        # 오른쪽 자식 노드는 스택에 대입
        # 왼쪽 자식노드는 t에 대입
        if x[t.dim] < t.vector[t.dim]
            s.push(t, "right")
            t = t.leftchild
        else
            s.push(t, "left")
            t=t.rightchild
    # 현재 노드 t와 x 거리 계산
    d = dist(x, t.vector)
    if d < current_best:
        current_best = d
        nearest = t
    
    try++
    #지정한 횟수만큼 우선순위 노드를 백트랙킹으로 탐색 후에는 종류
    if try > try_allowed:
        탐색 종료
    #거쳐온 노드에 대해 최근접 가능성 여부 확인
    while s != null:
        t1, other_side = s.pop()
        #입력 벡터 x와 거쳐온 벡터 t1의 거리 계산
        d = dist(x, t1.vector)
        
        #거쳐왔던 벡터 t1이 최적이라면, 현재 최근접 거리와 벡터 변경
        if d < current_best
            current_best = d
            nearest = t1
        
        # (벡터 x의 어느 차원의 값 - t1의 어느 차원 값) < current_best
        # t1의 반대편 t_other에 보다 가까운 점이 존재할 가능성이 있음.
        if (x, t1.vector)의 분할 평면까지 거리 < current_best:
            t_other = t1의 other_side 자식 노드
            search_kdtree(t_other, x)

 

 

300x250
728x90

아래와 같이 두 영상에 존재하는 동일한 건물의 특징점을 매칭하려면

 

두 특징점이 주어질때, 유사도나 거리 척도가 필요

 

 

http://vclab.kaist.ac.kr/cs484/hw4/index.html

 

 

 

유클리디안 거리 Euclidean Distance

 

유클리드 공간 상에서의 거리

 

위 사진에서 SIFT 기술자를 추출한다면 하나의 기술자 특징벡터는 128차원으로 이루어져 있을것임.

 

 

 

 

 

마할라노비스 거리 mahalanobis distance

 

점들의 분포 N(mu, sigma2)를 고려한 거리로

 

 

아래의 그림을 보면 분포 바깥 점이 평균과 더 가깝지만,

 

분포를 고려하면 멀리 위치한 분포 안의 점이 더 가까운것으로 판단함.

 

 

 

 

 

단순 매칭 전략 - 고정 임계값 사용

 

가장 단순한 매칭 방법은 고정 임계값 T을 사용하는 것으로

 

두 특징 벡터의 거리가 임계값보다 작은 경우 동일한 매칭 쌍으로 판단.

 

문제는 T가 너무 작은 경우 너무 적은 매칭 쌍만 생성됨. -> 매칭 쌍이지만 놓치는 경우 FN가 많이 발생

 

 

 

 

 

최근접 이웃 매칭 전략

 

주어진 특징 벡터와 가장 가까운 특징 벡터를 찾아 임계치보다 작으면 대응 쌍으로 판단.

 

1번 영상의 i번째 특징 벡터를 a_i,

 

2번 영상의 j번째 특징 벡터를 b_j라 할때

 

a_i와 가장 가까운 b_j를 탐색

 

d(a_i, b_j) < T인경우 매칭쌍

 

 

 

 

 

최근접 거리 비율 매칭

 

가장 가까운 특징벡터와의 거리와

 

두번째로 가장 가까운 특징벡터의 거리 비율이 임계치보다 작은 경우 매칭쌍으로 판단.

 

 

a_i와 가장 가까운 특징 벡터 b_j

 

두번째로 가까운 특징 벡터 b_k가 있을때

 

d(a_i, b_j)/d(a_i, b_k) < T 인 경우 대응쌍으로 판단

 

가장 좋은 성능을 보임

 

 

 

 

 

 

300x250
728x90

컴퓨터 비전 정리를 중간?

 

공부할 내용들 중 실제로 1/3정도 쯤 온것 같기도 한데

 

집에서 혼자서 해서 그런가 참 하기가 싫다.

 

 

 

중간 중간에 쉬었다가 하다가 그렇게 나마 반복하고있는데

 

점점 하기싫어 지는 기분이 커지더라

 

 

 

분명 처음 이 내용을 공부할때보다는 이해되는 부분은 많았다.

 

오츠 알고리즘 때부터 최적화 기법으로 가장 좋은 이진화 임계치를 찾는다고 하였는데,

 

통계/대학 수학/공업 수학 공부를 하면서 클래스간 분산이 최대가 되도록 하는 임계치를 찾는 다는 말이 이해가 되더라

 

 

 

 

이후 내용도 특징 벡터, 기술자라는 용어들이 햇갈렷엇다

 

키포인트나 기술자나 같은게 아닌가. 싶엇는데

 

키포인트가 주어지면 이미지 패치로 구한 키포인트와 주변 픽셀에 의한 성질이 키포인트고

 

그래프에 대한 내용도 어느정도 이해되기 시작했다.

 

 

 

 

내가 이전에 이 공부를 여러번 할때마다 힘들었던건

 

자료구조, 알고리즘, 선형대수, 확률 통계론, 공업 수학 등에 대한

 

터미놀로지, 개념들에 대한 이해, 빈 틈이 너무 많았기 때문이었던것 같았다.

 

 

 

 

당장 당장 모르는 개념들 간단히 필요할때마다 보면 잠깐 찾아보면 되겠지 싶었으나

 

그 개념이 나오기 까지의 배경에 대한 일들이 전혀 모르니

 

개념에 대한 정의만 알아서는 뭘 할수가 없었다.

 

 

 

이걸 가장 크게 느낀 개념이 최대 우도법인데

 

이전에 본 서적에서는 최대 우도법이라는 표현을 쓰고있어서 

 

우도 함수를 최대화하는 모수를 찾는 방법 이라는 단순 설명 만으로는 이해하기 힘들었었다.

 

 

 

그런데 확률, 통계론을 공부하는 과정에서

 

우도를 가능도라는 이름으로 바꿔서 보고, 모수란 무엇인지

 

확률 분포와 모수의 관계, 빈도론자와 베이지안 관점, 함수의 다변수 미분 그라디언트 등에 대해서 이해하고 나서야

 

최대 가능도 방법에 대해 완전히 받아들일수 있게 되었다.

 

 

 

이게 컴퓨터 비전을 처음 공부하기 시작한지

 

2년이 지나서야 가능했다.

 

 

 

지금 이 내용들이 이해가 가면서 다른 문제가 생겼는데

 

그 동안 시행착오를 하면서 지친것인지,

 

급한 마음이 없어져선지

 

열심히 하고싶은 마음이 사라졌고

 

 

 

 

 

내가 왜 이걸 하는지 의문이 들더라

 

학교 다닐때는 어쩔수 없이 공부 해야만 했기 때문에 열심히라도 했었는데

 

지금은 이 비전 분야를 공부해 나가고싶어서 공부하지만 이전 처럼은 열심히가 되질 않는다.

 

 

 

 

컴퓨터 비전에서 하고싶은게 무엇인가

 

내가 우선 컴퓨터 비전 분야에서 하고싶은것들은 다음과 같은 것들이 있겠다.

 

이미지 매칭

 

영상 분할

 

물체 인식

 

 

 

 

이미지 매칭에 필요한 특징들과 기술자들을 살펴봤고,

 

영상 분할의 경우 전통적인 방법과 기본적인 그래프를 이용한 방법을 살펴봤다.

 

물체 인식의 경우 이전에 단순 분류 cnn가지고 만들어보는 수준이었지 세부적인 분류나 다중 물체인식을 어떻게 하는지

 

논문 찾아가면서 삽질하다가  포기 했었다.

 

 

 

지금이라면 이해할수 있을것 같긴한데

 

너무 글만쓰는것 같기도 하고

 

300x250
728x90

이전 글에서는

 

이진 기술자들이 사용되는 이유와 특징 벡터를 추출하는 방법, 몇가지 경우의 조사 쌍들을 살펴봄

 

이번에는 대표적인 이진 기술자들인 BRIEF, ORB, BRISK를 살펴보자

 

 

https://github.com/deepanshut041/feature-detection

 

 

 

BRIEF Binary Robust Indepent Elementary Features

ref : medium.com/data-breach/introduction-to-brief-binary-robust-independent-elementary-features-436f4a31a0e6

BRIEF는 2010년 calonder가 소개한 이진 기술자로

 

두 점을 가우시안 분포로 생성하여, 비교 쌍 256개를 만듦 -> 크기가 256비트

 

고정된 크기의 가우시안 분포에서 비교쌍을 생성하므로 스케일, 회전 변환 대처 불가

 

 

 

 

 

ORB Oriented FAST and Rotated BRIEF

ref : medium.com/data-breach/introduction-to-orb-oriented-fast-and-rotated-brief-4220e8ec40cf

 

2011년 OpenCV 연구소의 Rublee가 소개한 고속 특징 검출기로

 

FAST 키포인트 검출기와 수정 BRIEF 기술자를 기반으로 만들어진 알고리즘.

 

키포인트 주방향으로 회전시킨 BRIEF 기술자를 사용하여 회전 변환에도 불변함. 크기는 512비트

 

 

BRISK: Binary Robust Invariant Scalable Keypoints

ref : gilscvblog.com/2013/11/08/a-tutorial-on-binary-descriptors-part-4-the-brisk-descriptor/

 

2011년 Leutenegger가 소개한 회전, 스케일 변화에도 강인한 이진 특징 기술자.

 

특징점 주위 60개 점을 비교 쌍으로 사용하는데,

 

특징 스케일에 따른 거리 조건을 만족하는 쌍만 선정하여 스케일에 강인해짐

 

+ 특징점 방향에 따라 회전한 60개 점을 사용해 회전 불변

 

크기는 512비트

 

300x250
728x90

이진 기술자 binary descriptor의 필요성

 

이전에 살펴본 SIFT, PCA-SIFT, GLOH 특징 벡터(특징 기술자)들은

 

각각 128, 20, 128차원으로 여전히 매칭, 물체 추적을 수행하기에는 차원수가 너무 크고

 

SIFT 키포인트의 특징 벡터를 실수로 표현하는 경우 4바이트(float) x 128(개) = 512바이트가 필요.

 

기존 키포인트로 매칭하기에는 키포인트 간 거리 계산시 계산량이 너무 많아짐.

 

 

 

 

 

이진 기술자와 조사 패턴

 

2012 Heinly는 특징점 중심으로 조사 패턴을 이용해 이진열을 만드는 방법을 제안함.

 

특징점 주위 존재 하는 두 화소를 비교할 쌍으로 보고, 명암값을 비교해 이진 값을 생성

 

특징점 주위 수백 개의 쌍을 검사 -> 수백 비트의 이진열 binary string 생성

 

* 아래 그림은 세 비교쌍으로 이진열을 생성하는 과정을 보임

https://www.researchgate.net/publication/281590321_An_improved_MOBIL_descriptor_for_markerless_augmented_reality/figures?lo=1

 

 

 

 

 

 

이진 특징 기술자를 구하는 방법

ref :medium.com/@ulasmezin/brief-descriptor-binary-robust-independent-elementary-features-493d89ea656d

 

위에서 설명한 이진 열은 이진 특징 기술자라고 할수 있으며 0, 1의 값을 갖는 이진 수로 이루어짐.

 

이진 특징 기술자들은 크기가 128, 256, 512 등이 될수 있으며

 

SIFT가 512바이트 크기를 차지했던것과 비교해,

 

128개로 이루어진 이진 특징 기술자는 128비트 정도만 공간을 차지함.

 

구하는 방법은 키포인트 중심으로 S x S 사이즈의 이미지 패치(조사 패턴)을 놓고

 

조사 패턴에 연결된 쌍끼리 값을 비교하여 구하면 되겠다.

 

 

아래의 이진 검사 방법을 보면 p(x)와 p(y)를 비교하는데, 각각 조사 패턴으로 연결된 점 x와 점 y의 강도를 말한다.

 

점 y의 명암 값이 크다면 조사 결과는 1이되고, x값이 크다면 조사 결과는 0이 된다.

 

이미지 패치 p에 비교 쌍(조사 쌍)의 갯수만큼이 이진 특징 백터의 크기가 되겠다.

 

 

 

 

 

 

 

 

조사 쌍들의 예시

 

이진 특징 기술자를 얻으려면 키포인트 주위를 검사할 조사 쌍이 필요한데,

 

아래 그림들 다양한 옵션을 주면서 만든 조사쌍들이며, 특정 확률 분포와 관련이 있음

 

 

G I는 점 X와 점 Y 각각을 균일하게 선정하여 연결시킨 경우

 

G II는 점 X, Y를 가우시안 분포에 따라 임의로 선정하여 연결.

 

G III에서는 X와 Y의 쌍이 가우시안 분포를 따르도록 선택 되었는데.

 

    여기서 x는 0.04 * sigma2를 표준편차로 하는 x를 선정하고,

   

    점 y는 점 x의 평균과 표준편차 0.01 *sigma2에 있는것을 선정

 

G IV는 원형 그리드 내부에 존재하는 점 X와 점 Y를 임의로 선택하여 조사쌍 들을 생성

 

 

 

 

300x250
728x90

PCA-SIFT

 

대부분 동일하나 특징 벡터 x를 추출하는 과정이 다름.

 

키포인트 중심으로 옥타브 o, sigma_o 영상에서 주 방향으로 39 x 39 윈도우 적용

 

윈도우 내부 d_y, d_x 영상 취득

 

=> 39 x 39 x 2 = 3,042차원 벡터 취득

 

이 고차원 벡터를 d = 20차원으로 축소 하여 특징 벡터 x로 사용.

 

 

 

 

 

SIFT와 PCA-SIFT의 비교

 

키포인트를 중심으로

 

기본 SIFT : 주 방향으로 4 x 4 윈도우, 8방향 그라디언트 히스토그램으로 4 x 4 x 8 = 128차원

 

PCA-SIFT : 주 방향 39 x 39 윈도우, dy, dx영상으로 39 x 39 x 2 = 3,042차원 + PCA 수행하여 d=20차원으로 축소

 

2004 ke에 따르면 PCA-SIFT는 SIFT에 근접한 반복력을 가지며, 보다 고속 매칭이 가능(128 -> 20차원)

 

 

 

 

 

 

GLOH Gradient Loation Orientation Histogram

 

SIFT, PCA-SIFT와 같은 특징은 정사각형 윈도우로부터 키포인트 기술자를 검출해냄.

 

GLOH은 정사각형 대신 원형 윈도우 사용

 

옥타브 o의 sigma_o 영상의 키포인트를 중심으로

 

우측 아래와 같은 3원으로 17개 영역으로 분할. 각 영역은 16단계 그라디언트 방향 히스토그램 계산

 

=> 17 x 16 = 272차원 특징백터 + PCA로 128차원으로 축소

 

128차원 특징벡터 x를 취득

 

 

https://www.researchgate.net/publication/319140954_Evaluation_of_Local_Feature_Detectors_and_Descriptors_for_Look_Angle_Varied_Terra-SAR_X_Band_Images/figures?lo=1&utm_source=google&utm_medium=organic

 

 

300x250
728x90

SIFT 특징

 

키포인트라 부르며, 위치와 스케일 정보를 가짐 (y, x, sigma)

 

-> sigma를 이용하여 크기 변환에 대응 가능

 

기술자 추출을 위한 윈도우 크기를 sigma에 따라 조절하거나, 스무딩이 필요

 

 

 

SIFT 기술자 추출 위치

 

SIFT 특징은 피라미드 구조

 

키포인트가 옥타브 1의 3번째 영상(sigma=2.5398)에서 검출된 경우.

 

옥타브 o = 1, sigma_o = 2.5398로

 

SIFT 기술자는 o번 옥타브, sigma_o 영상에서 기술자 추출

 

 

 

 

회전 변환애 대응하기 위한 주 방향 탐색

 

이미지 회전에 대응하기 위해 윈도우 방향 조절이 필요.

 

-> SIFT 기술자 추출전 주 방향 dominant orientation을 탐색

 

1. 키 포포인트를 중심으로 일정 크기 윈도우를 씌움

 

2. 윈도우 내 화소 집합으로 그라디언트 방향 히스토그램 취득

* 그라디언트 방향은 10도 간격으로 양자화, 36개 구간을 가진 히스토그램

 

3. 그라디언트 방향 히스토그램 계산시 그라디언트 크기를 가중치로 사용하며,

 

가우시안을 씌워 멀어질수록 적은 가중치 방영되도록 함.

 

* 아래 그림은 그라디언트 방향 히스토그램 계산을 위해 가우시안 블러링된 이미지에 방향 강도를 나타낸 영상

https://aishack.in/tutorials/sift-scale-invariant-feature-transform-keypoint-orientation/

 

 

 

4. 히스토그램에서 가장 큰 값을 가진 방향을 주 방향으로 사용.

* 최고 값의 0.8배 이상인 방향이 존재할 경우 해당 방향도 주방향으로 판단하여 새 키포인트 생성.

 => 위치는 같지만 방향이 다른 여러 키포인트가 생성 될 수 있음.

* 키포인트 정보 : 위치, 스케일, 주 방향 (y, x, sigma, theta)를 가짐.

 

* 아래는 위 이미지에 대해 주방향 취득을 위한 그라디언트 히스토그램

https://aishack.in/tutorials/sift-scale-invariant-feature-transform-keypoint-orientation/

 

 

 

 

주방향을 이용한 SIFT 기술자 추출

 

키포인트에 적절한 크기의 회전된 4 x 4윈도우를 씌움.

 

이때 윈도우는 주방향 theta가 기준되도록 회전

 

 

해당 키포인트의 그라디언트 방향을 계산 후,

 

8단계로 양자화 된 그래디언트 방향 히스토그램을 구함 

 

주방향 탐색때 처럼 회전된 윈도우 내부의 그라디언트 크기를 가중치로, 가우시안 블러링을 적용함.

 

하나의 키포인트 기술자는 4 x 4 x 8 = 128차원의 특징벡터 x로 추출됨

 

 

 

 

 

 

광도에 불변한 SIFT 기술자

 

1. 키포인트 기술자 특징 벡터 x를 벡터의 크기(노름)로 ||x||로 나누어 단위 벡터로 변환

 

2. 단위 벡터에 0.2보다 큰 요소가 존재시(상한 0.2), 0.2로 변경 후 다시 단위 벡터로 변환

 

=> 스케일, 회전, 광도 불변한 128차원 키포인트, 특징벡터 x 완성

 

 

 

 

 

위 과정을 거쳐 구한 SIFT 특징은

 

(y, x, sigma, theta, v_x)로 정리할수 있으며,

 

이 키포인트 특징 집합이 매칭 연산의 입력으로 사용되어, 두 영상 사이 매칭 쌍을 찾는데 사용

 

 

 

 

 

opencv에서 SIFT

 

sift = cv.SIFT_create()
kp, des = sift.detectAndCompute(gray,None)

sift 객체를 생성 후

 

sift.detectAndCompute(명암 영상,None)으로

 

키포인트들과 키포인트의 기술자들을 반환 반음.

 

키포인트 기술자들은 num of keypoints x 128 차원의 형태로 반환됨

 

docs.opencv.org/master/da/df5/tutorial_py_sift_intro.html

 

 

300x250
728x90

특징 기술자 feature descriptor의 조건

 

특징을 매칭, 인식 등에 사용하기 위해선

 

다음 조건 충족이 필요

 

1. 기술자 분별력이 커야 함.

 

완전히 서로 다른 두 영상이 주어질 때, 각 영상에서 구한 기술자들은 달라야 함

 

완전히 다른 두 영상 끼리는 매칭 될 수 없으므로.

 

 

2. 여러 변환에 불변해야함

 

평행 이동, 회전, 크기, 스케일, 비틀림 변환 등에도

 

특징 기술자가 변하지 않아야 매칭을 할 수 있음

 

 

3. 추가적으로 특징 기술자는

 

위와 같은 기하 불변성 geometry invariant 뿐만 하니라 광도 불변성 photometric invariant을 가져야 함.

 

 

4. 특징 기술자의 크기(차원)이 작을수록 좋음.

 

매칭은 기술자 간 거리로 판단하므로, 차원이 클수록 계산량이 많아짐

 

 

 

 

 

 

 

 

앞서 살펴본 관심점들

 

모라벡, 해리스 코너 알고리즘은 (y, x)

 

해리스 라플라스, SIFT, SURF 등의 특징은 (y, x, sigma)로 표현

 

 

 

 

 

 

 

특징, 관심점으로부터 기술자 추출하기

 

해당 특징점을 중심으로 윈도우를 씌우고, 보아야 함.

 

-> 윈도우 모양, 크기, 살펴볼 주제를 선택하여야 함.

 

카메라가 이동하여 찍은 영상의 경우 -> 쉽게 매칭 성공

 

영상이 이동 + 회전 변환이 수행된 경우 -> 크기, 회전 변환에 불변한 기술자 사용해야함

 

영상에 조명변화나 가림이 생기는 경우 -> 기하, 광도 변환에 불변한 기술자 사용 필요

 

 

 

 

 

 

 

 

 

 

300x250

+ Recent posts