2011-12-31 19 views
10

Vì vậy, tôi có một ma trận với hình ảnh mẫu của tôi (tất cả biến thành vectơ) được chạy máng PCA/LDA, và một vector biểu thị lớp mỗi hình ảnh thuộc về. Bây giờ tôi muốn sử dụng lớp SVM OpenCV để huấn luyện SVM của tôi (Tôi đang sử dụng Python, OpenCV 2.3.1). Nhưng tôi có vấn đề với việc xác định tham số:Python OpenCV SVM thực hiện

test = cv2.SVM() 
test.train(trainData, responses, ????) 

Tôi bị kẹt về cách xác định loại SVM (tuyến tính, v.v.) và các nội dung khác. Trong C++ bạn định nghĩa nó bằng cách nói rõ ví dụ: svm_type = CvSVM :: C_SVC ... Python không có. C++ cũng có một lớp đặc biệt để lưu trữ các tham số này -> CvSVMParams. Ai đó có thể cho tôi một ví dụ về điều này trong Python? Giống như việc xác định loại SVM, gamma vv

Các 2.3.1 tài liệu nói nó như thế này:

Python: cv2.SVM.train(trainData, responses[, varIdx[, sampleIdx[, params]]]) → retval 

varIdx và sampleIdx là gì, và làm thế nào để xác định params?

+1

Tôi hiện đang đọc tài liệu, nhưng trong khi đó, bạn có thể sử dụng giải pháp thay thế: chuyển ma trận thành gumpy và sử dụng sk-learn cho nhiệm vụ học máy. – timgluz

+0

Xin chào! Hãy thử các ví dụ sau: https://code.ros.org/svn/opencv/trunk/opencv/samples/python2/letter_recog.py – timgluz

+0

timgluz THX đó chính xác là những gì tôi đang tìm kiếm ... bạn có thể vui lòng sao chép phần SVM từ các liên kết trong một câu trả lời để tôi có thể chấp nhận nó (để những người khác có thể tìm thấy câu trả lời ngay lập tức và u nhận được tín dụng) ... phần SVM là từ dòng 79 đến 91 ... – Veles

Trả lời

18

Để sử dụng các thuật toán máy học OpenCV, bạn phải viết một số lớp wrapper:

1. tầng lớp phụ huynh đầu tiên

class StatModel(object): 
    '''parent class - starting point to add abstraction'''  
    def load(self, fn): 
     self.model.load(fn) 
    def save(self, fn): 
     self.model.save(fn) 

2. Cuối cùng SVM wrapper:

class SVM(StatModel): 
    '''wrapper for OpenCV SimpleVectorMachine algorithm''' 
    def __init__(self): 
     self.model = cv2.SVM() 

    def train(self, samples, responses): 
     #setting algorithm parameters 
     params = dict(kernel_type = cv2.SVM_LINEAR, 
         svm_type = cv2.SVM_C_SVC, 
         C = 1) 
     self.model.train(samples, responses, params = params) 

    def predict(self, samples): 
     return np.float32([self.model.predict(s) for s in samples]) 

3.Việc sử dụng mẫu:

import numpy as np 
import cv2 

samples = np.array(np.random.random((4,2)), dtype = np.float32) 
y_train = np.array([1.,0.,0.,1.], dtype = np.float32) 

clf = SVM() 
clf.train(samples, y_train) 
y_val = clf.predict(samples) 

Cài đặt thông số

Cài đặt thông số rất đơn giản - chỉ cần viết một cuốn từ điển chứa các thông số như phím. Bạn nên xem tài liệu gốc để xem tất cả các thông số có thể và giá trị được phép: http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#cvsvmparams

Có, giá trị có thể cho svm_type và kernel_type là C++, nhưng có cách dễ dàng để chuyển đổi các hằng số đó sang dạng Python, ví dụ: CvSVM :: C_SVC được viết dưới dạng cv2.SVM_C_SVC bằng Python.

Prelude Để biết thêm giấy gói cho các thuật toán máy học, nhìn vào letter-recog.py dụ trong các ví dụ opencv của bạn trên đĩa hoặc url mở kho OpenCV: https://github.com/Itseez/opencv/tree/master/samples/python2

+0

Điều này có vẻ rất hứa hẹn. Tôi đã đăng ký tại ros.org nhưng khi tôi nhập tên và mật khẩu của tôi cho các liên kết để python mẫu, tôi nhận được hộp thoại này và không thể vượt qua nó. "Để xem trang này, bạn phải đăng nhập vào khu vực này trên code.ros.org:443:" Có tên/mật khẩu đặc biệt cho khu vực svn này, ngoài vùng của riêng tôi không? – zerowords

+0

Xin chào! Đáng buồn là họ đã hủy bỏ chế độ xem công khai cho kho lưu trữ này. Tôi sẽ đăng một số cách giải quyết rất sớm. – timgluz

+0

Mã này chỉ hoạt động cho OpenCV 2. Trong OpenCV 3, các hàm SVM đã được chuyển từ cv2 sang cv2.ml và để tạo mô hình, hàm mới là cv2.ml.SVM_create() – jpyams

1

Phỏng theo timgluz phiên bản, nhưng sử dụng "train_auto" thay vì "train". cv2 sẽ tìm các thông số "C", "gamma", ... cho chúng tôi.

import cv2 
import numpy as np 

class Learn: 
    def __init__(self, X, y): 
     self.est = cv2.SVM() 
     params = dict(kernel_type=cv2.SVM_LINEAR, svm_type=cv2.SVM_C_SVC) 
     self.est.train_auto(X, y, None, None, params, 3) #kfold=3 (default: 10) 

    def guess(self, X): 
     return np.float32([self.est.predict(s) for s in X]) 

X = np.array(np.random.random((6,2)), dtype = np.float32) 
y = np.array([1.,0.,0.,1.,0.,1.], dtype = np.float32) 
g = Learn(X,y).guess(X)