Python과 OpenCV – 37 : ORB (Oriented FAST and Rotated BRIEF)을 이용한 이미지의 특징점 추출

이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_orb/py_orb.html 입니다.

ORB는 다른 특징점 추출 알고리즘과는 다르게 OpenCV 연구소에서 개발되었습니다. 특허권이 걸린 SIFT와 SURF를 대신할 수 있는데, 계산비용과 매칭 속도가 더 좋다고 합니다. ORG는 기본적으로는 FAST의 키포인트 검출기와 BRIEF의 기술자의 혼합하면서 속도를 더 개선 시켰다고 합니다. 결과적으로 ORB는 SURF와 SIFT보다 더 빠르고 더 잘 작동합니다. ORB는 저전력의 단말기에서도 잘작동하며 파노라마 이미지 생성을 위한 이미지 붙이기 등의 기능에 적합하다고 합니다.

OpenCV에서 ORB에 대한 예제 코드는 아래와 같습니다.

import numpy as np
import cv2

filename = './data/butterfly.jpg'
img = cv2.imread(filename, cv2.COLOR_BGR2GRAY)
img2 = None

orb = cv2.ORB_create()
kp, des = orb.detectAndCompute(img, None)

img2 = cv2.drawKeypoints(img, kp, None, (255,0,0), flags=0)
cv2.imshow('img2', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

위 코드에 대한 실행 결과는 다음과 같습니다.

Python과 OpenCV – 36 : BRIEF (Binary Robust Independent Elementary Features)을 이용한 이미지의 특징점 추출

이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_brief/py_brief.html 입니다.

지금까지 살펴본 SIFT나 SURF 등은 이미지의 특징점을 검출하기 위해 제법 많은 메모리를 사용하는데, 자원에 제약이 심한 임베디드 장비에서는 메모리를 적게 사용하는 특징점 검출 방법이 필요하며, 그 방법이 바로 BRIEF입니다.

BRIEF는 특징점에 대한 기술자(Descriptor)일 뿐, 특징점을 검출하는 방법은 제공하지 않는데.. 이를 위해 다른 특징점을 검출하는 SIFT나 SURF 등을 사용해야 합니다. BRIEF에 대해 설명하는 논문에서는 CenSurE를 추천하고 있습니다. OpenCV에서는 이를 STAR라고도 합니다. 여튼 CenSurE는 빠르며 다른 방법보다 BRIEF에 더 최적화되어 있다고 합니다.

OpenCV에서 제공하는 BRIEF의 예제를 살펴보면 다음과 같습니다.

import numpy as np
import cv2
from matplotlib import pyplot as plt

filename = './data/butterfly.jpg'
img = cv2.imread(filename, 0)

star = cv2.xfeatures2d.StarDetector_create()
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()

kp = star.detect(img,None)
kp, des = brief.compute(img, kp)

img2 = cv2.drawKeypoints(img, kp, None, (255,0,0))
cv2.imshow('img2', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

8번은 STAR 특징점 검출을 위한 객체를 생성합니다. 이렇게 생성된 STAR 검출기를 통해 특징점을 검출하고, 이 특징점을 이용해 9번 코드에서 생성한 BRIEF 객체를 통해 특징점의 기술자(Descriptor)를 계산하는 것입니다. 실행 결과는 다음과 같습니다.

Python과 OpenCV – 35 : FAST(Features from Accelerated Segment Test)을 이용한 이미지의 특징점 추출

이 글의 원문은 https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_fast/py_fast.html 입니다.

이미지에서 특징점을 추출해 내는 다양한 방법이 있지만, 그 속도면에서 아쉬움이 있었고 정확도를 희생하는 대신 빠른 속도로 특징점을 추출하는 방법으로 2006년에 FAST가 처음 제안되었습니다. 이 방법은 인공지능의 기계학습에서도 활용된다고 합니다. 이 방법은 특정 화소 인근의 화소값을 16개 뽑고 특정 화소의 화소값이 인근의 16개의 화소값에 임계치값(t)을 더한 값보다 크거나 임계치값을 뺀 값보다 작은 인근화소의 개수에 따라 특징점인지를 결정하는 매우 단순한 방식입니다. 여기에 더욱 속도를 향상시키기 위해 16개의 인근화소가 아닌 4개의 인근화소를 활용한다거나, 특징점이 비슷한 부분에서 너무 많이 추출되는 것을 방지하기 위해 억제(Non-maximal Suppression)하는 등이 절차가 적용되기도 합니다. 다른 방식에 비해 특징점 추출의 정확도를 떨어지지만 실시간에서 활용할 수 있는 속도를 제공하면서 어느 정도의 특징점 추출 방법으로 사용된다고 합니다.

OpneCV에서 이 FAST 특징점 추출에 대한 API 예제는 다음과 같습니다.

import numpy as np
import cv2
from matplotlib import pyplot as plt

filename = './data/butterfly.jpg'
img = cv2.imread(filename,0)

fast = cv2.FastFeatureDetector_create()

kp = fast.detect(img,None)
img2=cv2.drawKeypoints(img,kp,None)

print("Threshold: ", fast.getThreshold())
print("nonmaxSuppression: ", fast.getNonmaxSuppression())
print("neighborhood: ", fast.getType())
print("Total Keypoints with nonmaxSuppression: ", len(kp))

cv2.imshow('img2', img2)

cv2.waitKey()
cv2.destroyAllWindows()

실행결과는 아래와 같습니다.

콘솔에 출력된 결과는 아래와 같은데요.

Threshold:  10
nonmaxSuppression:  True
neighborhood:  2
Total Keypoints with nonmaxSuppression:  4992


인근 픽셀 화소값 비교를 위한 임계치 기본값은 10이고 비슷한 지점에서 너무 많은 특징점이 추출되는 것을 방지하기 위한 nonmaxSuppression가 True로 지정되어 있습니다. 시각적으로 이러한 특징점을 줄이기 위해 임계값을 변경하는 예제는 다음과 같습니다.

import numpy as np
import cv2
from matplotlib import pyplot as plt

filename = './data/butterfly.jpg'
img = cv2.imread(filename,0)

fast = cv2.FastFeatureDetector_create()

fast.setThreshold(150)
#fast.setNonmaxSuppression(False)

kp = fast.detect(img,None)
img2=cv2.drawKeypoints(img,kp,None)

print("Threshold: ", fast.getThreshold())
print("nonmaxSuppression: ", fast.getNonmaxSuppression())
print("neighborhood: ", fast.getType())
print("Total Keypoints with nonmaxSuppression: ", len(kp))

cv2.imshow('img2', img2)

kp = fast.detect(img,None)

cv2.waitKey()
cv2.destroyAllWindows()

결과는 다음과 같습니다.

Python과 OpenCV – 34 : SURF(Speeded-Up Robust Feature)을 이용한 이미지의 특징점 추출

이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_surf_intro/py_surf_intro.html 입니다.

SURF는 SIFT의 수행 속도를 개선시킨 것으로, 분석에 따르면 대략 3배 정도 빠르다고 합니다.SURF는 이미지가 회전되거나 Blurring 처리가 되었을 때에 사용해도 잘 잘동하지만 밝기가 변경되거나 시점이 변경이 되면 적당하지 않습니다.

OpenCV에서 제공하는 SURF와 관련된 함수를 살펴보겠습니다.

import cv2
import numpy as np

filename = './data/butterfly.jpg'
img = cv2.imread(filename)
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

surf = cv2.xfeatures2d.SURF_create(50000)

kp, des = surf.detectAndCompute(gray, None)

print(len(kp))

img2 = cv2.drawKeypoints(gray,kp,None,(0,0,255),4)

cv2.imshow('img2', img2)
cv2.waitKey()
cv2.destroyAllWindows()

위의 코드에서 이미지의 특징점을 추출하기 위한 SURF 기능을 사용하기 위해 8번 코드에서 SURF 객체를 생성합니다. 생성시 받는 인자는 Hessian 임계값으로 이 값이 작을수록 더 많은 특징점이 추출됩니다. 위 예제에서는 추출될 특징점 개수를 줄이기 위해 50000을 지정했으나 실제에서는 300-500 사이의 값을 지정합니다. 12번 코드에서 추출한 특징점의 개수를 출력하고 특징점을 이미지에 그리기 위해 14번 코드가 실행되었습니다. 결과는 다음과 같습니다.

위의 결과를 보면 특징점의 방향도 같이 표시되고 있는데, 방향이 필요없을 경우 속도 향상을 위해 방향 계산은 하지 않도록 할 수 있으며 아래 예제와 같습니다.

import cv2
import numpy as np

filename = './data/butterfly.jpg'
img = cv2.imread(filename)
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

surf = cv2.xfeatures2d.SURF_create(50000)

surf.setUpright(True)
kp, des = surf.detectAndCompute(gray, None)

print(len(kp))

img2 = cv2.drawKeypoints(gray,kp,None,(0,0,255),4)

cv2.imshow('img2', img2)
cv2.waitKey()
cv2.destroyAllWindows()

10번 코드를 통해 방향은 항상 위쪽 방향으로 간주하라고 지정합니다. 결과는 아래와 같습니다.

국가지점번호

우리나라의 특정 위치를 나타낼 수 있는 지점번호 체계에 대한 내용입니다. GIS 관련 사업 시에 국가지점번호를 지도에 표현할 때 도움이 되는 자료입니다. 먼저 국가지점 번호에 대한 직관적인 이해를 돕는 그림은 아래와 같습니다.

위의 그림은 일단 전국을 100km 단위의 격자로 나누되, 그 기준점은 별표 표시가 된 (700000, 1300000)입니다. 좌표계는 GRS80 타원체의 UTM-K입니다. 위 그림은 제가 작성한게 아닌데, 어디서 받았는지 기억이 나질 않습니다. 제공해주신 기관(?) 또는 개인에게 감사드립니다.

격자의 간격은 위처럼 100km로 시작하고, 좀더 자세한 위치를 표현하기 위해 아래처럼 10m 단위 간격의 격자로 구성됩니다. 각 격자에 대한 격자번호의 정의는 아래의 그림을 통해 파악할 수 있습니다.

이처럼 국가지점번호는 그 정의가 매우 명확합니다. 해서 국가지점번호를 나타내는 도형일 미리 생성하지 않고도 실시간으로 생성하여 논리적인 개념으로 지도 상에 표현할 수 있습니다.