Python/파이썬 OpenCV 공부

[OpenCV 머신러닝] OpenCV에서 서포트 벡터 머신(SVM) 사용하기 - cv2.ml.SVM_create, cv2.ml_SVM.trainAuto

AI 꿈나무 2020. 10. 24. 22:31
반응형

 이전 포스팅에서 서포트 벡터 머신(SVM)에 대해 알아보았습니다.

 이번에는 OpenCV로 서포트 벡터 머신을 사용하는 방법에 대해 알아보겠습니다.

 

 객체 생성 -> SVM 타입 지정 -> SVM 커널 지정 -> SVM 자동 학습(k-폴드 교차 검증) -> predict 순으로 진행됩니다.

1. SVM 객체 생성 - cv2.ml.SVM_create()

cv2.ml.SVM_create() -> retval

• retval: cv2.ml_SVM 객체

 cv2.ml.SVM_create() 함수로 cv2.ml_SVM 객체를 반환받을 수 있습니다.

 

2. SVM 타입 지정 - cv2.ml_SVM.setType

cv.ml_SVM.setType(type) -> None

• type: SVM 종류 지정. cv2.ml.SVM_ 으로 시작하는 상수.

 OpenCV에서는 5가지 타입의 SVM를 지원합니다.

type 설명 파라미터
cv2.ml.SVM_C_SVC C-서포트 벡터 분류. 일반적인 n 클래스 분류 문제에서 사용됩니다. C
cv2.ml.SVM_NU_SVC v-서포트 벡터 분류. C_SCV와 비슷하지만 Nu 값 범위가 0~1 사이로 정규화 되어 있습니다. Nu
cv2.ml.SVM_ONE_CLASS 1-분류 서포트 벡터 머신입니다. 데이터 분포 측정에 사용됩니다. C, Nu
cv2.ml.SVM_EPS_SVR $\epsilon$-서포트 벡터 회귀 P, C
cv2.ml.SVM_NU_SVR v-서포트 벡터 회귀 Nu, C

 대부분의 경우 C_SVC를 이용합니다.

 

3. SVM 커널 지정 - cv.ml_SVM.setKernel

cv.ml_SVM.setKernel(kernelType) -> None

• kernelType: 커널 함수 종류 지정. cv2.ml.SVM_ 으로 시작하는 상수.

 커널 함수 종류를 선택할 수 있습니다.

 

4. SVM 자동 학습(k-폴드 교차 검증) - cv2.ml_SVM.trainAuto

 trainAuto 함수는 c, gamma 등 파라미터 값을 자동으로 설정해줍니다.

 파라미터 값을 테스트 해보고 가장 결과가 좋은 값으로 학습을 하므로 연산 속도가 느립니다.

 trainAuto 함수로 파라미터 값만 얻고 train 하는 것을 추천합니다.

 

cv.ml_SVM.trainAuto(samples, layout, responses, kFold=None, ...) -> retval

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

• layout: 학습 데이터 배치 방법. cv2.ROW_SAMPLE 또는 cv2.COL_SAMPLE.

• responses: 각 학습 데이터에 대응되는 응답(레이블) 벡터. numpy.ndarray. shape=(N, ) 또는 (N, 1).dtype=numpy.int32 또는 numpy.float32.

• kFold: 교차 검증을 위한 부분 집합 개수

• retval: 학습이 정상적으로 완료되면 True

 samples, layout, responses를 지정하고 나머지는 디폴트 값으로 입력해주면 됩니다.

 

5. SVM 알고리즘 점 분류 예제

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

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

 

# 8개의 데이터 생성
trains = np.array([[150, 200], [200, 250],
                   [100, 250], [150, 300],
                   [350, 100], [400, 200],
                   [400, 300], [350, 400]], dtype=np.float32)

# 앞 4개는 0번 클래스 뒤 4개는 1번 클래스로 지정
labels = np.array([0, 0, 0, 0, 1, 1, 1, 1])

svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC) # c 파라미터
# svm.setKernel(cv2.ml.SVM_LINEAR) # Gamma 파라미터
svm.setKernel(cv2.ml.SVM_RBF) # Gamma 파라미터

# trainAuto 함수가 C, Gamma 값을 결정해줌
svm.trainAuto(trains, cv2.ml.ROW_SAMPLE, labels)
print('C:', svm.getC())
print('Gamma:', svm.getGamma())

# trainAuto 함수로 알아낸 값을 train 이용하면 더 빠르게 작동 가능
# svm.setC(2.5)
# svm.setGamma(0.00001)
# svm.train(trains, cv2.ml.ROW_SAMPLE, labels)

# 시각화를 위한 코드
w, h = 500, 500
img = np.zeros((h, w, 3), dtype=np.uint8)

# h와 w 모든 좌표에 대해서 1행 2열 test 샘플 만듬
# test 샘플을 predict에 입력
for y in range(h):
    for x in range(w):
        test = np.array([[x, y]], dtype=np.float32)
        _, res = svm.predict(test)
        ret = int(res[0, 0]) # test 샘플이 몇번 클래스인지에 대한 정보, float이므로 int변환

        # 0 번 클래스는 빨강색
        if ret == 0:
            img[y, x] = (128, 128, 255)  # Red
        # 1 번 클래스는 녹색
        else:
            img[y, x] = (128, 255, 128)  # Green

color = [(0, 0, 128), (0, 128, 0)]

# 빨강색과 녹색을 원으로 출력되도록
for i in range(trains.shape[0]):
    x = int(trains[i, 0])
    y = int(trains[i, 1])
    l = labels[i]

    cv2.circle(img, (x, y), 5, color[l], -1, cv2.LINE_AA)

cv2.imshow('svm', img)
cv2.waitKey()
cv2.destroyAllWindows()

 

trainAuto로 얻은 C와 Gamma값

 

SVM으로 분류한 데이터 시각화

 


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

 

OpenCV: cv::ml::SVM Class Reference

Support Vector Machines. More... #include enum  KernelTypes {   CUSTOM =-1,   LINEAR =0,   POLY =1,   RBF =2,   SIGMOID =3,   CHI2 =4,   INTER =5 } SVM kernel type More...   enum  ParamTypes {   C =0,   GAMMA =1,   P =2,   NU =3,

docs.opencv.org

반응형