123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- using MeterVision.Config;
- using MeterVision.model;
- using MeterVision.Util;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
- using static MeterVision.FreeAi.FaImport;
- namespace MeterVision.FreeAi
- {
- //识别主程序
- public class FaRun
- {
- //private FaLog faLog; //设备运行日志类
- private StringBuilder mRunLog = new StringBuilder();
- public event EventHandler<AiRealLogEventArgs> OnAiRealLogInfo;
- //ai输出的日志回调函数
- private void PrintfCallbackMethod(string message)
- {
- //Debug.Write(message);
- //faLog.Append_aiLog(message);
- mRunLog.Append(message);
- //发送消息给主程序控件
- OnAiRealLogInfo?.Invoke(this, new AiRealLogEventArgs(message));
- }
- //增加MCU的日志
- private void AddMCULog(string message)
- {
- mRunLog.Append(message + "\n");
- OnAiRealLogInfo?.Invoke(this, new AiRealLogEventArgs(message));
- }
- //开始识别
- //public bool StartRecognition(string jpgFile)
- //{
- // faLog = new FaLog();
- // FaImport.PrintfCallback callback = PrintfCallbackMethod;
- // short[] rgb565 = FaImageHelper.getRGB565Array_from_jpgfile(jpgFile,faLog);
- // FaImport.BeforeAI beforeAI = FaBefore.getBeforeAI(); //new FreeAiImport.BeforeAI();
- // FaImport.AfterAI afterAI = new FaImport.AfterAI();
- // FaImport.SmallImage smallJpg = new FaImport.SmallImage();
- // FaImport.BigImage bigJpg = new FaImport.BigImage();
- // string onnxPath = ConfigItem.GetConfigItem().OnnxPath;
- // //FaConfig.get_onnxPath();
- // //判断onnxPath的路径是否存在
- // if (!File.Exists(onnxPath))
- // {
- // faLog.Appendln_mcuLog("onnxPath error");
- // return false;
- // }
- // //调用识别
- // //开始调用c_dll的识别函数
- // int result = FaImport.recognition(rgb565, ref beforeAI, ref afterAI, ref smallJpg, ref bigJpg, onnxPath, callback);
- // string bigJpg_filePath = @"C:\test_image\result\" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".jpg";
- // FaImage.saveBigJpg(bigJpg, bigJpg_filePath);
- // return true;
- //}
- public ResultModel StartRecognition(string jpgFile)
- {
- //PrintfCallback callback = PrintfCallbackMethod;
- ////string jpgFile = resultModel.SrcImage;
- ////判断图像尺寸是否合规
- //if (!ThisApp.IsImageDimensionsValid(jpgFile))
- //{
- // Console.WriteLine($"{jpgFile}图像尺寸不合规!");
- // return null;
- //}
- //short[] rgb565 = GetRGB565Array(jpgFile);
- //if (rgb565.Length != (320 * 240))
- //{
- // throw new InvalidOperationException("无效的图像大小。");
- //}
- //BeforeAI beforeAI = FaBefore.getBeforeAI();
- //AfterAI afterAI = new AfterAI();
- //SmallImage smallJpg = new SmallImage();
- //BigImage bigJpg = new BigImage();
- ////string onnxPath = ConfigItem.GetConfigItem().OnnxPath;
- //string onnxPath = CfginiItem.GetConfigItem().OnnxPath;
- //onnxPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, onnxPath);
- ////判断onnxPath的路径是否存在
- //if (!File.Exists(onnxPath))
- //{
- // throw new InvalidOperationException($"onnx文件{onnxPath}不存在!");
- //}
- ////调用识别
- ////开始调用c_dll的识别函数
- ////int result;
- ////try
- ////{
- //// result = recognition(rgb565, ref beforeAI, ref afterAI, ref smallJpg, ref bigJpg, onnxPath, callback);
- ////}
- ////catch(AccessViolationException ex)
- ////{
- //// // 处理异常,例如记录日志
- //// Console.WriteLine("Access violation: " + ex.Message);
- ////}
- ////调用动态加载的方式
- ////初始化加载动态库,
- ////string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigItem.GetConfigItem().AiDll);
- //string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, CfginiItem.GetConfigItem().AiDll);
- //if (!File.Exists(dllPath))
- //{
- // throw new InvalidOperationException($"AI动态库文件{dllPath}不存在!");
- //}
- //int result = -1;
- //if (DynamicFaImport.Initialize(dllPath))
- //{
- // try
- // {
- // result = DynamicFaImport.Recognition(rgb565, ref beforeAI, ref afterAI, ref smallJpg, ref bigJpg, onnxPath, callback);
- // }
- // catch (AccessViolationException ex)
- // {
- // // 处理异常,例如记录日志
- // Console.WriteLine("Access violation: " + ex.Message);
- // }
- // catch (Exception ex)
- // {
- // Console.WriteLine("Exeception: " + ex.Message);
- // }
- //}
- //else
- //{
- // throw new InvalidOperationException($"初始化AI动态库{dllPath}失败!");
- //}
- //DynamicFaImport.Unload();
- ////存储图像
- //string dstImagPath = CfginiItem.GetConfigItem().DstImgPath;
- //dstImagPath = Path.Combine(dstImagPath, ThisApp.GetNowTime_yyyyMMdd());
- //if (!Directory.Exists(dstImagPath))
- //{
- // Directory.CreateDirectory(dstImagPath);
- //}
- //dstImagPath = Path.Combine(dstImagPath, Guid.NewGuid().ToString() + ".jpg");
- //SaveBigJpg(bigJpg, dstImagPath);
- ////存储日志
- //string aiLogPath = CfginiItem.GetConfigItem().AiLogPath;
- //aiLogPath = Path.Combine(aiLogPath, ThisApp.GetNowTime_yyyyMMdd());
- //if (!Directory.Exists(aiLogPath))
- //{
- // Directory.CreateDirectory(aiLogPath);
- //}
- //aiLogPath = Path.Combine(aiLogPath, Guid.NewGuid().ToString() + ".txt");
- //try
- //{
- // if (LicenseMana.mLicenseModel != null && LicenseMana.mLicenseModel.IsPermanent)
- // {
- // File.WriteAllText(aiLogPath, mRunLog.ToString());
- // }
- // else
- // {
- // File.WriteAllText(aiLogPath, "");
- // }
- //}
- //catch(Exception ex)
- //{
- // throw new InvalidOperationException($"保存文件{aiLogPath}失败:{ex.Message}");
- //}
- ////结果对象赋值
- //ResultModel resultModel = new ResultModel();
- //resultModel.SrcImage = jpgFile;
- //resultModel.DstImage = dstImagPath;
- //resultModel.LogPath = aiLogPath;
- //resultModel.MeterType = afterAI.meter_type;
- //if(afterAI.meter_type == 1)
- //{
- // //数字水表: 数字+指针
- // resultModel.DigitCount = afterAI.NUM_DETECTED;
- // resultModel.PointerCount = afterAI.IND_DETECTED;
- //}
- //else if(afterAI.meter_type == 2)
- //{
- // //全指针
- // resultModel.DigitCount = 0;
- // resultModel.PointerCount = afterAI.NUM_DETECTED;
- //}else if(afterAI.meter_type == 3)
- //{
- // //全数字
- // resultModel.DigitCount = afterAI.NUM_DETECTED;
- // resultModel.PointerCount = 0;
- //}
- //else
- //{
- // resultModel.MeterType = 0;
- // resultModel.DigitCount = 0;
- // resultModel.PointerCount = 0;
- //}
- ////1,2,7,8
- //resultModel.ResultType = afterAI.AI_result_array[11];
- //resultModel.RawValue = afterAI.init_AI_result;
- //resultModel.FinalValue = afterAI.AI_result;
- //resultModel.LastUnit = afterAI.UNIT_OF_THE_LAST_NUMBER;
- //resultModel.AiVer = BitConverter.ToString(afterAI.AI_ver).Replace("-", "");
- //resultModel.DebugInfoBytes = afterAI.AI_result_array;
- //return resultModel;
- return null;
- }
- public ResultModel StartRecognition(SingleDetailItem detailItem)
- {
- PrintfCallback callback = PrintfCallbackMethod;
- //string jpgFile = resultModel.SrcImage;
- //判断图像尺寸是否合规
- if (!ThisApp.IsImageDimensionsValid(detailItem.SrcImage))
- {
- Console.WriteLine($"{detailItem.SrcImage}图像尺寸不合规!");
- return null;
- }
- short[] rgb565 = GetRGB565Array(detailItem.SrcImage);
- if (rgb565.Length != (320 * 240))
- {
- throw new InvalidOperationException("无效的图像大小。");
- }
- BeforeAI beforeAI = FaBefore.getBeforeAI();
- AfterAI afterAI = new AfterAI();
- SmallImage smallJpg = new SmallImage();
- BigImage bigJpg = new BigImage();
- //string onnxPath = ConfigItem.GetConfigItem().OnnxPath;
- string onnxPath = CfginiItem.GetConfigItem().OnnxPath;
- onnxPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, onnxPath);
- //判断onnxPath的路径是否存在
- if (!File.Exists(onnxPath))
- {
- throw new InvalidOperationException($"onnx文件{onnxPath}不存在!");
- }
- //调用识别
- //开始调用c_dll的识别函数
- //int result;
- //try
- //{
- // result = recognition(rgb565, ref beforeAI, ref afterAI, ref smallJpg, ref bigJpg, onnxPath, callback);
- //}
- //catch(AccessViolationException ex)
- //{
- // // 处理异常,例如记录日志
- // Console.WriteLine("Access violation: " + ex.Message);
- //}
- //调用动态加载的方式
- //初始化加载动态库,
- //string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigItem.GetConfigItem().AiDll);
- string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, CfginiItem.GetConfigItem().AiDll);
- if (!File.Exists(dllPath))
- {
- throw new InvalidOperationException($"AI动态库文件{dllPath}不存在!");
- }
- int result = -1;
- if (DynamicFaImport.Initialize(dllPath))
- {
- try
- {
- result = DynamicFaImport.Recognition(rgb565, ref beforeAI, ref afterAI, ref smallJpg, ref bigJpg, onnxPath, callback);
- }
- catch (AccessViolationException ex)
- {
- // 处理异常,例如记录日志
- Console.WriteLine("Access violation: " + ex.Message);
- }
- catch (Exception ex)
- {
- Console.WriteLine("Exeception: " + ex.Message);
- }
- }
- else
- {
- throw new InvalidOperationException($"初始化AI动态库{dllPath}失败!");
- }
- DynamicFaImport.Unload();
- //存储图像
- string dstImagPath = CfginiItem.GetConfigItem().DstImgPath;
- dstImagPath = Path.Combine(dstImagPath, ThisApp.GetNowTime_yyyyMMdd());
- if (!Directory.Exists(dstImagPath))
- {
- Directory.CreateDirectory(dstImagPath);
- }
- dstImagPath = Path.Combine(dstImagPath, Guid.NewGuid().ToString() + ".jpg");
- SaveBigJpg(bigJpg, dstImagPath);
- //存储日志
- string aiLogPath = CfginiItem.GetConfigItem().AiLogPath;
- aiLogPath = Path.Combine(aiLogPath, ThisApp.GetNowTime_yyyyMMdd());
- if (!Directory.Exists(aiLogPath))
- {
- Directory.CreateDirectory(aiLogPath);
- }
- aiLogPath = Path.Combine(aiLogPath, Guid.NewGuid().ToString() + ".txt");
- try
- {
- if (LicenseMana.mLicenseModel != null && LicenseMana.mLicenseModel.IsPermanent)
- {
- File.WriteAllText(aiLogPath, mRunLog.ToString());
- }
- else
- {
- File.WriteAllText(aiLogPath, "");
- }
- }
- catch (Exception ex)
- {
- throw new InvalidOperationException($"保存文件{aiLogPath}失败:{ex.Message}");
- }
- //结果对象赋值
- ResultModel resultModel = new ResultModel();
- resultModel.SrcImage = detailItem.SrcImage;
- resultModel.DstImage = dstImagPath;
- resultModel.LogPath = aiLogPath;
- resultModel.MeterType = afterAI.METER_TYPE;
- //1,2,7,8
- resultModel.ResultType = afterAI.AI_RESULT_ARRAY[11];
- resultModel.RawValue = afterAI.INIT_AI_RESULT;
- resultModel.FinalValue = afterAI.AI_RESULT;
-
- if (detailItem.MeterType == 1 || detailItem.MeterType == 3) {
- resultModel.LastUnit = beforeAI.UNIT_OF_THE_LAST_NUMBER;
- }
- else if(detailItem.MeterType == 2)
- {
- resultModel.LastUnit = beforeAI.UNIT_OF_THE_LAST_INDICATOR;
- }
- resultModel.AiVer = BitConverter.ToString(afterAI.AI_VER).Replace("-", "");
- resultModel.DebugInfoBytes = afterAI.AI_RESULT_ARRAY;
-
- return resultModel;
- }
- private short[] GetRGB565Array(string jpgFilePath)
- {
- using (Bitmap bmp = new Bitmap(jpgFilePath))
- {
- int width = bmp.Width;
- int height = bmp.Height;
- //string message = string.Format("width = %d,height = %d", width, height);
- string message = $"width = {width}, height = {height}";
- AddMCULog(message);
- //创建数组存储RGB565数据
- short[] rgb565Data = new short[width * height];
- //给它多分配1倍的内存
- //short[] rgb565Data = new short[width * height*2];
- //锁定位图内存
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
- IntPtr ptr = bmpData.Scan0;
- //创建数据存储RGB888数据
- byte[] rgb888Data = new byte[Math.Abs(bmpData.Stride) * height];
- //将像素数据拷贝到字节数组中
- Marshal.Copy(ptr, rgb888Data, 0, rgb888Data.Length);
- // 逐个像素转换为 RGB565 格式,并进行上下颠倒处理
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- // 颠倒行的顺序
- int invertedY = height - 1 - y;
- //int index = y * bmpData.Stride + x * 3;
- int index = invertedY * bmpData.Stride + x * 3;
- byte r = rgb888Data[index + 2]; // R 通道
- byte g = rgb888Data[index + 1]; // G 通道
- byte b = rgb888Data[index]; // B 通道
- // 将 RGB888 转换为 RGB565
- short rgb565 = (short)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
- rgb565Data[y * width + x] = rgb565;
- }
- }
- //解锁位图
- bmp.UnlockBits(bmpData);
- bmp.Dispose();
- return rgb565Data;
- }//using Bitmap
- }
- private bool SaveBigJpg(BigImage bigJpg, string fileName)
- {
- if (bigJpg.size_of_JPEG_data == 0)
- {
- //Debug.Write("bigJpg dataSize error!");
- AddMCULog("bigJpg dataSize error!");
- return false;
- }
- bool saveResult = false;
- try
- {
- //获取文件夹路径
- string directoryPath = Path.GetDirectoryName(fileName);
- //如果文件夹不存在,创建文件夹
- if (!Directory.Exists(directoryPath))
- {
- Directory.CreateDirectory(directoryPath);
- }
- //保存文件
- //File.WriteAllBytes(fileName, bigJpg.JPEG_data);
- using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
- {
- fs.Write(bigJpg.JPEG_data, 0, bigJpg.size_of_JPEG_data);
- }
- saveResult = true;
- }
- catch (Exception e)
- {
- AddMCULog(e.Message);
- //Debug.Write(e.Message);
- }
- string strResult = string.Format("save {0} {1}", fileName, saveResult ? "success" : "fail");
- //Debug.Write(strResult);
- AddMCULog(strResult);
- return saveResult;
- }
- //-------------------------------------------------------------------
- }
- //日志信息事件
- public class AiRealLogEventArgs : EventArgs
- {
- public string mLogInfo { get; }
- public AiRealLogEventArgs(string logInfo)
- {
- mLogInfo = logInfo;
- }
- }
- //---------------------------------------------------
-
- }
|