2013-06-01 61 views
6

Tôi có một thư mục của mặt tích cực và tiêu cực khác của hình ảnh ở định dạng JPG, và tôi muốn đào tạo một SVM dựa trên đó hình ảnh, tôi đã thực hiện những điều sau đây nhưng tôi nhận được một lỗi:Làm thế nào để đào tạo một SVM với opencv dựa trên một tập hợp các hình ảnh?

Mat classes = new Mat(); 
Mat trainingData = new Mat(); 

Mat trainingImages = new Mat(); 
Mat trainingLabels = new Mat(); 

CvSVM clasificador; 

for (File file : new File(path + "positives/").listFiles()) { 
     Mat img = Highgui.imread(file.getAbsolutePath()); 
     img.reshape(1, 1); 

     trainingImages.push_back(img); 
     trainingLabels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32FC1)); 
    } 

    for (File file : new File(path + "negatives/").listFiles()) { 
     Mat img = Highgui.imread(file.getAbsolutePath()); 
     img.reshape(1, 1); 

     trainingImages.push_back(img); 
     trainingLabels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32FC1)); 
    } 

    trainingImages.copyTo(trainingData); 
    trainingData.convertTo(trainingData, CvType.CV_32FC1); 
    trainingLabels.copyTo(classes); 

    CvSVMParams params = new CvSVMParams(); 
    params.set_kernel_type(CvSVM.LINEAR); 

    clasificador = new CvSVM(trainingData, classes, new Mat(), new Mat(), params); 

Khi tôi cố gắng chạy mà tôi có được:

OpenCV Error: Bad argument (train data must be floating-point matrix) in cvCheckTrainData, file ..\..\..\src\opencv\modules\ml\src\inner_functions.cpp, line 857 
Exception in thread "main" CvException [org.opencv.core.CvException: ..\..\..\src\opencv\modules\ml\src\inner_functions.cpp:857: error: (-5) train data must be floating-point matrix in function cvCheckTrainData 
] 
    at org.opencv.ml.CvSVM.CvSVM_1(Native Method) 
    at org.opencv.ml.CvSVM.<init>(CvSVM.java:80) 

Tôi không thể quản lý SVM, ý tưởng nào? Cảm ơn

+0

Tôi đang cố gắng để phân loại tấm dựa trên segmets tôi đã thu được, mã của tôi được dựa trên ví dụ này: https: // github .com/MasteringOpenCV/code/blob/master/Chapter5_NumberPlateRecognition/trainSVM.cpp –

+0

Bạn đã thử sử dụng CV_64F chưa? Và đã làm bạn, chỉ để được hoàn toàn chắc chắn, kiểm tra những gì là loại 'trainingData' ngay trước khi nó được thông qua vào CvSVM? – morynicz

+0

cảm ơn @morynicz, 'CvType.typeToString (trainingData.type())' sẽ trả về "CV_32FC3" .. Cũng cố chuyển đổi thành CV_64F với cùng lỗi –

Trả lời

11

Giả sử rằng bạn biết những gì bạn đang làm bằng cách định hình lại một hình ảnh và sử dụng nó để huấn luyện SVM, nguyên nhân có thể xảy ra nhất của việc này là bạn

Mat img = Highgui.imread(file.getAbsolutePath()); 

không thực sự đọc một hình ảnh, tạo ra một ma trận img với tài sản vô data, mà cuối cùng sẽ kích hoạt sau trong mã OpenCV:

// check parameter types and sizes 
if(!CV_IS_MAT(train_data) || CV_MAT_TYPE(train_data->type) != CV_32FC1) 
    CV_ERROR(CV_StsBadArg, "train data must be floating-point matrix"); 

về cơ bản train_data thất bại điều kiện đầu tiên (là một ma trận hợp lệ) chứ không phải là thất bại thứ hai điều kiện (thuộc loại CV_32FC1).

Ngoài ra, mặc dù định dạng lại hoạt động trên đối tượng *this, nó hoạt động như bộ lọc và hiệu ứng của nó không phải là vĩnh viễn. Nếu nó được sử dụng trong một câu lệnh đơn mà không sử dụng ngay hoặc gán cho một biến khác thì nó sẽ vô dụng. Thay đổi dòng sau trong mã của bạn:

img.reshape(1, 1); 
trainingImages.push_back(img); 

tới:

trainingImages.push_back(img.reshape(1, 1)); 
0

Giống như lỗi nói, Bạn cần thay đổi loại ma trận của bạn, từ kiểu số nguyên, có thể là CV_8U, thành dấu phẩy động, CV_32F hoặc CV_64F. Để làm điều đó Bạn có thể sử dụng cv::Mat::convertTo(). Here là một chút về độ sâu và loại ma trận.

+0

thực sự tôi làm: 'trainingData.convertTo (trainingData, CvType.CV_32FC1); ' và 'các lớp' của tôi được điền bằng [1] ma trận CV_32FC1 –

+0

Rất tiếc. Xin lỗi, không thấy điều đó. – morynicz

Các vấn đề liên quan