/// <summary> /// SVM /// </summary> /// <param name="dataFilename"></param> /// <param name="filenameToSave"></param> /// <param name="filenameToLoad"></param> private void BuildSvmClassifier(string dataFilename, string filenameToSave, string filenameToLoad) { //C_SVCのパラメータ const float SvmC = 1000; //RBFカーネルのパラメータ const float SvmGamma = 0.1f; CvMat data = null; CvMat responses = null; CvMat sampleIdx = null; int nsamplesAll = 0, ntrainSamples = 0; double trainHr = 0, testHr = 0; CvSVM svm = new CvSVM(); CvTermCriteria criteria = new CvTermCriteria(100, 0.001); try { ReadNumClassData(dataFilename, 16, out data, out responses); } catch { Console.WriteLine("Could not read the database {0}", dataFilename); return; } Console.WriteLine("The database {0} is loaded.", dataFilename); nsamplesAll = data.Rows; ntrainSamples = (int)(nsamplesAll * 0.2); // Create or load Random Trees classifier if (filenameToLoad != null) { // load classifier from the specified file svm.Load(filenameToLoad); ntrainSamples = 0; if (svm.GetSupportVectorCount() == 0) { Console.WriteLine("Could not read the classifier {0}", filenameToLoad); return; } Console.WriteLine("The classifier {0} is loaded.", filenameToLoad); } else { // create classifier by using <data> and <responses> Console.Write("Training the classifier ..."); // 2. create sample_idx sampleIdx = new CvMat(1, nsamplesAll, MatrixType.U8C1); { CvMat mat; Cv.GetCols(sampleIdx, out mat, 0, ntrainSamples); mat.Set(CvScalar.RealScalar(1)); Cv.GetCols(sampleIdx, out mat, ntrainSamples, nsamplesAll); mat.SetZero(); } // 3. train classifier // 方法、カーネルにより使わないパラメータは0で良く、 // 重みについてもNULLで良い svm.Train(data, responses, null, sampleIdx, new CvSVMParams(CvSVM.C_SVC, CvSVM.RBF, 0, SvmGamma, 0, SvmC, 0, 0, null, criteria)); Console.WriteLine(); } // compute prediction error on train and test data for (int i = 0; i < nsamplesAll; i++) { double r; CvMat sample; Cv.GetRow(data, out sample, i); r = svm.Predict(sample); // compare results Console.WriteLine( "predict: {0}, responses: {1}, {2}", (char)r, (char)responses.DataArraySingle[i], Math.Abs((double)r - responses.DataArraySingle[i]) <= float.Epsilon ? "Good!" : "Bad!" ); r = Math.Abs((double)r - responses.DataArraySingle[i]) <= float.Epsilon ? 1 : 0; if (i < ntrainSamples) { trainHr += r; } else { testHr += r; } } testHr /= (double)(nsamplesAll - ntrainSamples); trainHr /= (double)ntrainSamples; Console.WriteLine("Gamma={0:F5}, C={1:F5}", SvmGamma, SvmC); if (filenameToLoad != null) { Console.WriteLine("Recognition rate: test = {0:F1}%", testHr * 100.0); } else { Console.WriteLine("Recognition rate: train = {0:F1}%, test = {1:F1}%", trainHr * 100.0, testHr * 100.0); } Console.WriteLine("Number of Support Vector: {0}", svm.GetSupportVectorCount()); // Save SVM classifier to file if needed if (filenameToSave != null) { svm.Save(filenameToSave); } Console.Read(); if (sampleIdx != null) { sampleIdx.Dispose(); } data.Dispose(); responses.Dispose(); svm.Dispose(); }
private void trainSVM(string[] shapeTypes) { string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); string folderPath = Path.Combine(myPhotos, "shape_samples"); CvSVM svm = new CvSVM(); CvSVMParams svmParams = new CvSVMParams(); svmParams.SVMType = CvSVM.C_SVC; svmParams.KernelType = CvSVM.LINEAR; svmParams.C = 0.01; int numSamples = Directory.GetFiles(folderPath, "*.png").Length; int numFeatures = 0; if (numSamples == 0) { return; } float[,] extractedFeatures = null; float[] labels = new float[numSamples]; int i = 0; foreach (string file in Directory.EnumerateFiles(folderPath, "*.png")) { Bitmap bitmap = (Bitmap)Image.FromFile(file, true); Mat mat = BitmapConverter.ToMat(bitmap); HOGDescriptor hog = new HOGDescriptor(); hog.WinSize = new OpenCvSharp.CPlusPlus.Size(32, 32); // Set hog features here: winSize; blockSize; cellSize hog.BlockSize = new OpenCvSharp.CPlusPlus.Size(4, 4); hog.CellSize = new OpenCvSharp.CPlusPlus.Size(4, 4); hog.BlockStride = new OpenCvSharp.CPlusPlus.Size(2, 2); float[] features = hog.Compute(mat, new OpenCvSharp.CPlusPlus.Size(16, 16), new OpenCvSharp.CPlusPlus.Size(0, 0), null); if (extractedFeatures == null) { numFeatures = features.Length; extractedFeatures = new float[numSamples, numFeatures]; } for (int j = 0; j < numFeatures; j++) { extractedFeatures[i, j] = features[j]; } labels[i] = -1; for (int shape = 0; shape < shapeTypes.Length; shape++) { if (file.ToLower().Contains(shapeTypes[shape].ToLower())) { labels[i] = shape; break; } } bitmap.Dispose(); i++; } Mat labelsMat = new Mat(numSamples, 1, MatType.CV_32FC1, labels); Mat extractedFeaturesMat = new Mat(numSamples, numFeatures, MatType.CV_32FC1, extractedFeatures); try { svm.Train(extractedFeaturesMat, labelsMat, null, null, svmParams); svm.Save(Path.Combine(folderPath, "trained_svm")); } catch (OpenCVException e) { //Only a single class present } }