IDCardRecognition.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using AI.Common.Interface;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Runtime.InteropServices;
  5. namespace IDCardRecognitionLibs
  6. {
  7. public class IDCardRecognition
  8. {
  9. #region private
  10. /// <summary>
  11. /// 检测算法
  12. /// </summary>
  13. private IDCardAnalyser? _idCardAnalyser = null;
  14. /// <summary>
  15. /// 主动结束
  16. /// </summary>
  17. private volatile bool _disposing = false;
  18. /// <summary>
  19. /// 选择的OCR模型,目前只支持PaddleOCR
  20. /// </summary>
  21. private EnumOCRModel _modelType = EnumOCRModel.PaddleOCR;
  22. #endregion
  23. #region 实现接口
  24. /// <summary>
  25. /// 评估单幅图像
  26. /// </summary>
  27. /// <param name="image"></param>
  28. /// <returns></returns>
  29. public IDCardRecogResult EvaluateOneImage(Bitmap image)
  30. {
  31. try
  32. {
  33. if (!_disposing)
  34. {
  35. // 将bitmap统一转成3通道图像进行接下来的处理
  36. return _idCardAnalyser.EvaluateOneImage(BitmapToRawImage(image));
  37. }
  38. else
  39. {
  40. return new IDCardRecogResult();
  41. }
  42. }
  43. catch(Exception excep)
  44. {
  45. throw new Exception(excep.Message);
  46. }
  47. }
  48. /// <summary>
  49. /// 主动销毁
  50. /// </summary>
  51. public void Dispose()
  52. {
  53. DoDispose();
  54. GC.SuppressFinalize(this);
  55. LogHelper.InfoLog("HepatoRenalEchoContrastDetect.Disposed manually.", string.Empty);
  56. }
  57. #endregion
  58. /// <summary>
  59. /// 构造函数
  60. /// </summary>
  61. /// <param name="dir">模型地址,从该地址下存放的Networks文件夹里面加载模型</param>
  62. public IDCardRecognition(string netDir)
  63. {
  64. //Thread.Sleep(30000);
  65. // 从该地址下面加载模型,默认使用paddleOCR模型
  66. _idCardAnalyser = new IDCardAnalyser(netDir, _modelType);
  67. }
  68. #region private funcs
  69. /// <summary>
  70. /// convert bitmap to bytes
  71. /// </summary>
  72. /// <param name="image"></param>
  73. /// <param name="keepChannel"></param>
  74. /// <returns></returns>
  75. /// <exception cref="Exception"></exception>
  76. private static RawImage BitmapToRawImage(Bitmap image, bool keepChannel = false)
  77. {
  78. EnumColorType enumColorType;
  79. int width = image.Width;
  80. int height = image.Height;
  81. PixelFormat pixelFormat = image.PixelFormat;
  82. if (pixelFormat != PixelFormat.Format24bppRgb && pixelFormat != PixelFormat.Format32bppArgb &&
  83. pixelFormat != PixelFormat.Format32bppPArgb && pixelFormat != PixelFormat.Format32bppRgb &&
  84. pixelFormat != PixelFormat.Format8bppIndexed)
  85. {
  86. throw new Exception("Unexpected image pixel format:" + pixelFormat);
  87. }
  88. int origChannel = 3;
  89. if (pixelFormat == PixelFormat.Format24bppRgb)
  90. {
  91. origChannel = 3;
  92. }
  93. else if (pixelFormat == PixelFormat.Format8bppIndexed)
  94. {
  95. origChannel = 1;
  96. }
  97. else
  98. {
  99. origChannel = 4;
  100. }
  101. int dstChannel = 3;
  102. if (keepChannel)
  103. {
  104. dstChannel = origChannel;
  105. }
  106. enumColorType = (EnumColorType)dstChannel;
  107. var bmData = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, pixelFormat);
  108. byte[] dstDataArray = new byte[width * height * dstChannel];
  109. unsafe
  110. {
  111. int stride = bmData.Stride;
  112. int dstStride = width * dstChannel;
  113. IntPtr ptr = bmData.Scan0;
  114. IntPtr ptrH, ptrW;
  115. for (int nh = 0; nh < height; nh++)
  116. {
  117. ptrH = IntPtr.Add(ptr, nh * stride);
  118. if (origChannel == dstChannel)
  119. {
  120. Marshal.Copy(ptrH, dstDataArray, nh * dstStride, dstStride);
  121. }
  122. else if (origChannel > dstChannel)
  123. {
  124. for (int nw = 0; nw < width; nw++)
  125. {
  126. ptrW = IntPtr.Add(ptrH, nw * origChannel);
  127. Marshal.Copy(ptrW, dstDataArray, nh * dstStride + nw * dstChannel, dstChannel);
  128. }
  129. }
  130. else
  131. {
  132. for (int nw = 0; nw < width; nw++)
  133. {
  134. ptrW = IntPtr.Add(ptrH, nw * origChannel);
  135. for (int nc = 0; nc < dstChannel; nc++)
  136. {
  137. Marshal.Copy(ptrW, dstDataArray, nh * dstStride + nw * dstChannel + nc, 1);
  138. }
  139. }
  140. }
  141. }
  142. }
  143. image.UnlockBits(bmData);
  144. return new RawImage(dstDataArray, width, height, enumColorType);
  145. }
  146. /// <summary>
  147. /// 销毁
  148. /// </summary>
  149. private void DoDispose()
  150. {
  151. if (!_disposing)
  152. {
  153. _disposing = true;
  154. if (_idCardAnalyser != null)
  155. {
  156. _idCardAnalyser.Dispose();
  157. _idCardAnalyser = null;
  158. }
  159. }
  160. }
  161. #endregion
  162. }
  163. }