Quantcast
Channel: OpenCV Q&A Forum - RSS feed
Viewing all articles
Browse latest Browse all 4615

SVM predict error on OpenCV4Android

$
0
0
Hi guys, I performed the training of an SVM based on the code below. I used C # for familiarity with the language. I tried doing with Java, directly on Android, but I had some problems as described in this question, mainly due to the absence of the class BOWImgDescriptorExtractor: C# Trainning public class Training { KAZE extractor; BFMatcher bFMatcher; BOWKMeansTrainer bOWKMeansTrainer; BOWImgDescriptorExtractor bOWImgDescriptorExtractor; Mat descriptorsExtractor; Mat descriptorsBOWImgDescriptorExtractor; int dictionarySize = 32; Dictionary images; List imagesType = new List { 0, 1 }; public Training() { extractor = new KAZE(true, true); bFMatcher = new BFMatcher(DistanceType.L2); bOWKMeansTrainer = new BOWKMeansTrainer( dictionarySize, new MCvTermCriteria(10, 0.001), 1, KMeansInitType.PPCenters); bOWImgDescriptorExtractor = new BOWImgDescriptorExtractor(extractor, bFMatcher); descriptorsExtractor = new Mat(); descriptorsBOWImgDescriptorExtractor = new Mat(0, dictionarySize, DepthType.Cv32F, 1); images = new Dictionary(); images.Add(0, 15); images.Add(1, 17); } public void Train() { string path = System.Reflection.Assembly.GetExecutingAssembly().Location; path = Directory.GetParent(Directory.GetParent(path).ToString()).ToString(); // Step 1 for (var i = 0; i < imagesType.Count; i++) { var type = imagesType[i]; for (var j = 1; j <= images[type]; j++) { var file = $@"{path}\Train\{type} ({j}).jpg"; var image = new Image(file); MKeyPoint[] keyPoints = extractor.Detect(image); Mat descriptors = new Mat(); extractor.Compute(image, new VectorOfKeyPoint(keyPoints), descriptors); descriptorsExtractor.PushBack(descriptors); } } bOWKMeansTrainer.Add(descriptorsExtractor); // Step 2 int count = bOWKMeansTrainer.DescriptorCount; Console.WriteLine($"Clustering {count} descriptors"); Mat dictionary = new Mat(); bOWKMeansTrainer.Cluster(dictionary); bOWImgDescriptorExtractor.SetVocabulary(dictionary); // Step 3 Matrix labels; List listLabels = new List(); for (var i = 0; i < imagesType.Count; i++) { var type = imagesType[i]; for (var j = 1; j <= images[type]; j++) { var file = $@"{path}\Train\{type} ({j}).jpg"; var image = new Image(file); MKeyPoint[] keyPoints = extractor.Detect(image); Mat descriptors = new Mat(); bOWImgDescriptorExtractor.Compute(image, new VectorOfKeyPoint(keyPoints), descriptors); descriptorsBOWImgDescriptorExtractor.PushBack(descriptors); listLabels.Add(type); } } labels = new Matrix(listLabels.ToArray()); // Step 4 SVM svm = new SVM(); svm.SetKernel(SVM.SvmKernelType.Rbf); svm.Type = SVM.SvmType.CSvc; svm.Gamma = 0.50625000000000009; svm.C = 312.50000000000000; svm.TermCriteria = new MCvTermCriteria(100, 0.000001); bool result = svm.Train( descriptorsBOWImgDescriptorExtractor, Emgu.CV.ML.MlEnum.DataLayoutType.RowSample, labels); svm.Save("output.xml"); ///////////////////////////////////////////// var file1 = $@"{path}\Train\{1} ({18}).jpg"; var img = new Image(file1); MKeyPoint[] keypoints = null; var bowDescriptor = new Mat(); keypoints = extractor.Detect(img); bOWImgDescriptorExtractor.Compute( img, new VectorOfKeyPoint(keypoints), bowDescriptor); var response = svm.Predict(bowDescriptor); Console.WriteLine($"Result {response}"); } } Question http://answers.opencv.org/question/199980/problem-when-training-svm-with-orb-descriptors-android/ As suggested, I conducted the training using KAZE (UpRight) and BagOfWords. After generating the output.xml file, I loaded it on Android and tried to sort a simple image. Output.xml https://pastebin.com/fDm8Ynnx This is the code I'm using to sort the image: private void predict(Mat image) { Mat grayImage = new Mat(); Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY); KAZE kaze = KAZE.create(); kaze.setUpright(true); kaze.setExtended(true); MatOfKeyPoint keyPoints = new MatOfKeyPoint(); kaze.detect(grayImage, keyPoints); MatOfFloat descriptors = new MatOfFloat(); kaze.compute(grayImage, keyPoints, descriptors); try { float result = svm.predict(descriptors); } catch(Exception e) { Log.d(TAG, e.getMessage()); } } However, I have obtained this exception: **error: (-215:Assertion failed) samples.cols == var_count && samples.type() == CV_32F in function 'virtual float cv::ml::SVMImpl::predict(cv::InputArray, cv::OutputArray, int) const** I've tried several settings, but they all give me the same error. descriptors.convertTo(descriptors, CvType.CV_32F); try { float result = svm.predict(descriptors); } catch(Exception e) { Log.d(TAG, e.getMessage()); } ----------------------------------------------------------------- Mat mat = descriptors.reshape(1, 1); try { float result = svm.predict(mat); } catch(Exception e) { Log.d(TAG, e.getMessage()); } ----------------------------------------------------------------- Mat mat = descriptors.reshape(descriptors.cols(), 1); try { float result = svm.predict(mat); } catch(Exception e) { Log.d(TAG, e.getMessage()); } ----------------------------------------------------------------- Mat testMat = image.clone().reshape(image.cols(),1); testMat.convertTo(testMat, CvType.CV_32F); try { float result = svm.predict(testMat); } catch(Exception e) { Log.d(TAG, e.getMessage()); } In this case: 1 - Since I'm only using one image, I do not need to use BagOfWords. I can directly use the descriptors obtained by KAZE. Is this correct? 2 - In some examples that I found in other languages, people directly use the Mat object of the loaded image. Is it possible to call svm.predict using this Mat object? Thank you!

Viewing all articles
Browse latest Browse all 4615


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>