/// <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(); }
public void Run() { // Training data var points = new CvPoint2D32f[500]; var responses = new int[points.Length]; var rand = new Random(); for (int i = 0; i < responses.Length; i++) { double x = rand.Next(0, 300); double y = rand.Next(0, 300); points[i] = new CvPoint2D32f(x, y); responses[i] = (y > f(x)) ? 1 : 2; } // Show training data and f(x) using (Mat pointsPlot = Mat.Zeros(300, 300, MatType.CV_8UC3)) { for (int i = 0; i < points.Length; i++) { int x = (int)points[i].X; int y = (int)(300 - points[i].Y); int res = responses[i]; Scalar color = (res == 1) ? Scalar.Red : Scalar.GreenYellow; pointsPlot.Circle(x, y, 2, color, -1); } // f(x) for (int x = 1; x < 300; x++) { int y1 = (int)(300 - f(x - 1)); int y2 = (int)(300 - f(x)); pointsPlot.Line(x - 1, y1, x, y2, Scalar.LightBlue, 1); } Window.ShowImages(pointsPlot); } // Train var dataMat = new Mat(points.Length, 2, MatType.CV_32FC1, points); var resMat = new Mat(responses.Length, 1, MatType.CV_32SC1, responses); using (var svm = new CvSVM()) { // normalize data dataMat /= 300.0; var criteria = TermCriteria.Both(1000, 0.000001); var param = new CvSVMParams( SVMType.CSvc, SVMKernelType.Rbf, 100.0, // degree 100.0, // gamma 1.0, // coeff0 1.0, // c 0.5, // nu 0.1, // p null, criteria); svm.Train(dataMat, resMat, null, null, param); // Predict for each 300x300 pixel using (Mat retPlot = Mat.Zeros(300, 300, MatType.CV_8UC3)) { for (int x = 0; x < 300; x++) { for (int y = 0; y < 300; y++) { float[] sample = { x / 300f, y / 300f }; var sampleMat = new CvMat(1, 2, MatrixType.F32C1, sample); int ret = (int)svm.Predict(sampleMat); var plotRect = new CvRect(x, 300 - y, 1, 1); if (ret == 1) { retPlot.Rectangle(plotRect, Scalar.Red); } else if (ret == 2) { retPlot.Rectangle(plotRect, Scalar.GreenYellow); } } } Window.ShowImages(retPlot); } } }
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 } }