너무너무 중요한 특징점 추출 알고리즘이다.
목적: Scaling과 Rotation에 불변하는 Point feature 를 추출하기 위함.
Point feature 란?:
이미지 상에서 두드러지는 지점을 말한다.
왜 중요한가?: 다른 viewpoint에서 찍힌 두 사진에서 point feature를 사용하여 대응점을 비교하기 위해.
==> 3D reconstruction의 기본이되는 근본 알고리즘이다.
Point feature가 되기 위한 자격:
1) perspective과 illumination에 대해 불변해야한다.
2) 같은 점은, pose와 viewpoint에 상관없이 유사한 vector로 이루어져야한다.
여기 아인슈타인 형님이 계신다.

우리의 목표는 scale invariant한 특징점을 추출하는데 있기때문에, 이렇게 한번 생각해 볼 수 있을거다.
이미지에 Blur를 점점더 세게 줄수록, 결국에는 멀리있는 물체를 보는 것과 같은 효과가 아닐까? 라는 망상..
를 증가시킬수록 더욱 더 뿌옇게 사진이 흐려진다. 위 그림에서 오른쪽으로 갈수록 가 증가중이다.

여기서 끝나면 서운하다.
를 증가시키고, 적당히 증가시켰다면, 이미지의 스케일을 줄이고 또 를 증가시키고,
또 스케일을 줄이고, 를 증가시켜 총 20장의 사진을 확보한다.

위에서 얻었던 사진들을 쭉 나열해놓고, 각 이미지간의 차이를 오른쪽에 쌓는다.
그림에서 보면, 노랑색 정사각형들의 차를 통해 청록색 정사각형들이 새롭게 쌓이고 있다.
이 청록색 부분이 Difference of Gaussian (DOG)이다.

이렇게 해서 얻은 차를 보면, 위 와 같다.
분명히 한 턴에 5장의 아인슈타인 형님들이 계셨는데 왜 4개씩밖에 없는지는, 위 과정을 이해했다면 알것이다.
쌓아둔 DOG이미지에서, 극값을 찾아주면된다.

위에서 쌓아둔 DOG를 보면서 극값을 찾을건데, 위 그림의 오른쪽 부분처럼, X자로 쳐져있는 i번째 픽셀의 위, 아래, 양옆의 26칸을 확인하면서, i번째 픽셀이 26칸의 값들보다 크거나 작다면 극값으로 친다.
여기서 추가적으로 설정된 threshold보다 큰 픽셀이 골라지면 Bad point로 임명한다. (제거)
CV lecture에는 Gradient 구하는 방법이 나와있지 않아 아래 블로그를 참고하였다.

(출처: https://velog.io/@everyman123/SIFT-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0)
만드는 방법:
keypoint를 중심으로 16x16 패치를 추출한다,
위의 식에서 m(gradient magnitude)을 구하고 (orientation)를 구해서, 히스토그램을 만들어준다.
이 작업은 keypoint에 방향속성을 추가하기 위함이며, 360도의 각도를 10도단위로 쪼개어 36개의 bin을 만든다.
위와같은 히스토그램이 생기면, 여기서 80%보다 큰 방향이 있다면, 그 값 혹은 가장 큰값을 keypoint의 방향으로 정한다.
keypoint를 중심으로 16x16 픽셀크기의 윈도우를 구성하여, 이를 4x4 픽셀 16개로 쪼갠뒤,
각 4x4 픽셀의 gradient의 크기와 방향을 또 계산해준다. 이번에는 10도 단위가 아닌 45도 단위로 쪼개어 총 8개의 구간이 생긴다.

원래 16x16짜리를 4x4로 쪼개어 16개의 칸을 만들었고, 각 4x4 윈도우마다 8개의 방향을 가지는 방향정보가 계산되어 들어있다. 따라서, 이렇게 16x8=128개의 방향정보를 가지고 keypoint descriptor를 표현할 수 있다.
근데 여기까지만 하면! 이미지를 회전시킨다면 gradient값이 바뀌어, 우리가 원하는 불변성을 보존할 수 없다.
마지막으로 앞서 구했던 keypoint의 orientation을 descriptor에서 빼주어, Rotation에 대해 invariant하게 해준다
이렇게해서~
스케일과 회전에 대해 불변하는 특징점을 추출하는 SIFT를 완벽이해했다.