当前位置:   article > 正文

C# PaddleInference 文字检测(只检测不识别)_c# 全文错别字 检测

c# 全文错别字 检测

目录

效果

项目

代码

下载


效果

项目

代码

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

namespace PaddleInference_文字检测
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

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

        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);
        }


        int MaxSize = 1536;
        float? BoxThreshold = 0.3f;
        float? BoxScoreThreahold = 0.7f;
        int? DilatedSize = 2;
        int MinSize = 3;
        float UnclipRatio = 2.0f;
        PaddlePredictor predictor;
        private unsafe void Form1_Load(object sender, EventArgs e)
        {
            IntPtr _ptr = PaddleNative.PD_ConfigCreate();

            Encoding PaddleEncoding = Environment.OSVersion.Platform == PlatformID.Win32NT ? Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) : Encoding.UTF8;

            //设置推理模型路径
            String programPath = Application.StartupPath + "\\ch_PP-OCRv3_det\\inference.pdmodel";
            String paramsPath = Application.StartupPath + "\\ch_PP-OCRv3_det\\inference.pdiparams";

            byte[] programBytes = PaddleEncoding.GetBytes(programPath);
            byte[] paramsBytes = PaddleEncoding.GetBytes(paramsPath);
            fixed (byte* programPtr = programBytes)
            fixed (byte* paramsPtr = paramsBytes)
            {
                PaddleNative.PD_ConfigSetModel(_ptr, (IntPtr)programPtr, (IntPtr)paramsPtr);
            }

            predictor = new PaddlePredictor(PaddleNative.PD_PredictorCreate(_ptr));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (img == "")
            {
                return;
            }

            Mat src = Cv2.ImRead(img);

            Mat resized = MatResize(src, MaxSize);
            Mat padded = MatPadding32(resized);
            Mat normalized = Normalize(padded);
            OpenCvSharp.Size resizedSize = resized.Size();
            using (PaddleTensor input = predictor.GetInputTensor(predictor.InputNames[0]))
            {
                input.Shape = new[] { 1, 3, normalized.Rows, normalized.Cols };
                float[] setData = ExtractMat(normalized);
                input.SetData(setData);
            }

            if (!predictor.Run())
            {
                throw new Exception("PaddlePredictor(Detector) run failed.");
            }

            using (PaddleTensor output = predictor.GetOutputTensor(predictor.OutputNames[0]))
            {
                float[] data = output.GetData<float>();
                int[] shape = output.Shape;

                Mat pred = new Mat(shape[2], shape[3], MatType.CV_32FC1, data);
                Mat cbuf = new Mat();

                Mat roi = pred[0, resizedSize.Height, 0, resizedSize.Width];
                roi.ConvertTo(cbuf, MatType.CV_8UC1, 255);

                Mat dilated = new Mat();
                Mat binary = BoxThreshold != null ?
                   cbuf.Threshold((int)(BoxThreshold * 255), 255, ThresholdTypes.Binary) :
                   cbuf;

                if (DilatedSize != null)
                {
                    Mat ones = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(DilatedSize.Value, DilatedSize.Value));
                    Cv2.Dilate(binary, dilated, ones);
                    ones.Dispose();
                }
                else
                {
                    Cv2.CopyTo(binary, dilated);
                }

                OpenCvSharp.Point[][] contours = dilated.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxSimple);

                OpenCvSharp.Size size = src.Size();
                double scaleRate = 1.0 * src.Width / resizedSize.Width;

                RotatedRect[] rects = contours
                    .Where(x => BoxScoreThreahold == null || GetScore(x, pred) > BoxScoreThreahold)
                    .Select(x => Cv2.MinAreaRect(x))
                    .Where(x => x.Size.Width > MinSize && x.Size.Height > MinSize)
                    .Select(rect =>
                    {
                        float minEdge = Math.Min(rect.Size.Width, rect.Size.Height);
                        Size2f newSize = new Size2f(
                            (rect.Size.Width + UnclipRatio * minEdge) * scaleRate,
                            (rect.Size.Height + UnclipRatio * minEdge) * scaleRate);
                        RotatedRect largerRect = new RotatedRect(rect.Center * scaleRate, newSize, rect.Angle);
                        return largerRect;
                    })
                    .OrderBy(v => v.Center.Y)
                    .ThenBy(v => v.Center.X)
                    .ToArray();

                src.Dispose();
                binary.Dispose();
                roi.Dispose();
                cbuf.Dispose();
                pred.Dispose();
                dilated.Dispose();

                //绘图
                Mat src2 = Cv2.ImRead(img);
                for (int i = 0; i < rects.Length; i++)
                {
                    Scalar scalar = Scalar.RandomColor();
                    List<OpenCvSharp.Point> temp = new List<OpenCvSharp.Point>();
                    foreach (var item2 in rects[i].Points())
                    {
                        temp.Add(new OpenCvSharp.Point(item2.X, item2.Y));
                    }
                    List<List<OpenCvSharp.Point>> lltemp = new List<List<OpenCvSharp.Point>>();
                    lltemp.Add(temp);
                    Cv2.Polylines(src2, lltemp, true, scalar);
                }

                if (pictureBox1.Image!=null)
                {
                    pictureBox1.Image.Dispose();
                }

                pictureBox1.Image = BitmapConverter.ToBitmap(src2);
                src2.Dispose();

            }
        }

        private float GetScore(OpenCvSharp.Point[] contour, Mat pred)
        {
            int width = pred.Width;
            int height = pred.Height;
            int[] boxX = contour.Select(v => v.X).ToArray();
            int[] boxY = contour.Select(v => v.Y).ToArray();

            int xmin = Clamp(boxX.Min(), 0, width - 1);
            int xmax = Clamp(boxX.Max(), 0, width - 1);
            int ymin = Clamp(boxY.Min(), 0, height - 1);
            int ymax = Clamp(boxY.Max(), 0, height - 1);

            OpenCvSharp.Point[] rootPoints = contour
                .Select(v => new OpenCvSharp.Point(v.X - xmin, v.Y - ymin))
                .ToArray();
            Mat mask = new Mat(ymax - ymin + 1, xmax - xmin + 1, MatType.CV_8UC1, Scalar.Black);
            mask.FillPoly(new[] { rootPoints }, new Scalar(1));

            Mat croppedMat = pred[ymin, ymax + 1, xmin, xmax + 1];
            float score = (float)croppedMat.Mean(mask).Val0;
            return score;
        }

        public int Clamp(int val, int min, int max)
        {
            if (val < min)
            {
                return min;
            }
            else if (val > max)
            {
                return max;
            }
            return val;
        }

        float[] ExtractMat(Mat src)
        {
            int rows = src.Rows;
            int cols = src.Cols;
            float[] array = new float[rows * cols * 3];
            GCHandle gCHandle = default(GCHandle);
            try
            {
                gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
                IntPtr intPtr = gCHandle.AddrOfPinnedObject();
                for (int i = 0; i < src.Channels(); i++)
                {
                    Mat dest = new Mat(rows, cols, MatType.CV_32FC1, intPtr + i * rows * cols * 4, 0L);
                    Cv2.ExtractChannel(src, dest, i);
                    dest.Dispose();
                }
                return array;
            }
            finally
            {
                gCHandle.Free();
            }
        }

        private Mat MatResize(Mat src, int? maxSize)
        {
            if (maxSize == null) return src.Clone();

            OpenCvSharp.Size size = src.Size();
            int longEdge = Math.Max(size.Width, size.Height);
            double scaleRate = 1.0 * maxSize.Value / longEdge;

            return scaleRate < 1.0 ?
                src.Resize(OpenCvSharp.Size.Zero, scaleRate, scaleRate) :
                src.Clone();
        }

        private Mat MatPadding32(Mat src)
        {
            OpenCvSharp.Size size = src.Size();
            OpenCvSharp.Size newSize = new OpenCvSharp.Size(
                32 * Math.Ceiling(1.0 * size.Width / 32),
                32 * Math.Ceiling(1.0 * size.Height / 32));

            return src.CopyMakeBorder(0, newSize.Height - size.Height, 0, newSize.Width - size.Width, BorderTypes.Constant, Scalar.Black);
        }

        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;
        }

    }
}

  1. using OpenCvSharp.Extensions;
  2. using OpenCvSharp;
  3. using Sdcb.PaddleInference.Native;
  4. using Sdcb.PaddleInference;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Data;
  8. using System.Drawing;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Windows.Forms;
  12. using System.Runtime.InteropServices;
  13. using System.Globalization;
  14. namespace PaddleInference_文字检测
  15. {
  16. public partial class Form1 : Form
  17. {
  18. public Form1()
  19. {
  20. InitializeComponent();
  21. }
  22. Bitmap bmp;
  23. string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
  24. string img = "";
  25. private void button1_Click(object sender, EventArgs e)
  26. {
  27. OpenFileDialog ofd = new OpenFileDialog();
  28. ofd.Filter = fileFilter;
  29. if (ofd.ShowDialog() != DialogResult.OK) return;
  30. pictureBox1.Image = null;
  31. img = ofd.FileName;
  32. bmp = new Bitmap(img);
  33. pictureBox1.Image = new Bitmap(img);
  34. }
  35. int MaxSize = 1536;
  36. float? BoxThreshold = 0.3f;
  37. float? BoxScoreThreahold = 0.7f;
  38. int? DilatedSize = 2;
  39. int MinSize = 3;
  40. float UnclipRatio = 2.0f;
  41. PaddlePredictor predictor;
  42. private unsafe void Form1_Load(object sender, EventArgs e)
  43. {
  44. IntPtr _ptr = PaddleNative.PD_ConfigCreate();
  45. Encoding PaddleEncoding = Environment.OSVersion.Platform == PlatformID.Win32NT ? Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) : Encoding.UTF8;
  46. //设置推理模型路径
  47. String programPath = Application.StartupPath + "\\ch_PP-OCRv3_det\\inference.pdmodel";
  48. String paramsPath = Application.StartupPath + "\\ch_PP-OCRv3_det\\inference.pdiparams";
  49. byte[] programBytes = PaddleEncoding.GetBytes(programPath);
  50. byte[] paramsBytes = PaddleEncoding.GetBytes(paramsPath);
  51. fixed (byte* programPtr = programBytes)
  52. fixed (byte* paramsPtr = paramsBytes)
  53. {
  54. PaddleNative.PD_ConfigSetModel(_ptr, (IntPtr)programPtr, (IntPtr)paramsPtr);
  55. }
  56. predictor = new PaddlePredictor(PaddleNative.PD_PredictorCreate(_ptr));
  57. }
  58. private void button2_Click(object sender, EventArgs e)
  59. {
  60. if (img == "")
  61. {
  62. return;
  63. }
  64. Mat src = Cv2.ImRead(img);
  65. Mat resized = MatResize(src, MaxSize);
  66. Mat padded = MatPadding32(resized);
  67. Mat normalized = Normalize(padded);
  68. OpenCvSharp.Size resizedSize = resized.Size();
  69. using (PaddleTensor input = predictor.GetInputTensor(predictor.InputNames[0]))
  70. {
  71. input.Shape = new[] { 1, 3, normalized.Rows, normalized.Cols };
  72. float[] setData = ExtractMat(normalized);
  73. input.SetData(setData);
  74. }
  75. if (!predictor.Run())
  76. {
  77. throw new Exception("PaddlePredictor(Detector) run failed.");
  78. }
  79. using (PaddleTensor output = predictor.GetOutputTensor(predictor.OutputNames[0]))
  80. {
  81. float[] data = output.GetData<float>();
  82. int[] shape = output.Shape;
  83. Mat pred = new Mat(shape[2], shape[3], MatType.CV_32FC1, data);
  84. Mat cbuf = new Mat();
  85. Mat roi = pred[0, resizedSize.Height, 0, resizedSize.Width];
  86. roi.ConvertTo(cbuf, MatType.CV_8UC1, 255);
  87. Mat dilated = new Mat();
  88. Mat binary = BoxThreshold != null ?
  89. cbuf.Threshold((int)(BoxThreshold * 255), 255, ThresholdTypes.Binary) :
  90. cbuf;
  91. if (DilatedSize != null)
  92. {
  93. Mat ones = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(DilatedSize.Value, DilatedSize.Value));
  94. Cv2.Dilate(binary, dilated, ones);
  95. ones.Dispose();
  96. }
  97. else
  98. {
  99. Cv2.CopyTo(binary, dilated);
  100. }
  101. OpenCvSharp.Point[][] contours = dilated.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxSimple);
  102. OpenCvSharp.Size size = src.Size();
  103. double scaleRate = 1.0 * src.Width / resizedSize.Width;
  104. RotatedRect[] rects = contours
  105. .Where(x => BoxScoreThreahold == null || GetScore(x, pred) > BoxScoreThreahold)
  106. .Select(x => Cv2.MinAreaRect(x))
  107. .Where(x => x.Size.Width > MinSize && x.Size.Height > MinSize)
  108. .Select(rect =>
  109. {
  110. float minEdge = Math.Min(rect.Size.Width, rect.Size.Height);
  111. Size2f newSize = new Size2f(
  112. (rect.Size.Width + UnclipRatio * minEdge) * scaleRate,
  113. (rect.Size.Height + UnclipRatio * minEdge) * scaleRate);
  114. RotatedRect largerRect = new RotatedRect(rect.Center * scaleRate, newSize, rect.Angle);
  115. return largerRect;
  116. })
  117. .OrderBy(v => v.Center.Y)
  118. .ThenBy(v => v.Center.X)
  119. .ToArray();
  120. src.Dispose();
  121. binary.Dispose();
  122. roi.Dispose();
  123. cbuf.Dispose();
  124. pred.Dispose();
  125. dilated.Dispose();
  126. //绘图
  127. Mat src2 = Cv2.ImRead(img);
  128. for (int i = 0; i < rects.Length; i++)
  129. {
  130. Scalar scalar = Scalar.RandomColor();
  131. List<OpenCvSharp.Point> temp = new List<OpenCvSharp.Point>();
  132. foreach (var item2 in rects[i].Points())
  133. {
  134. temp.Add(new OpenCvSharp.Point(item2.X, item2.Y));
  135. }
  136. List<List<OpenCvSharp.Point>> lltemp = new List<List<OpenCvSharp.Point>>();
  137. lltemp.Add(temp);
  138. Cv2.Polylines(src2, lltemp, true, scalar);
  139. }
  140. if (pictureBox1.Image!=null)
  141. {
  142. pictureBox1.Image.Dispose();
  143. }
  144. pictureBox1.Image = BitmapConverter.ToBitmap(src2);
  145. src2.Dispose();
  146. }
  147. }
  148. private float GetScore(OpenCvSharp.Point[] contour, Mat pred)
  149. {
  150. int width = pred.Width;
  151. int height = pred.Height;
  152. int[] boxX = contour.Select(v => v.X).ToArray();
  153. int[] boxY = contour.Select(v => v.Y).ToArray();
  154. int xmin = Clamp(boxX.Min(), 0, width - 1);
  155. int xmax = Clamp(boxX.Max(), 0, width - 1);
  156. int ymin = Clamp(boxY.Min(), 0, height - 1);
  157. int ymax = Clamp(boxY.Max(), 0, height - 1);
  158. OpenCvSharp.Point[] rootPoints = contour
  159. .Select(v => new OpenCvSharp.Point(v.X - xmin, v.Y - ymin))
  160. .ToArray();
  161. Mat mask = new Mat(ymax - ymin + 1, xmax - xmin + 1, MatType.CV_8UC1, Scalar.Black);
  162. mask.FillPoly(new[] { rootPoints }, new Scalar(1));
  163. Mat croppedMat = pred[ymin, ymax + 1, xmin, xmax + 1];
  164. float score = (float)croppedMat.Mean(mask).Val0;
  165. return score;
  166. }
  167. public int Clamp(int val, int min, int max)
  168. {
  169. if (val < min)
  170. {
  171. return min;
  172. }
  173. else if (val > max)
  174. {
  175. return max;
  176. }
  177. return val;
  178. }
  179. float[] ExtractMat(Mat src)
  180. {
  181. int rows = src.Rows;
  182. int cols = src.Cols;
  183. float[] array = new float[rows * cols * 3];
  184. GCHandle gCHandle = default(GCHandle);
  185. try
  186. {
  187. gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
  188. IntPtr intPtr = gCHandle.AddrOfPinnedObject();
  189. for (int i = 0; i < src.Channels(); i++)
  190. {
  191. Mat dest = new Mat(rows, cols, MatType.CV_32FC1, intPtr + i * rows * cols * 4, 0L);
  192. Cv2.ExtractChannel(src, dest, i);
  193. dest.Dispose();
  194. }
  195. return array;
  196. }
  197. finally
  198. {
  199. gCHandle.Free();
  200. }
  201. }
  202. private Mat MatResize(Mat src, int? maxSize)
  203. {
  204. if (maxSize == null) return src.Clone();
  205. OpenCvSharp.Size size = src.Size();
  206. int longEdge = Math.Max(size.Width, size.Height);
  207. double scaleRate = 1.0 * maxSize.Value / longEdge;
  208. return scaleRate < 1.0 ?
  209. src.Resize(OpenCvSharp.Size.Zero, scaleRate, scaleRate) :
  210. src.Clone();
  211. }
  212. private Mat MatPadding32(Mat src)
  213. {
  214. OpenCvSharp.Size size = src.Size();
  215. OpenCvSharp.Size newSize = new OpenCvSharp.Size(
  216. 32 * Math.Ceiling(1.0 * size.Width / 32),
  217. 32 * Math.Ceiling(1.0 * size.Height / 32));
  218. return src.CopyMakeBorder(0, newSize.Height - size.Height, 0, newSize.Width - size.Width, BorderTypes.Constant, Scalar.Black);
  219. }
  220. private Mat Normalize(Mat src)
  221. {
  222. Mat normalized = new Mat();
  223. src.ConvertTo(normalized, MatType.CV_32FC3, 1.0 / 255);
  224. Mat[] bgr = normalized.Split();
  225. float[] scales = new[] { 1 / 0.229f, 1 / 0.224f, 1 / 0.225f };
  226. float[] means = new[] { 0.485f, 0.456f, 0.406f };
  227. for (int i = 0; i < bgr.Length; ++i)
  228. {
  229. bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 * scales[i], (0.0 - means[i]) * scales[i]);
  230. }
  231. normalized.Dispose();
  232. Mat dest = new Mat();
  233. Cv2.Merge(bgr, dest);
  234. foreach (Mat channel in bgr)
  235. {
  236. channel.Dispose();
  237. }
  238. return dest;
  239. }
  240. }
  241. }

下载

Demo下载

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

闽ICP备14008679号