hisence-yolo-detection/HisenceYoloDetection/PaddleOcrModelCountry.cs

295 lines
9.1 KiB
C#
Raw Normal View History

2024-05-31 10:14:57 +08:00

using Newtonsoft.Json;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using PaddleOCRSharp;
using STTech.BytesIO.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
using Point = OpenCvSharp.Point;
namespace XKRS.Device.SimboVision.SimboHelper
{
public class SegResultCountry
{
public List<ResultCountry> SegmentResult;
public class ResultCountry
{
public double fScore;
public int classId;
public string classname;
public double area;
public List<List<int>> rect;
}
}
public class PaddleOcrModelCountry
{
IntPtr Model;
public bool Load(string ModelFile,string Device)
{
bool res = false;
try
{
Model = OcrEngine.InitModel(ModelFile, Device);
res = true;
#if USE_MULTI_THREAD
IsCreated = true;
if (IsCreated)
{
if (_runHandleBefore == null)
{
_runHandleBefore = new AutoResetEvent(false);
}
if (_runHandleAfter == null)
{
_runHandleAfter = new ManualResetEvent(false);
}
if (_runTask == null)
{
_runTask = Task.Factory.StartNew(() =>
{
while (IsCreated)
{
_runHandleBefore.WaitOne();
if (IsCreated)
{
_result = RunInferenceFixed(_req);
_runHandleAfter.Set();
}
}
}, TaskCreationOptions.LongRunning);
}
}
#endif
}
catch (Exception ex)
{
throw ex;
}
return res;
}
#if USE_MULTI_THREAD
MLRequest _req = null;
MLResult _result = null;
public bool IsCreated { get; set; } = false;
Task _runTask = null;
AutoResetEvent _runHandleBefore = new AutoResetEvent(false);
ManualResetEvent _runHandleAfter = new ManualResetEvent(false);
object _runLock = new object();
#endif
[HandleProcessCorruptedStateExceptions]
2024-06-11 11:40:47 +08:00
public MLResult RunInference(MLRequest req)
2024-05-31 10:14:57 +08:00
{
#if USE_MULTI_THREAD
MLResult mlResult = null;
lock (_runLock)
{
_result = new MLResult();
_req = req;
_runHandleAfter.Reset();
_runHandleBefore.Set();
_runHandleAfter.WaitOne();
mlResult = _result;
}
return mlResult;
#else
return RunInferenceFixed(req);
#endif
}
2024-06-27 09:22:31 +08:00
//string pattern = @"^[A-Za-z0-9]+$"; //@意思忽略转义,+匹配前面一次或多次,$匹配结尾
// Match match = Regex.Match(str, pattern);
private void ConvertJsonResult(string json, ref MLResult result)
2024-05-31 10:14:57 +08:00
{
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
2024-06-27 09:22:31 +08:00
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
2024-05-31 10:14:57 +08:00
if (detResult == null)
{
return;
}
int iNum = detResult.SegmentResult.Count;
int IokNum = 0;
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.SegmentResult[ix];
var rect = det.rect;
List<Point> points = new List<Point>();
List<float> maxYs = new List<float>();
//把字体打印在矩形框的下面考虑矩形框最靠下的角点Y值不能超过边框值 否则就往上写
for (int n = 0; n < det.rect.Count(); n++)
{
points.Add(new Point(det.rect[n][0], det.rect[n][1]));
maxYs.Add(det.rect[n][1]);
}
// 定义矩形左上角和右下角的坐标
Point topLeft = points[0];
Point bottomRight = points[2];
// 计算矩形的长和宽
int width = bottomRight.X - topLeft.X;//矩形宽度
int height = bottomRight.Y - topLeft.Y;//矩形高度
//下面定义一个矩形区域,以后在这个矩形里画上白底黑字
float rectX = points[0].X;
float rectY = points[0].Y;
float rectWidth = width;
float rectHeight = height;
2024-06-27 09:22:31 +08:00
//string pattern = @"^[A-Za-z0-9]+$"; //@意思忽略转义,+匹配前面一次或多次,$匹配结尾
// bool match = Regex.IsMatch(det.classname, pattern);
if (det.classname != ""&& rectWidth>0&& rectHeight>0)
{
DetectionResultDetail detectionResultDetail = new DetectionResultDetail();
detectionResultDetail.LabelNo = det.classId;
//todo: 标签名相对应
detectionResultDetail.LabelDisplay = det.classname;
detectionResultDetail.Rect = new Rectangle((int)rectX, (int)rectY, (int)rectWidth, (int)rectHeight);
detectionResultDetail.Score = det.fScore;
detectionResultDetail.LabelName = det.classname;
detectionResultDetail.Area = det.area;
result.ResultDetails.Add(detectionResultDetail);
}
2024-05-31 10:14:57 +08:00
}
}
[HandleProcessCorruptedStateExceptions]
2024-06-11 11:40:47 +08:00
public MLResult RunInferenceFixed(MLRequest req)
2024-05-31 10:14:57 +08:00
{
2024-06-11 11:40:47 +08:00
MLResult mlResult = new MLResult();
2024-05-31 10:14:57 +08:00
Mat originMat = new Mat();
try
{
originMat = req.currentMat;//1ms
int iWidth = originMat.Cols;
int iHeight = originMat.Rows;
//输入数据转化为字节
var inputByte = new byte[originMat.Total() * 3];//这里必须乘以通道数不然数组越界也可以用w*h*c差不多
Marshal.Copy(originMat.Data, inputByte, 0, inputByte.Length);
byte[] labellist = new byte[20480]; //新建字节数组label1_str label2_str
byte[] outputByte = new byte[originMat.Total() * 3];
Stopwatch sw = new Stopwatch();
sw.Start();
unsafe
{
mlResult.IsSuccess = OcrEngine.Inference(Model, inputByte, iWidth, iHeight, 3, ref outputByte[0], ref labellist[0]);
}
sw.Stop();
if (mlResult.IsSuccess)
{
mlResult.ResultMessage = $"深度学习推理成功,耗时:{sw.ElapsedMilliseconds} ms";
Mat maskWeighted = new Mat(iHeight, iWidth, MatType.CV_8UC3, outputByte);
mlResult.ResultMap = BitmapConverter.ToBitmap(maskWeighted);//4ms
//将字节数组转换为字符串
mlResult.ResultMap = originMat.ToBitmap();//4ms
string strGet = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
Console.WriteLine("strGet:", strGet);
ConvertJsonResult(strGet, ref mlResult);
maskWeighted?.Dispose();
maskWeighted = null;
//解析json字符串
return mlResult;
}
else
{
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
return mlResult;
}
}
catch (Exception ex)
{
mlResult.ResultMessage = $"深度学习执行推理异常:{ex.Message}";
return mlResult;
}
finally
{
//originMat?.Dispose();
//originMat = null;
// GC.Collect();
}
}
public void FreeModel()
{
OcrEngine.FreePredictor(Model);
}
}
}