matplotlib, OpenCV로 데이터 clustering 하기 (cluster 개수 없이)
컴퓨터비전

matplotlib, OpenCV로 데이터 clustering 하기 (cluster 개수 없이)

반응형

clustering(군집화)는 데이터 분포를 분석하여 비슷한 집단끼리 묶어주는 기술이다.


clusters

최근 딥러닝 분야에서 이 기술을 많이 사용하는데, 꼭 딥러닝 뿐만 아니라 다양한 문제에서 유용하게 사용할 수 있다.

예를들어 필자가 이 알고리즘을 이용하는 이유는 대학교에서 출전하는 자율주행차 대회 때문인데, Lidar에서 받아온 좌표값을 분석하기 위해 사용될 예정이다. 아래와 같이 고깔 장애물을 피할때 clustering 기법을 이용하면 편하게 최적 경로의 알고리즘을 구현할 수 있을 것 이다.



사실 clustering 알고리즘은 구글링을 하면 쉽게 찾을 수 있는데 대부분의 코드가 cluster의 개수를 정해줘야 한다. 하지만 최적의 cluster의 개수도 찾을 수 있다면 더욱더 좋을 것이다.

마침 stack overflow에 좋은 예시가 있어 참고했다.


https://stackoverflow.com/questions/10136470/unsupervised-clustering-with-unknown-number-of-clusters


위 링크의 코드를 살짝 수정해서 plt 대신 opencv에서 실시간으로 돌아가게 해봤다. 코드는 아래와 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import matplotlib.pyplot as plt
import numpy
import cv2
import scipy.cluster.hierarchy as hcluster
 
while True:
    img = numpy.zeros((6006003), numpy.uint8)
 
    N = 50
    data = numpy.random.randn(3 * N, 2)
    data[:N] += 6
    data[-N:] += 12
 
    thresh = 1.6
    clusters = hcluster.fclusterdata(data, thresh, criterion="distance")
 
    plt.scatter(*numpy.transpose(data), c=clusters)
 
    for i in range(03 * N - 1):
        x = int(((numpy.transpose(data)[0])[i]+4* 30)
        y = int(((numpy.transpose(data)[1])[i]+4* 30)
 
        max = clusters.max()
        min = 1
 
        for j in range(min, max):
            X = numpy.transpose(data)[0][clusters == i]
            X = (X + 4* 30
            Y = numpy.transpose(data)[1][clusters == i]
            Y = (Y + 4* 30
 
            if len(X) and len(Y) > 2:
                avg_X = int((numpy.mean(X)))
                avg_Y = int((numpy.mean(Y)))
                img = cv2.circle(img, (avg_X, avg_Y), 10, (00255), -1)
 
        img = cv2.circle(img, (x, y), 2, (255255255), -1)
 
    cv2.imshow('image', img)
 
    if cv2.waitKey(5& 0xFF == ord('q'):
        break
 
cv2.waitKey(0)
cv2.destroyAllWindows()
cs


결과는 아래와 같다.



총 300개의 점을 3개의 집합으로 나눴을때 매우 빠른 속도로 clustering을 한 뒤 각각의 cluster에 중심을 빨간 점으로 표시하는 코드이다. (OpenCV를 사용한 이유는 pit.show()가 상대적으로 느리기 때문)


반응형
    # 테스트용