Color based classification using SVM
I would like to ask a question about how to use SVM to classify images based on colors:
I have a dataset which contains 15 features extracted using simple image histogram includes mean, stddev, mode, and other statistics accompanied with a label in the same dataset.
How I can proceed from this dataset and how to change it to xml file store and load it in my Android app. Do I need to separate the dataset into training and label data, etcl.
I know there is lots of material in the website but a kind help from you will save my time.
Here the code I developed and I have this error: E/cv::error(): OpenCV Error: Assertion failed (samples.cols == var_count && samples.type() == CV_32F) in virtual float cv::ml::SVMImpl::predict(cv::InputArray, cv::OutputArray, int) const, file /Volumes/Linux/builds/master_pack-android/opencv/modules/ml/src/svm.cpp, line 1930
int trainingRow = 18;
int trainingCol = 18;
Mat trainingDataMat = new Mat(trainingRow, trainingCol, CvType.CV_32FC1);
int testingRow = 1;
int testingCol = 18;
Mat testingDataMat = new Mat(testingRow, testingCol, CvType.CV_32FC1);
featureVector = "featureVector";
double[][] trainingList = new double[trainingRow][trainingCol];
trainingList = readFromFile(featureVector, trainingRow, trainingCol);
for(int i=0;i<trainingRow;i++){
for(int j=0;j<trainingCol;j++) {
Log.i(TAG, "Data of data" + "[" + i + "," + j + "]" + " " + trainingList[i][j]);
trainingDataMat.put(i, j, trainingList[i][j]);
}
v_features.push_back(trainingDataMat.reshape(1,1));
}
featureVector = "label";
int[] labelList = new int[trainingRow];
labelList = readFromFile1(featureVector);
for(int i=0;i<trainingRow;i++){
Log.i(TAG, "Data of label " + "[" + i + "]" + " " + labelList[i]);
Mat labelsMat = new Mat(1, 1, CvType.CV_32SC1, new Scalar(labelList[i]));
trainingLabels.push_back(labelsMat);
}
Log.i(TAG,"Training...");
v_features.copyTo(trainingData);
trainingData.convertTo(trainingData, CvType.CV_32F);
trainingLabels.copyTo(classes);
classes.convertTo(classes, CvType.CV_32S);
classifier.setType(SVM.C_SVC);
classifier.setKernel(SVM.LINEAR);
classifier.setGamma(0.5);
classifier.setNu(0.5);
classifier.setC(1);
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
classifier.setTermCriteria(criteria);
classifier.train(trainingData, Ml.ROW_SAMPLE, classes);
Log.i(TAG,"Done Training");
Log.i(TAG,"Testing...");
featureVector = "testVector";
double[][] testingList = new double[testingRow][testingCol];
testingList = readFromFile(featureVector, testingRow, testingCol);
for(int i=0;i<testingRow;i++) {
for (int j = 0; j < testingCol; j++) {
Log.i(TAG, "Data of test" + "[" + i + "," + j + "]" + " " + testingList[i][j]);
testingDataMat.put(i, j, testingList[i][j]);
}
vt_features.push_back(testingDataMat.reshape(1, 1));
}
vt_features.copyTo(testingData);
testingData.convertTo(testingData, CvType.CV_32F);
Log.i(TAG, "classification result" + classifier.predict(testingData));
save our time, too, please.
show us, what you tried, so far, so we don't have to start from 0
Thanks for your help. So far I segmented an image and i calculated mean, mode, stddev, energy, and entropy and create a dataset. Now i would like to use SVM to train the data and afterward predict the correct classification using my Android app
here is a rough outline for hog features. try something, and come back, if you run into trouble.
@berak Thank for the link. I followed exctaly what in the link but I countered a problem in the line v_descriptors.push_back(descriptorsValues.reshape(1, 1)); I think the reshape function did not work for me and I delete it then I countered a problem with the line classifier.train(trainingData, Ml.ROW_SAMPLE, classes); I really need suggestion on that.
you your features have to be a single row matrix, so if it's an image, or a column vector, you need to reshape(1,1) your images, for both training and testing. (each row in the trainData is supposed to be 1 sample)
what went wrong ? how do you put your features into a Mat ?
I put the segmented images in the path String PATH_POSITIVE = "/mnt/sdcard/Data_Set/Postive_Img"; and then use just HOGDescriptor to extract the features. Is that right or I need to add my features that I extracted (I extracted 18 features from the image which in double values). The app stop working at this point when reshaping the descriptor produced by the HOG.
can we focus on the data, you get from your textfile, for now ? (see answer below)
if that works out, we can expand it to use HOG features instead, but possibly in a follow-up question.
@Nani, any updates / new problems there ? i cannot see anything.