Пример #1
0
        /// <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
            }
        }