[OpenCV] 05-5. Introduction to SURF (Speeded-Up Robust Features)
🐍Python/OpenCV

[OpenCV] 05-5. Introduction to SURF (Speeded-Up Robust Features)

728x90
반응형

< Introduction to SURF (Speeded-Up Robust Features) >

이번 장에서는,

  • SURF의 기본
  • OpenCV에서 SURF의 기능

위의 것들에 대해서 알아볼 것이다.

Theory

이전 장에서, 키포인트 검출과 디스크립션을 위한 SIFT를 봤다. 하지만 이는 상대적으로 느리기에 사람들은 더 빠른 버전을 필요로한다. SURF는 speeded-up version of SIFT이다.

SIFT에서는, scale-space를 찾기 위해 Lowe는 가우시안의 차이로 가우시안의 라플라시안(LoG)을 근사했다. 하지만 SURF는 조금 더 가서 박스 필터로 LoG를 근사하는 방법을 취한다. 아래의 이미지는 이러한 근사의 과정을 보여준다. 이 근사의 가장 큰 장점으로, 박스 필터로 컨볼루션하는 것이 전체 이미지에서의 연산을 쉽게 한다. 그리고 이는 다른 크기에 대해서 유사하게 작동한다. 또한 SURF는 규모와 위치 모두에 대해 헤시안 행렬의 행렬식(determinant)에 의존한다.


방향 지정의 경우, SURF는 크기6s인 인근에 대해 수평 및 수직 방향의 wavelet* 반응을 사용한다.

wavelet : 웨이블릿(wavelet)이란 0을 중심으로 증가와 감소를 반복하는 진폭을 수반한 파동 같은 진동을 말한다. 그것은 지진계나 심박 체크에 기록되어 보이는 것과 같은 전형적인 “짧은 진동”의 형태로 나타난다. 일반적으로 웨이블릿은신호 처리에 유용한 특정한 성질을 가지도록 하는 목적을 가지고 만들어진다. 웨이블릿은 합성곱(convolution) 기술을 통해 알고 있는 신호와 결합하여, 알려지지 않은 신호로부터 정보를 추출하는데에 사용될 수 있다.
(출처 - 위키백과)

적당한 가우시안 가중치가 적용되기도 한다. 그런 다음 아래의 이미지처럼 공간에 표시된다. 주요 방향은 60도 각의 방향 윈도우를 슬라이딩하면서 얻은 반응들의 합을 계산함으로 추측된다. 흥미로운 것은, wavelet 반응은 전체 이미지를 사용하여 어떤 크기이던 쉽게 찾아질 수 있다. 많은 경우, 방향 불변성(방향과 무관)이 요구되지 않기 때문에, 이 방향을 찾을 일이 없어서 과정의 속도를 높이게 되는 것이다. SURF는 Upright-SURF 또는 U-SURF라는 기능을 제공한다. 이는 속도를 증가시키고 ±15o까지 강건하다. OpenCV는 upright 플래그에 의존하여 두 가지를 모두 지원한다. 만약에 플래그가 0일 경우, 방향은 계산이 된다. 만약 플래그가 1일 경우. 방향은 계산되지 않고 속도는 더 빨라진다.


feature description을 위해, SURF는 수평 및 수직 방향으로의 wavelet 반응을 사용한다. (다시 말하지만, 전체 이미지를 쓰는 것이 더 쉽다) 20sX20s 크기의 인접부는 s가 크기인 키포인트를 중심으로 한다. 이는 4X4 하위지역으로 나뉜다. 각 하위지역에 대해, 수평 및 수직의 wavelet 반응은 다음과 같은 벡터형태로 나타낸다.
v=(dx,dy,|dx|,|dy|)
이는 벡터로 표현될 때, 64차원의 SURF feature descriptor를 제공한다. 차원이 더 낮을수록, 연산과 매칭의 속도가 높지만, 특성의 변별성은 더 좋아진다.

더 많은 변별성에 대해, SURF feature descriptor는 128 차원으로 확장된다. dx |dx|의 합은 각각 dy<0일 때와, dy0일 때의 경우에 대해서 계산된다. 비슷하게, dy |dy|의 합은 dx의 부호에 따라 나뉜다. 따라서 특성의 수가 두 배가 되는 것이다. 이는 계산복잡도를 많이 더하진 않는다. OpenCV에서는 플래그에 0을 보내면 64차원이고, 1을 보내면 128차원이다(디폴트값은 128차원)

또 다른 중요한 개선 사항으로는 근본적인 관심있는 지점에 대해 라플라시안의 부호를 사용한다는 것이다. 이는 탐지 과정에서 이미 연산되었기에 연산비용이 추가로 들지 않는다. 라플라시안의 부호는 어두운 배경에서의 밝은 blob과 그 반대의 상황을 구분한다. 매칭 단계에서는, 그들이 같은 타입의 유형일 경우에만 비교한다.(아래 그림 참조) 이 최소한의 정보는 descriptor의 성능 저하 없이 매칭을 빠르게 해준다.


요약하자면, SURF는 속도 증진을 위해 매 단계에서 수 많은 특성을 추가한다. 분석으로는 SIFT 보다 3배 빠르고 성능은 비슷하다는 것을 알 수 있다. SURF는 블러링이나 회전된 이미지에 대해 다루기 쉽지만, 관점의 변화나 조명 변화에 대해서 잘 다루지 못한다.

SURF in OpenCV

OpenCV 3.x 버전에서는 SIFT, SURF, ORB를 더 이상 제공하지 않는다.. 추가적으로 contrib 버전을 받아야한다.

!pip install opencv-contrib-python

으로 설치를 해주자.

64/128 차원의 descriptors, Upright/Normal SURF등과 같은 일부 선택적 조건으로 SURF 객체를 시작한다. 모든 세부 사항은 문서에 잘 설명되어 있다. 그런 다음
SIFT에서 했던 것 처럼 키포인트와 descriptor를 찾기 위해, cv2.xfeatures2d.SURF_create()를 사용한다.

먼저 키포인트와 descriptor를 찾아 간단한 데모를 볼 것이다.

# 오리지날
def SURF():
    img = cv2.imread('./images/flower.jpg')
    imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    img2, img3 = None, None
    surf = cv2.xfeatures2d.SURF_create()
    surf.setHessianThreshold(50000)

    kp, des = surf.detectAndCompute(img,None)
    img2 = cv2.drawKeypoints(imgray,kp,img2,(255,0,0),4)

    cv2.imshow("image",img2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

SURF()


Threshold를 10000으로 낮췄을 때, 더 많은 특성들을 검출한다. (임계가 높을 수록 걸러짐)


surf.setUpright(True)

이를 추가하면 방향을 고려하지 않은 결과를 내뱉는다. (Threshold=50000)


surf.setExtended(True)

이를 추가하면 디스크립터의 차원을 64에서 128차원의 크기의 벡터로 설정할 수 있다.


728x90
반응형