Im trying to do 3 class classification with 5 samples for each class on android But im getting this error OpenCV Error: Assertion failed (nsamples == 1) in virtual float cv::ml::SVMImpl::predict ?
Here is my code
public ImageDetection(Context mContext) throws IOException { context = mContext; TermCriteria tc = new TermCriteria(CV_TERMCRIT_ITER, 10, 0.001); dictionarySize = 1500; int retries = 1; bowTrainer = new BOWKMeansTrainer(dictionarySize, tc, retries, KMEANS_PP_CENTERS);
descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
bowImgDescriptorExtractor = new BOWImgDescriptorExtractor(descriptorExtractor, descriptorMatcher);
trainDescriptor = new MatVector();
evalDescriptor = new Mat();
trainLabs = new int[15];
evalLabs = new int[15];
initializeSVM();
collectClassCentroids();
startClustering();
evaluate();
}
private void initializeSVM() {
svm.setKernel(SVM.RBF);
svm.setType(SVM.C_SVC);
svm.setGamma(0.50625000000000009);
svm.setC(312.50000000000000);
svm.setTermCriteria(new TermCriteria(CV_TERMCRIT_ITER, 100, 0.000001));
}
private void collectClassCentroids() throws IOException {
int[][] train = new int[][]{{R.drawable.train1_1, R.drawable.train1_2, R.drawable.train1_3, R.drawable.train1_4, R.drawable.train1_5},
{R.drawable.train2_1, R.drawable.train2_2, R.drawable.train2_3, R.drawable.train2_4, R.drawable.train2_5},
{R.drawable.train3_1, R.drawable.train3_2, R.drawable.train3_3, R.drawable.train3_4, R.drawable.train3_5}};
int counter1 = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
Mat src = loadResource(train[i][j]);
if (!src.empty()) {
cvtColor(src,src, CV_RGBA2GRAY);
KeyPointVector mKeypoint = new KeyPointVector();
featureDetector.detect(src, mKeypoint);
Mat mFeatures = new Mat();
descriptorExtractor.compute(src, mKeypoint, mFeatures);
trainLabs[counter1] = i;
counter1++;
bowTrainer.add(mFeatures);
}
}
}
}
public void startClustering() throws IOException {
trainDescriptor = bowTrainer.getDescriptors();
int countRow = 0;
for (int i = 0; i < trainDescriptor.size(); i++) {
countRow += trainDescriptor.get(i).rows();
}
Mat dictionary = bowTrainer.cluster();
bowImgDescriptorExtractor.setVocabulary(dictionary);
trainLabel = new Mat(trainLabs);
Mat trainingData = new Mat(0, dictionarySize, CV_32FC1);
KeyPointVector keyPointVector1 = new KeyPointVector();
Mat bowDescriptor1 = new Mat();
int[][] train = new int[][]{{R.drawable.train1_1, R.drawable.train1_2, R.drawable.train1_3, R.drawable.train1_4, R.drawable.train1_5},
{R.drawable.train2_1, R.drawable.train2_2, R.drawable.train2_3, R.drawable.train2_4, R.drawable.train2_5},
{R.drawable.train3_1, R.drawable.train3_2, R.drawable.train3_3, R.drawable.train3_4, R.drawable.train3_5}};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
Mat src = loadResource(train[i][j]);
cvtColor(src, src, CV_RGBA2GRAY);
featureDetector.detect(src, keyPointVector1);
bowImgDescriptorExtractor.compute(src, keyPointVector1, bowDescriptor1);
trainingData.push_back(bowDescriptor1);
}
}
System.out.println("Training Data "+trainingData.rows()+","+trainingData.cols());
System.out.println("Training Label "+trainLabel.rows()+","+trainLabel.cols());
svm.train(trainingData, ROW_SAMPLE, trainLabel);
}
public void evaluate() throws IOException {
int [] evalLabel = trainLabs;
Mat groundTruth = new Mat(evalLabel);
Mat evalData = new Mat(0,dictionarySize,CV_32FC1);
KeyPointVector keyPointVectorEval = new KeyPointVector();
Mat bowDescriptor = new Mat();
Mat results = new Mat(0,1,CV_32FC1);
int[][] eval = new int[][]{{R.drawable.train1_1, R.drawable.train1_2, R.drawable.train1_3, R.drawable.train1_4, R.drawable.train1_5},
{R.drawable.train2_1, R.drawable.train2_2, R.drawable.train2_3, R.drawable.train2_4, R.drawable.train2_5},
{R.drawable.train3_1, R.drawable.train3_2, R.drawable.train3_3, R.drawable.train3_4, R.drawable.train3_5}};
for (int i = 0; i < 4; i++) {
for (int j = 0; j <5 ; j++) {
Mat rImg = loadResource(eval[i][j]);
cvtColor(rImg, rImg, CV_RGBA2GRAY);
featureDetector.detect(rImg, keyPointVectorEval);
bowImgDescriptorExtractor.compute(rImg, keyPointVectorEval, bowDescriptor);
//evalData.push_back(bowDescriptor);
System.out.print("Ground Truth : "+evalLabel[i]);
Mat pass = bowDescriptor.reshape(1,1);
evalData.push_back(pass);
float respons = svm.predict(evalData);
int getInt = ((int) respons);
System.out.println("Response : "+respons);
}
}
// Mat subs = subtractPut(groundTruth, results);
//double errorRate = (double)countNonZero(subs) / evalData.rows();
//System.out.println("Error rate is : "+errorRate);
}
private Mat loadResource(int resourceId) throws IOException {
InputStream is = context.getResources().openRawResource(resourceId);
int bytesRead;
byte[] data = new byte[16 * 1024];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((bytesRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, bytesRead);
}
byte[] bytes = buffer.toByteArray();
Mat mat = imdecode(new Mat(bytes), CV_32FC1);
return mat;
}