PaddleSharpAPI.cs 7.7 KB
using log4net;
using PaddleOCRSharp;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;

namespace paddleOCR
{
    internal class PaddleSharpAPI
    {
        static PaddleOCREngine engine;
        static string baseDir = ".\\LabelOut\\";

        public static void Init()
        {
            //自带轻量版中英文模型V3模型
            OCRModelConfig config = null;

            //服务器中英文模型
            //OCRModelConfig config = new OCRModelConfig();
            //string root = System.IO.Path.GetDirectoryName(typeof(OCRModelConfig).Assembly.Location);
            //string modelPathroot = root + @"\inferenceserver";
            //config.det_infer = modelPathroot + @"\ch_ppocr_server_v2.0_det_infer";
            //config.cls_infer = modelPathroot + @"\ch_ppocr_mobile_v2.0_cls_infer";
            //config.rec_infer = modelPathroot + @"\ch_ppocr_server_v2.0_rec_infer";
            //config.keys = modelPathroot + @"\ppocr_keys.txt";

            //英文和数字模型V3
            //OCRModelConfig config = new OCRModelConfig();
            //string root = System.IO.Path.GetDirectoryName(typeof(OCRModelConfig).Assembly.Location);
            //string modelPathroot = root + @"\en_v3";
            //config.det_infer = modelPathroot + @"\en_PP-OCRv3_det_infer";
            //config.cls_infer = modelPathroot + @"\ch_ppocr_mobile_v2.0_cls_infer";
            //config.rec_infer = modelPathroot + @"\en_PP-OCRv3_rec_infer";
            //config.keys = modelPathroot + @"\en_dict.txt";


            //OCR参数
            OCRParameter oCRParameter = new OCRParameter();
            oCRParameter.numThread = 6;//预测并发线程数
            oCRParameter.Enable_mkldnn = true;//web部署该值建议设置为0,否则出错,内存如果使用很大,建议该值也设置为0.
            oCRParameter.cls = false; //是否执行文字方向分类;默认false
            oCRParameter.det = true;//是否开启方向检测,用于检测识别180旋转
            oCRParameter.use_angle_cls = true;//是否开启方向检测,用于检测识别180旋转
            oCRParameter.det_db_score_mode = true;//是否使用多段线,即文字区域是用多段线还是用矩形,
            oCRParameter.UnClipRatio = 1.6f;
            oCRParameter.MaxSideLen = 960;
            //初始化OCR引擎
            engine = new PaddleOCREngine(config, oCRParameter);

        }
        static ILog log = VisionAPI.log;
        static System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        public static bool OCRHandle(string imgPath, out string result)
        {
            result = "";
            sw.Restart();
            if (string.IsNullOrEmpty(imgPath))
            {
                return false;
            }
            if (Directory.Exists(baseDir))
            {
                Directory.Delete(baseDir, true);
            }
            Directory.CreateDirectory(baseDir);


            EyemImage image = new EyemImage();
            EyemImage tpDstImg = new EyemImage();
            int flag;
            log.Info($"准备读取图像:{imgPath}");
            flag = VisionAPI.eyemImageRead(imgPath, -1, out image);
            log.Info($"读取图像:{imgPath},rtnCode={flag}");
            ///实例分割
            ///
            {
                RotateBox container = new RotateBox();
                flag = VisionAPI.eyemNNInstanceSegment(image,0.15f, ref container, out tpDstImg);
                log.Info($"标签分割完成,rtncode={flag}");
                Bitmap b = VisionAPI.eyemCvtToBitmap(tpDstImg);
                log.Info($"转换为Bitmap");
                b?.Save($"labelSplit.jpg", ImageFormat.Jpeg);
                log.Info($"保存分割结果图:labelSplit.jpg");
                VisionAPI.eyemImageFree(ref tpDstImg);
                for (int i = 0; i < 25; i++)
                {

                    EyemImage tpDstImg1 = new EyemImage();
                    if (i < container.p1.Length && container.p1[i].iX != 0)
                    {
                        flag = VisionAPI.eyemAchvRotateImage(image, container.p1[i], container.p2[i], container.p3[i], container.p4[i], out tpDstImg1);
                        //if (flag == 0)
                        {
                            if (!Directory.Exists($"{baseDir}label{i}"))
                                Directory.CreateDirectory($"{baseDir}label{i}");
                            Bitmap lbl = VisionAPI.eyemCvtToBitmap(tpDstImg1);
                            lbl?.Save($"{baseDir}label{i}\\1.jpg", ImageFormat.Jpeg);
                            lbl?.RotateFlip(RotateFlipType.Rotate180FlipNone);
                            lbl?.Save($"{baseDir}label{i}\\2.jpg", ImageFormat.Jpeg);
                            log.Info($"获取标签图像并保存:{baseDir}label{i}");
                        }
                        VisionAPI.eyemImageFree(ref tpDstImg1);
                    }

                }
                VisionAPI.eyemImageFree(ref image);
            }
            log.Info($"分隔标签耗时:{sw.ElapsedMilliseconds}ms");
            sw.Restart();
            DirectoryInfo directoryInfo = new DirectoryInfo(baseDir);
            var files = directoryInfo.GetDirectories();
            if (files != null && files.Length == 0)
            {
                if (!Directory.Exists($"{baseDir}label"))
                    Directory.CreateDirectory($"{baseDir}label");
                log.Info($"无分割的标签,将原图传入名为label.jpg");
                byte[] bytes;
                using (FileStream fs = new FileStream(imgPath, FileMode.Open))
                {
                    bytes = new byte[fs.Length];
                    fs.Read(bytes, 0, bytes.Length);
                }
                MemoryStream memoryStream = new MemoryStream(bytes);
                Bitmap bitmap = new Bitmap(memoryStream);
                bitmap.Save($"{baseDir}label\\label.jpg");
            }
            log.Info($"开始OCR识别");
            StringBuilder stringBuilder = new StringBuilder();
            foreach (var dir in directoryInfo.GetDirectories())
            {
                Dictionary<float,StringBuilder> pairs = new Dictionary<float, StringBuilder>();
                foreach (var item in dir.GetFiles())
                {
                    float score = 0f;
                    StringBuilder sb = new StringBuilder();
                    var imagebyte = File.ReadAllBytes(item.FullName);
                    var res = engine.DetectText(imagebyte);
                    foreach (var text in res.TextBlocks)
                    {
                        score += text.Score;
                        sb.AppendLine(text.Text);
                    }
                    pairs.Add(score, sb);
                    log.Info($"【{item.FullName}】识别结果:【{score}】【{sb.ToString().Replace("\r","").Replace("\n",";")}】");
                }
                float key = pairs.Keys.Max();
                stringBuilder.Append(pairs[key].ToString());
                log.Info($"使用识别分数【{key}】");
            }
            log.Info($"OCR识别完成");
            sw.Stop();
            log.Info("识别耗时:" + sw.ElapsedMilliseconds.ToString() + "ms");
            string[] strs = stringBuilder.ToString().Replace(":\r", ":").Replace("\r", "").Split('\n');
            foreach (string str in strs)
            {
                if (string.IsNullOrEmpty(str)) continue;
                result += str + ";";
            }
            if (result.EndsWith(";"))
            {
                result = result.Substring(0, result.Length - 1);
            }
            log.Info("识别结果:" + result);
            return true;
        }
    }
}