赞
踩
目录
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;
}
}
}
- 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;
- }
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。