Как обучить SVM с opencv на основе набора изображений?
у меня есть папка положительных и других отрицательных изображений в формате JPG, и я хочу обучить SVM на основе этих изображений, я сделал следующее, Но я получаю сообщение об ошибке:
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);
когда я пытаюсь запустить, что я получаю:
OpenCV Error: Bad argument (train data must be floating-point matrix) in cvCheckTrainData, file ......srcopencvmodulesmlsrcinner_functions.cpp, line 857
Exception in thread "main" CvException [org.opencv.core.CvException: ......srcopencvmodulesmlsrcinner_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)
Я не могу тренировать SVM, есть идеи? Спасибо
2 ответов
предполагая, что вы знаете, что делаете, изменяя изображение и используя его для обучения SVM, наиболее вероятной причиной этого является то, что ваш
Mat img = Highgui.imread(file.getAbsolutePath());
не удается фактически прочитать изображение, генерируя матрицу img
С null data
свойство, которое в конечном итоге вызовет следующее В коде 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" );
в принципе train_data
сбой первого условия (будучи допустимой матрицей), а не сбой второго условия (будучи типа CV_32FC1).
кроме того, хотя reshape работает на *this
объект, он действует как фильтр, и его эффект не является постоянным. Если он используется в одном операторе без немедленного использования или назначения другой переменной, он будет бесполезен. Измените следующие строки кода:
img.reshape(1, 1);
trainingImages.push_back(img);
в:
trainingImages.push_back(img.reshape(1, 1));
как говорится в ошибке, вам нужно изменить тип вашей матрицы, от целочисленного типа, вероятно CV_8U, до с плавающей запятой, CV_32F или CV_64F. Для этого вы можете использовать cv::Mat::convertTo()
. здесь немного о глубинах и типах матриц.