본문 바로가기
CODING/AI & ML & DL

[ML] BoVW : bag of visual words | Feature engineering

by 밍톨맹톨 2020. 12. 22.
728x90
728x90

[ ML 텀 프로젝트로 진행했던 2D caltech101 data 분류 정리]

BoVW [ bag of visual words ] 

 사진이나 영상 분류를 위해 영상에서 feature를 뽑아 분류하는 것

 

❗️ feature를 뽑는다는 것
  - SIFT 기법과 같은 방법을 통해 영상의 특징이 되는 부분 예를 들면 아래 왼쪽과 같은 그림에서 특징이라고 할 수 있는 코나, 입, 턱 선등을 영상에서 뽑아내는 것을 의미한다. 

 


BoVW 알고리즘 방법 

 

1️⃣ 모든 영상의 특징점 검출

2️⃣ 모든 특징점들이 Codebook 계산 ( 중요한 특징들을 뽑는 것 )

3️⃣ 모든 영상과 Codebook을 비교해서 histogram ( 빈도수 ) 계산

4️⃣ 분류기를 사용해 학습 및 예측 


SIFT 기법

영상의 특징점을 검출하는 방법 중 하나로 영상 내에서 환경 변화에 강인한 부분, 즉 엣지부분을 찾아 특징점으로 추출한다. 

영상의 크기 변화나 회전에 영향을 받지 않는다는 특징이 있어 이미지가 돌아가거나 크기가 다르더라도 동일한 물체를 찾을 수 있음 

 

but 단색의 벽이나 배경, 단순 에지의 경우 특징점을 추출하지 못하는 경우가 생김 

SIFT 알고리즘을 사용해서 특징점을 추출한 것

[ SIFT 알고리즘 | ver. Python ] ⬇️

 

SIFT 알고리즘 사용을 위해 cv2를 import 해주고

import cv2
def extract_sift_descriptors(img):
    
    # SIFT 인스턴스 생성
    sift = cv2.xfeatures2d.SIFT_create()
    # SIFT를 이용하여 특징점 위치 추출
    keypoints = sift.detect(img,None)
    # img의 type을 uint8로 변환 
    img=np.uint8(img)
    # SIFT를 이용하여 추출된 위치 주변 정보인 기술자 추출
    descriptors = sift.compute(img,keypoints)
    # SIFT 기술자 반환
    return descriptors[1]

descriptors[0] - keypoints 

descriptors [1] - descriptor 


Codebook 만들기

codebook이란 SIFT 알고리즘을 통해 뽑아낸 특징들 중 이미지를 분류하는데 있어서 중요하다고 생각되는 단어만 포함되어 있는 것을 말하는데, 이를 계산하기 위해서는 K-means cluster ( k-평균 군집 분석)를 사용한다. 

 

[ Codebook _ K-means cluster | ver. Python ] ⬇️

 

X : 영상의 이미지 

voc_size : 추출하고 싶은 군집의 개수 ( 중요한 특징의 개수 )

from sklearn.cluster import KMeans

def build_codebook(X, voc_size):

    X = X.reshape(3060*1024,128)
    
    kmeans = KMeans(n_clusters= voc_size)
    
    kmeans.fit(X)
    
    pred = kmeans.cluster_centers_
    
    return pred 

Histogram 생성하기 

영상을 분류하기 위해서 histogram을 구하게 되는데 이 histogram은 codebook에 포함된 단어가 몇 번이 나타났는지를 표현하는 것이다.

 

아래의 x축은 codebook이 되고 sift로 추출한 

[ Histogram 계산 | ver. Python ] ⬇️

import scipy.cluster.vq as vq

def BoW( descriptor, codebook):
    descriptor=descriptor.tolist()

    index = vq.vq(descriptor,codebook)

    hist, _ = np.histogram(index,bins=range(codebook.shape[0] + 1), normed=True)
    
    return hist

scipy.cluster.vq를 사용해서 모든 영상점의 특징점 ( SIFT descriptor )과 유사한 Codebook을 비교해서 Index를 받아서 np.histogram을 사용해서 histogram을 계산한다.


 

위의 과정을 거친 뒤 분류 모델을 사용해 학습하고 예측하면 된다.

 

이와 같은 handcraft feature ( 전문가에 의해 고안된 아이디어를 바탕으로 직접 설계된 특징)은 한때 영상 분류 분야에서 혁신이었지만 지금은 인공신경망 기반의 방법론들이 훨씬 더 좋은 성능을 내고 있다. 

728x90

댓글