当前位置:   article > 正文

C# PaddleInference OCR文字识别(只识别)_c# ocr识别

c# ocr识别

目录

说明

效果

项目

测试图片

代码

下载 


说明

C# PaddleInference OCR文字识别(只识别),没有文字区域检测、文字方向判断

测试图片是文字区域检测裁剪出来、处理过的图片

完整的OCR识别查看 C# PaddleInference OCR识别 学习研究Demo_天天代码码天天的博客-CSDN博客

效果

项目

VS2022+.net4.8+OpenCvSharp4+Sdcb.PaddleInference

测试图片

代码

using OpenCvSharp;
using Sdcb.PaddleInference;
using Sdcb.PaddleInference.Native;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace PaddleInference_OCR文字识别
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Bitmap bmp;
        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string img = "";
        string startupPath = "";

        OcrShape recShape = new OcrShape(3, 320, 48);
        PaddlePredictor rec_predictor;

        public IReadOnlyList<string> Labels;

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;


        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;

            img = ofd.FileName;
            bmp = new Bitmap(img);
            pictureBox1.Image = new Bitmap(img);
            textBox1.Text = "";
        }

        private unsafe void Form1_Load(object sender, EventArgs e)
        {

            string startupPath = Application.StartupPath;
            IntPtr det_ptr = PaddleNative.PD_ConfigCreate();
            Encoding PaddleEncoding = Environment.OSVersion.Platform == PlatformID.Win32NT ? Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) : Encoding.UTF8;

            //识别模型
            IntPtr rec_ptr = PaddleNative.PD_ConfigCreate();
            String rec_programPath = startupPath + "\\ch_PP-OCRv3_rec\\inference.pdmodel";
            String rec_paramsPath = startupPath + "\\ch_PP-OCRv3_rec\\inference.pdiparams";
            byte[] rec_programBytes = PaddleEncoding.GetBytes(rec_programPath);
            byte[] rec_paramsBytes = PaddleEncoding.GetBytes(rec_paramsPath);
            fixed (byte* rec_programPtr = rec_programBytes)
            fixed (byte* rec_paramsPtr = rec_paramsBytes)
            {
                PaddleNative.PD_ConfigSetModel(rec_ptr, (IntPtr)rec_programPtr, (IntPtr)rec_paramsPtr);
            }

            rec_predictor = new PaddlePredictor(PaddleNative.PD_PredictorCreate(rec_ptr));

            //Labels
            String labelsPath = startupPath + "\\ppocr_keys.txt";
            Stream Steam = new FileStream(labelsPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            StreamReader reader = new StreamReader(Steam);
            List<string> tempList = new List<string>();
            while (!reader.EndOfStream)
            {
                tempList.Add(reader.ReadLine());
            }
            reader.Dispose();
            Steam.Dispose();
            Labels = tempList;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null)
            {
                return;
            }
            dt1 = DateTime.Now;
            var src = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);

            int modelHeight = recShape.Height;
            int maxWidth = (int)Math.Ceiling(1.0 * src.Width / src.Height * modelHeight);

            Mat channel3 = new Mat();
            if (src.Channels() == 4)
            {
                channel3 = src.CvtColor(ColorConversionCodes.RGBA2BGR);
            }
            else if (src.Channels() == 3)
            {
                channel3 = src.Clone();
            }
            else if (src.Channels() == 1)
            {
                channel3 = src.CvtColor(ColorConversionCodes.GRAY2RGB);
            }
            else
            {
                throw new Exception("Unexpect src channel: {" + src.Channels() + "}, allow: (1/3/4)");
            }

            Mat resized = ResizePadding(channel3, modelHeight, maxWidth);
            Mat normalize = Normalize(resized);

            using (PaddleTensor input = rec_predictor.GetInputTensor(rec_predictor.InputNames[0]))
            {
                int channel = normalize.Channels();
                input.Shape = new[] { 1, channel, modelHeight, maxWidth };
                float[] data = ExtractMat(normalize, channel, modelHeight, maxWidth);
                input.SetData(data);
            }

            normalize.Dispose();
            resized.Dispose();

            if (!rec_predictor.Run())
            {
                throw new Exception($"PaddlePredictor(Recognizer) run failed.");
            }

            using (PaddleTensor output = rec_predictor.GetOutputTensor(rec_predictor.OutputNames[0]))
            {
                float[] data = output.GetData<float>();
                int[] shape = output.Shape;
                GCHandle dataHandle = default;
                try
                {
                    dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                    IntPtr dataPtr = dataHandle.AddrOfPinnedObject();

                    int labelCount = shape[2];
                    int charCount = shape[1];

                    StringBuilder sbInfo = new StringBuilder();

                    for (int i = 0; i < shape[0]; i++)
                    {
                        StringBuilder sb = new StringBuilder();
                        int lastIndex = 0;
                        float score = 0;
                        for (int n = 0; n < charCount; ++n)
                        {
                            Mat mat = new Mat(1, labelCount, MatType.CV_32FC1, dataPtr + (n + i * charCount) * labelCount * sizeof(float));
                            int[] maxIdx = new int[2];
                            mat.MinMaxIdx(out double _, out double maxVal, new int[0], maxIdx);
                            if (maxIdx[1] > 0 && (!(n > 0 && maxIdx[1] == lastIndex)))
                            {
                                score += (float)maxVal;
                                sb.Append(GetLabelByIndex(maxIdx[1]));
                            }
                            lastIndex = maxIdx[1];
                            mat.Dispose();
                        }
                        sbInfo.AppendLine("Text:" + sb.ToString());
                        sbInfo.AppendLine("Score:" + score / sb.Length);
                    }

                    dt2 = DateTime.Now;
                    sbInfo.AppendLine("-----------------------------------\n");
                    sbInfo.AppendLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                    sbInfo.AppendLine("耗时:" + (dt2 - dt1).TotalMilliseconds + "ms\n");
                    textBox1.Text = sbInfo.ToString();
                }
                finally
                {
                    dataHandle.Free();
                }
            }

        }

        string GetLabelByIndex(int x)
        {
            if (x > 0 && x <= Labels.Count)
            {
                return Labels[x - 1];
            }
            else if (x == Labels.Count + 1)
            {
                return "";
            }
            else
            {
                throw new Exception("Unable to GetLabelByIndex: index {" + x + "} out of range {" + Labels.Count + "}, OCR model or labels not matched?");
            }
        }

        private Mat ResizePadding(Mat src, int height, int targetWidth)
        {
            OpenCvSharp.Size size = src.Size();
            float whRatio = 1.0f * size.Width / size.Height;
            int width = (int)Math.Ceiling(height * whRatio);

            if (width == targetWidth)
            {
                return src.Resize(new OpenCvSharp.Size(width, height));
            }
            else
            {
                Mat resized = src.Resize(new OpenCvSharp.Size(width, height));
                return resized.CopyMakeBorder(0, 0, 0, targetWidth - width, BorderTypes.Constant, Scalar.Gray);
            }
        }

        private Mat Normalize(Mat src)
        {
            Mat normalized = new Mat();
            src.ConvertTo(normalized, MatType.CV_32FC3, 1.0 / 255);
            Mat[] bgr = normalized.Split();
            float[] scales = new[] { 1 / 0.229f, 1 / 0.224f, 1 / 0.225f };
            float[] means = new[] { 0.485f, 0.456f, 0.406f };
            for (int i = 0; i < bgr.Length; ++i)
            {
                bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 * scales[i], (0.0 - means[i]) * scales[i]);
            }
            normalized.Dispose();
            Mat dest = new Mat();
            Cv2.Merge(bgr, dest);
            foreach (Mat channel in bgr)
            {
                channel.Dispose();
            }
            return dest;
        }

        private float[] ExtractMat(Mat mat, int channel, int height, int width)
        {
            float[] result = new float[1 * channel * width * height];
            GCHandle resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
            IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
            try
            {

                Mat src = mat.Clone();
                if (src.Channels() != channel)
                {
                    throw new Exception($"src channel={src.Channels()}, expected {channel}");
                }
                for (int c = 0; c < channel; ++c)
                {
                    Mat dest = new Mat(height, width, MatType.CV_32FC1, resultPtr + c * height * width * sizeof(float));
                    Cv2.ExtractChannel(src, dest, c);
                    dest.Dispose();
                }
                return result;
            }
            finally
            {
                resultHandle.Free();
            }
        }

        private float[] ExtractMat(Mat[] srcs, int channel, int height, int width)
        {
            float[] result = new float[srcs.Length * channel * width * height];
            GCHandle resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
            IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
            try
            {
                for (int i = 0; i < srcs.Length; ++i)
                {
                    Mat src = srcs[i];
                    if (src.Channels() != channel)
                    {
                        throw new Exception($"src[{i}] channel={src.Channels()}, expected {channel}");
                    }
                    for (int c = 0; c < channel; ++c)
                    {
                        Mat dest = new Mat(height, width, MatType.CV_32FC1, resultPtr + (c + i * channel) * height * width * sizeof(float));
                        Cv2.ExtractChannel(src, dest, c);
                        dest.Dispose();
                    }
                }
                return result;
            }
            finally
            {
                resultHandle.Free();
            }
        }

    }
}
 

  1. using OpenCvSharp;
  2. using Sdcb.PaddleInference;
  3. using Sdcb.PaddleInference.Native;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Windows.Forms;
  12. namespace PaddleInference_OCR文字识别
  13. {
  14. public partial class Form1 : Form
  15. {
  16. public Form1()
  17. {
  18. InitializeComponent();
  19. }
  20. Bitmap bmp;
  21. string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
  22. string img = "";
  23. string startupPath = "";
  24. OcrShape recShape = new OcrShape(3, 320, 48);
  25. PaddlePredictor rec_predictor;
  26. public IReadOnlyList<string> Labels;
  27. DateTime dt1 = DateTime.Now;
  28. DateTime dt2 = DateTime.Now;
  29. private void button1_Click(object sender, EventArgs e)
  30. {
  31. OpenFileDialog ofd = new OpenFileDialog();
  32. ofd.Filter = fileFilter;
  33. if (ofd.ShowDialog() != DialogResult.OK) return;
  34. pictureBox1.Image = null;
  35. img = ofd.FileName;
  36. bmp = new Bitmap(img);
  37. pictureBox1.Image = new Bitmap(img);
  38. textBox1.Text = "";
  39. }
  40. private unsafe void Form1_Load(object sender, EventArgs e)
  41. {
  42. string startupPath = Application.StartupPath;
  43. IntPtr det_ptr = PaddleNative.PD_ConfigCreate();
  44. Encoding PaddleEncoding = Environment.OSVersion.Platform == PlatformID.Win32NT ? Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) : Encoding.UTF8;
  45. //识别模型
  46. IntPtr rec_ptr = PaddleNative.PD_ConfigCreate();
  47. String rec_programPath = startupPath + "\\ch_PP-OCRv3_rec\\inference.pdmodel";
  48. String rec_paramsPath = startupPath + "\\ch_PP-OCRv3_rec\\inference.pdiparams";
  49. byte[] rec_programBytes = PaddleEncoding.GetBytes(rec_programPath);
  50. byte[] rec_paramsBytes = PaddleEncoding.GetBytes(rec_paramsPath);
  51. fixed (byte* rec_programPtr = rec_programBytes)
  52. fixed (byte* rec_paramsPtr = rec_paramsBytes)
  53. {
  54. PaddleNative.PD_ConfigSetModel(rec_ptr, (IntPtr)rec_programPtr, (IntPtr)rec_paramsPtr);
  55. }
  56. rec_predictor = new PaddlePredictor(PaddleNative.PD_PredictorCreate(rec_ptr));
  57. //Labels
  58. String labelsPath = startupPath + "\\ppocr_keys.txt";
  59. Stream Steam = new FileStream(labelsPath, FileMode.Open, FileAccess.Read, FileShare.Read);
  60. StreamReader reader = new StreamReader(Steam);
  61. List<string> tempList = new List<string>();
  62. while (!reader.EndOfStream)
  63. {
  64. tempList.Add(reader.ReadLine());
  65. }
  66. reader.Dispose();
  67. Steam.Dispose();
  68. Labels = tempList;
  69. }
  70. private void button3_Click(object sender, EventArgs e)
  71. {
  72. if (pictureBox1.Image == null)
  73. {
  74. return;
  75. }
  76. dt1 = DateTime.Now;
  77. var src = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
  78. int modelHeight = recShape.Height;
  79. int maxWidth = (int)Math.Ceiling(1.0 * src.Width / src.Height * modelHeight);
  80. Mat channel3 = new Mat();
  81. if (src.Channels() == 4)
  82. {
  83. channel3 = src.CvtColor(ColorConversionCodes.RGBA2BGR);
  84. }
  85. else if (src.Channels() == 3)
  86. {
  87. channel3 = src.Clone();
  88. }
  89. else if (src.Channels() == 1)
  90. {
  91. channel3 = src.CvtColor(ColorConversionCodes.GRAY2RGB);
  92. }
  93. else
  94. {
  95. throw new Exception("Unexpect src channel: {" + src.Channels() + "}, allow: (1/3/4)");
  96. }
  97. Mat resized = ResizePadding(channel3, modelHeight, maxWidth);
  98. Mat normalize = Normalize(resized);
  99. using (PaddleTensor input = rec_predictor.GetInputTensor(rec_predictor.InputNames[0]))
  100. {
  101. int channel = normalize.Channels();
  102. input.Shape = new[] { 1, channel, modelHeight, maxWidth };
  103. float[] data = ExtractMat(normalize, channel, modelHeight, maxWidth);
  104. input.SetData(data);
  105. }
  106. normalize.Dispose();
  107. resized.Dispose();
  108. if (!rec_predictor.Run())
  109. {
  110. throw new Exception($"PaddlePredictor(Recognizer) run failed.");
  111. }
  112. using (PaddleTensor output = rec_predictor.GetOutputTensor(rec_predictor.OutputNames[0]))
  113. {
  114. float[] data = output.GetData<float>();
  115. int[] shape = output.Shape;
  116. GCHandle dataHandle = default;
  117. try
  118. {
  119. dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
  120. IntPtr dataPtr = dataHandle.AddrOfPinnedObject();
  121. int labelCount = shape[2];
  122. int charCount = shape[1];
  123. StringBuilder sbInfo = new StringBuilder();
  124. for (int i = 0; i < shape[0]; i++)
  125. {
  126. StringBuilder sb = new StringBuilder();
  127. int lastIndex = 0;
  128. float score = 0;
  129. for (int n = 0; n < charCount; ++n)
  130. {
  131. Mat mat = new Mat(1, labelCount, MatType.CV_32FC1, dataPtr + (n + i * charCount) * labelCount * sizeof(float));
  132. int[] maxIdx = new int[2];
  133. mat.MinMaxIdx(out double _, out double maxVal, new int[0], maxIdx);
  134. if (maxIdx[1] > 0 && (!(n > 0 && maxIdx[1] == lastIndex)))
  135. {
  136. score += (float)maxVal;
  137. sb.Append(GetLabelByIndex(maxIdx[1]));
  138. }
  139. lastIndex = maxIdx[1];
  140. mat.Dispose();
  141. }
  142. sbInfo.AppendLine("Text:" + sb.ToString());
  143. sbInfo.AppendLine("Score:" + score / sb.Length);
  144. }
  145. dt2 = DateTime.Now;
  146. sbInfo.AppendLine("-----------------------------------\n");
  147. sbInfo.AppendLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
  148. sbInfo.AppendLine("耗时:" + (dt2 - dt1).TotalMilliseconds + "ms\n");
  149. textBox1.Text = sbInfo.ToString();
  150. }
  151. finally
  152. {
  153. dataHandle.Free();
  154. }
  155. }
  156. }
  157. string GetLabelByIndex(int x)
  158. {
  159. if (x > 0 && x <= Labels.Count)
  160. {
  161. return Labels[x - 1];
  162. }
  163. else if (x == Labels.Count + 1)
  164. {
  165. return "";
  166. }
  167. else
  168. {
  169. throw new Exception("Unable to GetLabelByIndex: index {" + x + "} out of range {" + Labels.Count + "}, OCR model or labels not matched?");
  170. }
  171. }
  172. private Mat ResizePadding(Mat src, int height, int targetWidth)
  173. {
  174. OpenCvSharp.Size size = src.Size();
  175. float whRatio = 1.0f * size.Width / size.Height;
  176. int width = (int)Math.Ceiling(height * whRatio);
  177. if (width == targetWidth)
  178. {
  179. return src.Resize(new OpenCvSharp.Size(width, height));
  180. }
  181. else
  182. {
  183. Mat resized = src.Resize(new OpenCvSharp.Size(width, height));
  184. return resized.CopyMakeBorder(0, 0, 0, targetWidth - width, BorderTypes.Constant, Scalar.Gray);
  185. }
  186. }
  187. private Mat Normalize(Mat src)
  188. {
  189. Mat normalized = new Mat();
  190. src.ConvertTo(normalized, MatType.CV_32FC3, 1.0 / 255);
  191. Mat[] bgr = normalized.Split();
  192. float[] scales = new[] { 1 / 0.229f, 1 / 0.224f, 1 / 0.225f };
  193. float[] means = new[] { 0.485f, 0.456f, 0.406f };
  194. for (int i = 0; i < bgr.Length; ++i)
  195. {
  196. bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 * scales[i], (0.0 - means[i]) * scales[i]);
  197. }
  198. normalized.Dispose();
  199. Mat dest = new Mat();
  200. Cv2.Merge(bgr, dest);
  201. foreach (Mat channel in bgr)
  202. {
  203. channel.Dispose();
  204. }
  205. return dest;
  206. }
  207. private float[] ExtractMat(Mat mat, int channel, int height, int width)
  208. {
  209. float[] result = new float[1 * channel * width * height];
  210. GCHandle resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
  211. IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
  212. try
  213. {
  214. Mat src = mat.Clone();
  215. if (src.Channels() != channel)
  216. {
  217. throw new Exception($"src channel={src.Channels()}, expected {channel}");
  218. }
  219. for (int c = 0; c < channel; ++c)
  220. {
  221. Mat dest = new Mat(height, width, MatType.CV_32FC1, resultPtr + c * height * width * sizeof(float));
  222. Cv2.ExtractChannel(src, dest, c);
  223. dest.Dispose();
  224. }
  225. return result;
  226. }
  227. finally
  228. {
  229. resultHandle.Free();
  230. }
  231. }
  232. private float[] ExtractMat(Mat[] srcs, int channel, int height, int width)
  233. {
  234. float[] result = new float[srcs.Length * channel * width * height];
  235. GCHandle resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
  236. IntPtr resultPtr = resultHandle.AddrOfPinnedObject();
  237. try
  238. {
  239. for (int i = 0; i < srcs.Length; ++i)
  240. {
  241. Mat src = srcs[i];
  242. if (src.Channels() != channel)
  243. {
  244. throw new Exception($"src[{i}] channel={src.Channels()}, expected {channel}");
  245. }
  246. for (int c = 0; c < channel; ++c)
  247. {
  248. Mat dest = new Mat(height, width, MatType.CV_32FC1, resultPtr + (c + i * channel) * height * width * sizeof(float));
  249. Cv2.ExtractChannel(src, dest, c);
  250. dest.Dispose();
  251. }
  252. }
  253. return result;
  254. }
  255. finally
  256. {
  257. resultHandle.Free();
  258. }
  259. }
  260. }
  261. }

下载 

Demo下载

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/692794
推荐阅读
相关标签
  

闽ICP备14008679号