Problem when training SVM with ORB descriptors (Android)
Hello guys!
I have a folder with 20 positive and 10 negative images and I'm trying to train an SVM through the image descriptors using ORB. I'm getting the following error when calling svm.TrainAuto:
E/cv::error(): OpenCV(3.4.1) Error: Assertion failed (samples.type() == 5 || samples.type() == 4) in void cv::ml::TrainDataImpl::setData(cv::InputArray, int, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray), file /build/master_pack-android/opencv/modules/ml/src/data.cpp, line 259
E/org.opencv.ml: ml::trainAuto_11() caught cv::Exception: OpenCV(3.4.1) /build/master_pack-android/opencv/modules/ml/src/data.cpp:259: error: (-215) samples.type() == 5 || samples.type() == 4 in function void cv::ml::TrainDataImpl::setData(cv::InputArray, int, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray)
The code I'm using is below:
public class TrainingActivity extends Activity {
private final String TAG = "OpenCV";
private Button mTrainingButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_training);
mTrainingButton = findViewById(R.id.trainingButton);
}
@Override
protected void onResume() {
super.onResume();
initOpenCV();
}
public void onTrainingButtonClick(View view) {
train();
}
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback() {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
onLoaderCallbackSuccess();
break;
default:
super.onManagerConnected(status);
}
}
};
private void initOpenCV() {
if (OpenCVLoader.initDebug())
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
else
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, mLoaderCallback);
}
private void onLoaderCallbackSuccess() {
mTrainingButton.setVisibility(View.VISIBLE);
}
private void train() {
final ORB orb = ORB.create();
Mat extractorTrainingData = new Mat();
Mat extractorTrainingLabel = new Mat();
String path = "/OpenCV/training/open/positives";
File[] files = FileHelper.getFiles(path);
// Positives
for (File file : files) {
try {
Mat image = Imgcodecs.imread(file.getAbsolutePath());
Mat grayImage = new Mat();
Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_RGB2GRAY);
Log.d(TAG, grayImage.dump());
MatOfKeyPoint keyPoints = new MatOfKeyPoint();
orb.detect(grayImage, keyPoints);
Log.d(TAG, keyPoints.dump());
MatOfFloat descriptors = new MatOfFloat();
orb.compute(grayImage, keyPoints, descriptors);
Log.d(TAG, descriptors.dump());
extractorTrainingData.push_back(descriptors);
extractorTrainingLabel.push_back(Mat.ones(new Size(1, 1), CvType.CV_32S));
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
path = "/OpenCV/training/open/negatives";
files = FileHelper.getFiles(path);
// Negatives
for (File file : files) {
try {
Mat image = Imgcodecs.imread(file.getAbsolutePath());
Mat grayImage = new Mat();
Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_RGB2GRAY);
Log.d(TAG, grayImage.dump());
MatOfKeyPoint keyPoints = new MatOfKeyPoint();
orb.detect(grayImage, keyPoints);
Log.d(TAG, keyPoints.dump());
MatOfFloat descriptors = new MatOfFloat();
orb.compute(grayImage, keyPoints, descriptors);
Log.d(TAG, descriptors.dump());
extractorTrainingData.push_back(descriptors);
extractorTrainingLabel.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32S));
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
try {
SVM svm = SVM.create();
svm.setKernel(SVM.RBF);
svm.setType(SVM.C_SVC);
//Mat mat = extractorTrainingData.reshape(1, 1);
//Boolean result = svm.trainAuto(
// mat, Ml.ROW_SAMPLE, extractorTrainingLabel);
Boolean result = svm.trainAuto(
extractorTrainingData, Ml.ROW_SAMPLE, extractorTrainingLabel);
String xml = Environment
.getExternalStorageDirectory() + "/images/svm.xml";
if (result)
svm.save(xml);
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
}
I've tried using the reshape function in these settings:
Mat mat = extractorTrainingData.reshape(1, 1);
Boolean result = svm.trainAuto(mat, Ml.ROW_SAMPLE, extractorTrainingLabel);
Mat ...