支持向量机手写数字识别案例(OpencvSharp)

支持向量机简介

支持向量机(Support Vector Machine,SVM)是一种二分类模型,目标时寻找一个标准(成为超平面)对样本数据进行分割,分割的原则是确保分类最优化(类别之间的间隔最大)。当数据集较小时,使用支持向量机进行分类非常有效。

在对原始数据分类的过程中,可能无法使用线性方法实现分割。支持向量机在分类时,把无法线性分割的数据映射到高维空间,然后再高维空间占到分类最优的线性分类器。

分类器

在已有数据中,找到距离分类器最近的点,确保他们离分类器尽可能的远。在这儿,离分类器最近的点到分类器的距离成为间隔(margin),都希望间隔尽可能地大,这样分类器在处理数据时,就会更准确。离分类器最近的那些点叫做支持向量(support vector),正是这些支持向量决定了分类器所在的位置。
支持向量机在处理数据时,如果在低维空间内无法完成分类,就自动将数据映射到高维空间,使其尽可能线性,简单而讲,就是对当前数据进行函数映射操作。

概念总结

支持向量机可以处理任何维度的数据,在不同的维度下,支持向量机都会尽可能寻找类似于二维空间中的直线分类器。
“支持向量”是离分类器最近的那些点,这些点位于最大“间隔上”。通常情况分类仅靠这些点完成,而与其他点无关。
“机器”指得是分类器。
综上所述,支持向量机是一种基于关键点的算法分类。

手写数字识别案例代码

本案例中训练数据机验证数据所选图像均从百度搜索,侵犯立删

 //支持向量机手写数字识别案例
                    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();
                    }

在这里插入图片描述
训练数据集(上述代码中未体现子图分割部分,同时还添加了一些excel中部分格式的数字图像数据)
在这里插入图片描述验证数据图像
在这里插入图片描述验证数据结果显示

总结

此次通过支持向量机对手写数字识别案例,对比之前通过knn近邻对手写数字识别进行对比发现,相对knn近邻算法,支持向量机在相同训练数据量情况下,所验证出的结果准确率较高一些。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值