OpencvSharp SVM实现汉字识别

1.准备训练数据与标签

2.训练SVM模型、保存

//训练SVM分类器
void TrainSVM()
{
    Mat train_img = new Mat(@"C:\\Users\\HJ\\Desktop\\OCR.bmp");

    Mat traindata = new Mat();
    Mat trainlabel = new Mat();
    //------------------------图像预处理-------------------------------
    Mat graymat = new Mat();
    Cv2.CvtColor(train_img,graymat,ColorConversionCodes.BGR2GRAY); //转灰度图
    //Cv2.ImShow("gray_img",graymat);

    Mat blurImg = new Mat();
    Cv2.GaussianBlur(graymat,blurImg,new OpenCvSharp.Size(5,5),0); //高斯滤波
    //Cv2.ImShow("blurImg", blurImg);

     Mat _dilate = new Mat();
     Mat element =  Cv2.GetStructuringElement(MorphShapes.Rect,new OpenCvSharp.Size(11,11),new CVPoint(-1,-1));
    Cv2.Erode(graymat, _dilate, element); //形态学处理-腐蚀
    //Cv2.ImShow("_dilate", _dilate);

    Mat binImg = new Mat();
    Cv2.Threshold(_dilate, binImg,0,255,ThresholdTypes.BinaryInv|ThresholdTypes.Otsu); //二值化
    //Cv2.ImShow("binImg", binImg);

    CVPoint[][] contours = new CVPoint[][] { };
    HierarchyIndex[] hierarchy = new HierarchyIndex[] { };
    Cv2.FindContours(binImg,out contours, out hierarchy,RetrievalModes.External,ContourApproximationModes.ApproxSimple); //提取字符
                                    
    List<int> labels = new List<int>() { 51894, 45794, 45552,51924,47099,55254};//汉字国标码十六进制转十进制
   
    for (int i = 0; i < contours.Length; i++)
    {
        if (Cv2.ContourArea(contours[i])>10)
        {
            Rect rect = Cv2.BoundingRect(contours[i]);
            Cv2.Rectangle(train_img,rect,new Scalar(0,255,0),2);
            Mat ROI = new Mat(train_img,rect);
            Cv2.ImShow($"ROI{i}", ROI);

          ;
            Mat resizemat = new Mat();
            Cv2.Resize(ROI, resizemat, new OpenCvSharp.Size(30,30)); //统一单个字符图像大小


           Mat _floatmat = new Mat();
            resizemat.ConvertTo(_floatmat,MatType.CV_32FC1);//traindata接收CV_32FC1,数据转换
         

            traindata.PushBack(_floatmat.Reshape(1,1)); //添加训练数据
            trainlabel.PushBack(labels[i]); //添加对应的标签
        }
    }
    traindata.ConvertTo(traindata,MatType.CV_32FC1);
    trainlabel.ConvertTo(trainlabel,MatType.CV_32SC1); //SVM接收的标签数据类型为CV_32SC1
  
    SVM sVM = SVM.Create(); //创建SVM
    sVM.Type = SVM.Types.CSvc; //设定type
    sVM.KernelType = SVM.KernelTypes.Linear; //设定内核type
    sVM.Train(traindata,SampleTypes.RowSample,trainlabel); //训练
    sVM.Save("model.xml"); //保存模型

}

3.加载SVM模型、预测验证模型

void Predict()
{

   Mat test_Img = new Mat("C:\\Users\\HJ\\Desktop\\TestOCR.bmp"); //读取测试图像
 
   SVM svm = SVM.Load("model.xml");


  //图像预处理
  Mat graymat = new Mat();
  Cv2.CvtColor(test_Img, graymat, ColorConversionCodes.BGR2GRAY); //转灰度图


  Mat blurImg = new Mat();
  Cv2.GaussianBlur(graymat, blurImg, new OpenCvSharp.Size(5, 5), 0); //高斯滤波


  Mat _dilate = new Mat();
  Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(13, 11), new CVPoint(-1, -1));
  Cv2.Erode(graymat, _dilate, element); //腐蚀
  

  Mat binImg = new Mat();
  Cv2.Threshold(_dilate, binImg, 200, 255, ThresholdTypes.BinaryInv); //二值化

  CVPoint[][] contours = new CVPoint[][] { };
  HierarchyIndex[] hierarchy = new HierarchyIndex[] { };
  Cv2.FindContours(binImg, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); //提取字符

  for (int i = 0; i < contours.Length; i++)
  {
      Rect rect = Cv2.BoundingRect(contours[i]);
      Cv2.Rectangle(test_Img,rect,new Scalar(0,0,255),2);
      Mat ROI = new Mat(test_Img,rect);
      Mat resize = new Mat();
      Cv2.Resize(ROI,resize,new OpenCvSharp.Size(30,30)); //统一每个字符的图像大小
      Mat roifloat = new Mat();
      resize.ConvertTo(roifloat,MatType.CV_32FC1);

      roifloat = roifloat.Reshape(1,1);
      float f = svm.Predict(roifloat); //预测字符

      string character = "";
      //转汉字
      string hanzi = "";
      string s = ((int)f).ToString("X");
      byte[] b = strToToHexByte(s);
      hanzi = GBCode2Chinese2GBCode.BytesToString(b);

      switch (f) //Cv2.PutText()无法显示中文,暂时用拼音代替
      {
          case 47099:
              character = "fu";                  
              break;
          case 55254:
              character = "zi";
              break;
          case 51894:
              character = "shi";
              break;
          case 45552:
              character = "bie";
              break;
          case 45794:
              character = "ce";
              break;
          case 51924:
              character = "shi";
              break;
          default:
              character = "NUll";
              break;
      }

      double scale = rect.Width * 0.02;
      Cv2.PutText(test_Img, character, rect.BottomRight,HersheyFonts.HersheySimplex,scale,new Scalar(0,255,0),2);
      Cv2.ImShow("test_img",test_Img);

}

预测结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HeliosXxzh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值