Support vector machine handwritten digit recognition case (OpencvSharp)

Introduction to Support Vector Machines

Support Vector Machine (SVM) is a two-class classification model. The goal is to find a standard (called a hyperplane) to segment the sample data. The principle of segmentation is to ensure optimal classification (the largest interval between categories). Classification using support vector machines is very effective when the data set is small.

During the classification of raw data, segmentation may not be achieved using linear methods. When classifying, the support vector machine maps the data that cannot be linearly divided into a high-dimensional space, and then uses the high-dimensional space to obtain the optimal linear classifier for classification.

Classifier

In the existing data, find the points closest to the classifier and make sure they are as far away from the classifier as possible. Here, the distance from the point closest to the classifier to the classifier becomes the margin. We hope that the margin will be as large as possible, so that the classifier will be more accurate when processing the data. The points closest to the classifier are called support vectors, and it is these support vectors that determine the location of the classifier.
When the support vector machine processes data, if it cannot complete classification in the low-dimensional space, it will automatically map the data to the high-dimensional space to make it as linear as possible. Simply put, it is a function mapping operation on the current data.

Concept summary

Support vector machines can process data of any dimension. In different dimensions, support vector machines will try their best to find a straight line classifier similar to that in two-dimensional space.
"Support vectors" are those points closest to the classifier that lie "on the maximum margin". Usually the classification is done only by these points and has nothing to do with other points.
"Machine" refers to the classifier.
To sum up, support vector machine is an algorithm classification based on key points.

Handwritten digit recognition case code

In this case, the images selected for the training data machine verification data are all searched from Baidu, and any infringement will be deleted immediately.

 //支持向量机手写数字识别案例
                    Mat trainData = new Mat(0, 0, MatType.CV_32FC1);
                    Mat trainLabel = new Mat(0, 0, MatType.CV_32SC1);
                    Mat validData = new Mat(0, 0, MatType.CV_32FC1);
                    float[] validActual;
                    const int boundWidth = 100, boundHeight = 100;
                    string trainPath = @"D:\Jay.Lee\Study\imgs\KNEARTESTIMG\numberSubImgs\numberSubImgs";
                    string validPath = @"D:\Jay.Lee\Study\imgs\KNEARTESTIMG\test.png";
                    //训练数据集收集
                    //训练数据标签集收集
                    for(int i = 0; i < 10; i++)
                    {
    
    
                        for(int j = 0; j < 32; j++)
                        {
    
    
                            //图像获取
                            Mat temp = new Mat(trainPath + $"{
      
      i}_{
      
      j}.png", ImreadModes.Grayscale);
                            temp = temp.Threshold(0, 255, ThresholdTypes.Otsu);
                            //数据转成单行
                            temp = temp.Reshape(0, 1).Normalize(0,1,NormTypes.MinMax);
                            //数据转型float
                            temp.ConvertTo(temp, MatType.CV_32FC1);
                            //数据添加到训练数据集中
                            trainData.PushBack(temp);
                            //数据对应标签添加到训练数据标签中
                            trainLabel.PushBack(Mat.Ones(1, 1, MatType.CV_32SC1) * i);
                        }
                    }
                    //验证数据集收集
                    //验证数据实际值
                    //验证图像获取
                    Mat validImg =new Mat(validPath);
                    //验证图像取反
                    Mat validCp =255- validImg.CvtColor(ColorConversionCodes.BGR2GRAY);
                    //验证图像取二值
                    validCp = validCp.Threshold(0, 255, ThresholdTypes.Otsu);
                    //验证图像找轮廓对应子图
                    validCp.FindContours(out Point[][] vCnts, out HierarchyIndex[] hiers, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
                    vCnts = vCnts.ToList().Where(cnt => Cv2.ContourArea(cnt) > 5 && Cv2.ArcLength(cnt, false) > 5).OrderBy(cnt => Cv2.BoundingRect(cnt).X).ToArray();
                    int validNums = vCnts.Length;
                    validActual = new float[] {
    
     0, 5, 2, 2, 1, 8, 5, 9 };
                    for(int i = 0; i < validNums; i++)
                    {
    
    
                        //获取手写数字边界矩形
                        Mat temp = validCp[Cv2.BoundingRect(vCnts[i])];
                        //验证数据转单行
                        temp = temp.Resize(new Size(boundWidth,boundHeight)).Normalize(0, 1, NormTypes.MinMax).Reshape(0, 1);
                        //验证数据转float
                        temp.ConvertTo(temp, MatType.CV_32FC1);
                        //验证数据转到总验证数据集中
                        validData.PushBack(temp);
                    }
                    //支持向量机创建&&训练&&验证
                    using (var svm = OpenCvSharp.ML.SVM.Create())
                    {
    
    
                        //支持向量机核算法类型选择-poly
                        svm.KernelType = OpenCvSharp.ML.SVM.KernelTypes.Poly;
                        svm.Degree = 0.7;
                        //支持向量机训练
                        svm.Train(trainData, OpenCvSharp.ML.SampleTypes.RowSample, trainLabel);
                        Mat svmResult = new Mat();
                        //支持向量机验证机结果获取
                        svm.Predict(validData, svmResult);
                        //验证结果&实际值显示
                        for(int i = 0; i < svmResult.Rows; i++)
                        {
    
    
                            string annotation = $"VV:{
      
      ((float*)svmResult.Ptr(i))[0]}" +
                                $" AV:{
      
      validActual[i]}";
                            Rect boundRect = Cv2.BoundingRect(vCnts[i]);
                            Point position = new Point(boundRect.X, boundRect.Y);
                            validImg.PutText(annotation, position, HersheyFonts.HersheySimplex, 0.5, Scalar.Red, thickness: 2);
                        }
                        Cv2.ImShow("validResult", validImg);
                        Cv2.WaitKey();
                    }

Insert image description here
Training data set (the subgraph segmentation part is not reflected in the above code, and some digital image data in some formats in excel are also added)
Insert image description hereVerification data image
Insert image description hereverification data results display

Summarize

This time, the case of handwritten digit recognition through support vector machine was compared with the previous handwritten digit recognition through knn nearest neighbor. It was found that compared with the knn nearest neighbor algorithm, the support vector machine has a higher accuracy of verified results under the same amount of training data. Some.

Guess you like

Origin blog.csdn.net/JAYLEE900/article/details/131569676