Python/파이썬 OpenCV 공부

[OpenCV 머신러닝] OpenCV에서 k-means 알고리즘 사용하기 - cv2.kmeans

AI 꿈나무 2020. 10. 25. 22:28
반응형

 OpenCV에서 제공하는 함수를 이용하여 k-means 알고리즘을 이용하는 방법에 대해 공부해보겠습니다.

 

k-평균(k-means) 알고리즘

 k-means 알고리즘은 주어진 데이터를 k 개의 구역으로 나누는 군집화(clustering) 알고리즘입니다.

 비지도 학습이며 데이터를 무작정 입력으로 주고 임의의 기준으로 나눠주는 형태로 동작하는 알고리즘 입니다.

 

 k는 군집 갯수를 의미하여 사용자가 지정해줘야 하는 파라미터입니다.

 

k-means 알고리즘 동작 순서 

출처 : 위키피디아

 

1. 임의의 k개 중심을 선정합니다. (초기치 중심을 설정해줘야 합니다)

 랜덤하게 각 샘플의 중심이라고 간주할 위치를 임의로 선택합니다.

 초기 중심점을 어떻게 선정하냐에 따라 결과값이 달라지게 됩니다.

 

2. 모든 데이터에 대하여 가장 가까운 중심을 선택하여 이동합니다.

 중심점 간의 거리의 중간으로 영역을 분할합니다.

 초평면 안에 있는 데이터들의 평균위치를 계산하게 됩니다.

 

3. 각 군집에 대해 중심을 다시 계산합니다.

 중심을 이동하고 클래스에 해당하는 영역을 다시 선정합니다.

 

4. 중심이 변경되면 2~3 과정을 반복합니다.

 중심이 바뀌지 않을 때 까지 반복합니다.

 OpenCV 함수에서는 종료 기준을 선정할 수 있습니다.

 

5. 중심이 변경되지 않으면 종료합니다.

 

k-means 알고리즘을 이용한 컬러 영상 분할

 색상 양자화라는 용어를 쓰기도 합니다.

 영상에 존재하는 1600만 가지의 컬러값을 10개(k, 군집 개수)로 단순화할 수 있습니다.

 

 입력 영상의 각 픽셀 값을 색 공간 상의 한 점으로 표현하게 됩니다.

 ex) RGB 3차원 공간에서의 한점 or RG 2가지 정보 이용 or HS 2차원 공간에서의 한 점(V는 조명의 영향이므로 제외)

 

 색 공간에서 k-means 알고리즘을 수행하고 각 픽셀 값을 k개의 대표 색상으로 치환하게 됩니다.

 

K-mean 군집화 함수 - cv2.kmeans

cv2.kmeans(data, K, bestLabels, criteria, attempts, flags, centers=None) -> retval, bestLabels, centers

• data: 학습 데이터 행렬. numpy.ndarray. shape=(N, d), dtype=numpy.float32.

• K: 군집 개수

• bestLabels: 각 샘플의 군집 번호 행렬. numpy.ndarray. shape=(N, 1), dtype=np.int32.

• criteria: 종료 기준. (type, maxCount, epsilon) 튜플.

• attempts: 다른 초기 레이블을 이용해 반복 실행할 횟수.

• flags: 초기 중앙 설정 방법.
  cv2.KMEANS_RANDOM_CENTERS, cv2.KMEANS_PP_CENTERS, cv2.KMEANS_USE_INITIAL_LABELS 중 하나.

• centers: 군집 중심을 나타내는 행렬. np.ndarray. shape=(N, d), dtype=np.float32.

• retval: Compactness measure

 bestLabels은 None을 입력하고 결과값으로 받습니다.

 attempts는 초기 값에 따라 결과가 달라지기 때문에 여러 초기값을 반복하는 인자입니다.

 centers는 결과값으로 받습니다. 군집 중심 정보를 나타내는 행렬입니다.

 retval은 각각의 샘플에 평균을 뺀 값을 제곱한 정보입니다. 이 값이 작으면 뭉쳐져 있는 형태, 크면 퍼져있는 형태입니다.

 

k-means 알고리즘을 이용한 컬러 영상 분할 예제 코드

 컬러 영상 분할 뿐만 아니라 입력 데이터를 k개로 구분하는 용도로 kmeans 알고리즘을 이용하기도 합니다.

  

 예제 코드 출처 :  황선규 박사님 github홈페이지 sunkyoo.github.io/opencv4cvml/

 황선규 박사님의 예제코드를 분석하고 실습해보았습니다.

 

# 입력 영상 불러오기
# 640x480
src = cv2.imread('flowers.jpg')

if src is None:
    print('Image load failed')
    sys.exit()
    
# 차원 변환 $ np.float32 자료형 변환
# 307200, 3
data = src.reshape((-1, 3)).astype(np.float32)

# K-means 알고리즘
# 최대 10번 반복하고 1픽셀 이하로 움직이면 종료
criteria = (cv2.TERM_CRITERIA_EPS|cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

for K in range(5, 11)
    print('K:', K)
    # label은 각각의 데이터가 속한 군집 정보, center은 군집의 중심점 좌표
    ret, label, center = cv2.kmeans(data, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
    
    # 군집화 결과를 이용하여 출력 영상 생성
    center = np.unit8(center)
    
    # 중심점 좌표를 받아서 dst에 입력 (307200, 3) 3은 중심 좌표
    dst = center[label.flatten()] # 각 픽셀을 K개 군집 중심 색상으로 치환
    
    # 입력 영상과 동일한 형태로 변환 (640,480,3)
    dst = dst.reshape((src.shape))
    
    cv2.imshow('src', src)
    cv2.imshow('dst', dst)
    cv2.waitKey()

cv2.destroyAllWindows()

 

원본 영상

 

k=6

 

k=10

 

k(군집 개수)가 증가할수록 다양한 색상을 표현하는 것을 확인할 수 있었습니다.


OpenCV 홈페이지와 황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다.

 

OpenCV: K-Means Clustering in OpenCV

Goal Learn to use cv.kmeans() function in OpenCV for data clustering Understanding Parameters Input parameters samples : It should be of np.float32 data type, and each feature should be put in a single column. nclusters(K) : Number of clusters required at

docs.opencv.org

 

반응형