이전 포스팅에서 서포트 벡터 머신(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
'Python > 파이썬 OpenCV 공부' 카테고리의 다른 글
[OpenCV 머신러닝] 학습 데이터 영상을 위치 정규화하여 성능 높이기 - cv2.moments, cv2.warpAffine (0) | 2020.10.25 |
---|---|
[OpenCV 머신러닝] OpenCV에서 HOG 알고리즘을 이용한 SVM 필기체 숫자 인식 (0) | 2020.10.25 |
[OpenCV 머신러닝] 서포트 벡터 머신 알고리즘이란? (0) | 2020.10.24 |
[OpenCV 머신러닝] OpenCV로 KNN 필기체 숫자 인식 프로그램 구현하기 (2) | 2020.10.24 |
[OpenCV 머신러닝] OpenCV로 k 최근접 이웃 알고리즘(KNN) 구현하기 - cv2.ml.KNearest_create (0) | 2020.10.24 |