private float classifyShape(Mat shape, CvSVM svm) { 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(shape, new OpenCvSharp.CPlusPlus.Size(16, 16), new OpenCvSharp.CPlusPlus.Size(0, 0), null); hog.Dispose(); Mat featureMat = new Mat(1, features.Length, MatType.CV_32FC1, features); float prediction = svm.Predict(featureMat.ToCvMat()); featureMat.Dispose(); return(prediction); }
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); } } }
/// <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(); }