FaImport.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace MeterVision.FreeAi
  8. {
  9. public class FaImport
  10. {
  11. //beforeAI结构体
  12. //[StructLayout(LayoutKind.Sequential, Pack = 1)]
  13. //public struct BeforeAI
  14. //{
  15. // // 01 (配置信息)数字个数(黑色+红色)
  16. // public byte NUM_NUMBERS; // uint8_t 对应 byte
  17. // // 01 (配置信息)数字个数(黑色),人工决定的时候不需要配置,=NUM_NUMBERS
  18. // public byte NUM_BLACK_NUMBERS; // uint8_t 对应 byte
  19. // // 02(配置信息)指针个数
  20. // public byte NUM_INDICATORS; // uint8_t 对应 byte
  21. // // 1立方=1000L = 10000分升,1分升=1/10升=1/10000立方
  22. // // 尾数单位的含义,最小单位1分升,1dL, 0.1L(万分之一立方)
  23. // public uint UNIT_OF_THE_LAST_NUMBER; // uint32_t 对应 uint
  24. // // 04(配置信息)强制拉回的概率阈值(初始=50%)
  25. // public byte BEST_CONF; // uint8_t 对应 byte
  26. // // 05(配置信息)识别可信度的概率阈值(初始=5%)
  27. // public byte GOOD_CONF; // uint8_t 对应 byte
  28. // // 06(配置信息)单独每一位概率阈值(初始=90%)
  29. // public byte BIT_BEST_CONF; // uint8_t 对应 byte
  30. // // 07(配置信息)是否颠倒安装(0=正常安装;1=上下颠倒安装)
  31. // public byte IS_UPDOWN; // uint8_t 对应 byte
  32. // // 每小时的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
  33. // public ulong MAX_FLOW_PER_HOUR; // uint64_t 对应 ulong
  34. // // 当前时间距离上次准确识别时间内的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
  35. // public ulong MAX_FLOW_threshold; // uint64_t 对应 ulong
  36. // // 09(本次结果)图像倾斜角度
  37. // public short lean_angle; // int16_t 对应 short
  38. // // 8字节整数,表示识别结果,最小单位分升,即1dL=0.1L=1m³/10000),万分之一立方;
  39. // public ulong AI_result; // uint64_t 对应 ulong
  40. // // 传入的ai_result的值是否是可信的前值(来源于AfterAI);
  41. // public byte is_OK_preValue; // uint8_t 对应 byte
  42. // // 11(上次结果)数字区域的xmin、ymin、xmax、ymax坐标值
  43. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  44. // public ushort[] num_region; // uint16_t 对应 ushort, 4 个元素的数组
  45. // // 12 是否需要上传整图?0=不需要;1=需要;
  46. // public byte is_get_whole_image; // uint8_t 对应 byte
  47. // // 上传日志的printf回调函数
  48. // public IntPtr printfAiLog; // 回调函数指针, 用 IntPtr 表示
  49. // // 14(配置信息)公司平台上传的图片的存储大小?(1:BMP彩色图; >1:JPG彩色图)
  50. // public ushort PingTai_image_size; // uint16_t 对应 ushort
  51. // // 15(配置信息)上传图像尺寸大小 = 数字区域区域外扩 PingTai_image_margin 像素
  52. // public byte PingTai_image_margin; // uint8_t 对应 byte
  53. // // 16(配置信息)数字区域的xmin、ymin、xmax、ymax坐标值
  54. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  55. // public ushort[] config_num_region; // uint16_t 对应 ushort, 4 个元素的数组
  56. // // 17(配置信息)图像倾斜角度
  57. // public short config_lean_angle; // int16_t 对应 short
  58. // // 18(配置信息)在识别过程中,是否使用 config_num_region、config_lean_angle变量值
  59. // public byte is_use_config_info; // uint8_t 对应 byte
  60. // // 19(配置信息)是否上传CNN模型的检测结果到服务器?(0=不上传;1=上传)
  61. // public byte is_upload_cnn_output; // uint8_t 对应 byte
  62. // // 20(配置信息)对CNN输出进行解码时,使用的NMS阈值(默认值=10)
  63. // public byte nms_threshold; // uint8_t 对应 byte
  64. // // 21(配置信息)是否使用检测到的大框来排除数字(0=不用;1=用)(默认值=1)
  65. // public byte is_use_detected_num88;// uint8_t 对应 byte
  66. // // 22(上次结果),存储每个指针区域的xmin、ymin、xmax、ymax坐标值。最多存储10个指针
  67. // //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  68. // //public ushort[,] indicators_regions; // uint16_t[10][4] 对应 ushort[10, 4]
  69. // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
  70. // public ushort[] indicators_regions; // 对应 uint16_t[10][4] 展开成一维数组
  71. // // 表具中心点x
  72. // public float center_x; // float 对应 float
  73. // // 表具中心点y
  74. // public float center_y; // float 对应 float
  75. // // 图片亮度
  76. // public float bright_factor; // float 对应 float
  77. // // 仪表类型,模型类型
  78. // public byte meter_type; // uint8_t 对应 byte
  79. // // 人工配置的水表参数使能开关
  80. // public byte manual_parameter_enable; // uint8_t 对应 byte
  81. // // 大图JPG图像的最大字节数
  82. // public ushort big_jpg_max_size; // uint16_t 对应 ushort
  83. // // AI输出JPG图是,使用测试图标记,1:使用,0:不使用
  84. // public byte use_test_jpg_flag; // uint8_t 对应 byte
  85. // // 数字水表图像放大倍率,中心点为图像中心
  86. // public float number_image_zoomrate; // float 对应 float
  87. // // 指针水表图像放大倍率,中心点为拟合圆圆心
  88. // public float indicator_image_zommrate;// float 对应 float
  89. // // 水表中数字区域位于上半部?1=位于上半部分;0=位于下半部分。 默认值为1
  90. // public byte is_nums_in_upper; // uint8_t 对应 byte
  91. // // 数字+指针水表中“数字”部分读数;全指针水表中“黑色”指针部分的读数;全数字水表中“数字”部分读数
  92. // public ulong result_of_1st_part; // uint64_t 对应 ulong
  93. // // 数字+指针水表中“指针”部分读数;全指针水表中“红色”指针部分的读数;用来判断此水表是否在动
  94. // public ulong result_of_2st_part; // uint64_t 对应 ulong
  95. // // 压缩JPG的索引,来自after_struct,首次索引为0
  96. // public byte compress_jpg_index; // uint8_t 对应 byte
  97. // // 是否上传红色指针部分的数据(0:不上传;1:上传;默认1)
  98. // public byte is_upload_red_ind_part;// uint8_t 对应 byte
  99. //}
  100. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  101. public struct BeforeAI
  102. {
  103. // 01 (配置信息)数字个数(黑色+红色)
  104. public byte NUM_NUMBERS; // uint8_t 对应 byte
  105. // 01 (配置信息)数字个数(黑色),人工决定的时候不需要配置,=NUM_NUMBERS
  106. public byte NUM_BLACK_NUMBERS; // uint8_t 对应 byte
  107. // 02(配置信息)指针个数
  108. public byte NUM_INDICATORS; // uint8_t 对应 byte
  109. // 1立方=1000L = 10000分升,1分升=1/10升=1/10000立方
  110. // 尾数单位的含义,最小单位1分升,1dL, 0.1L(万分之一立方)
  111. public uint UNIT_OF_THE_LAST_NUMBER; // uint32_t 对应 uint
  112. // 04(配置信息)强制拉回的概率阈值(初始=50%)
  113. public byte BEST_CONF; // uint8_t 对应 byte
  114. // 05(配置信息)识别可信度的概率阈值(初始=5%)
  115. public byte GOOD_CONF; // uint8_t 对应 byte
  116. // 06(配置信息)单独每一位概率阈值(初始=90%)
  117. public byte BIT_BEST_CONF; // uint8_t 对应 byte
  118. // 07(配置信息)是否颠倒安装(0=正常安装;1=上下颠倒安装)
  119. public byte IS_UPDOWN; // uint8_t 对应 byte
  120. // 每小时的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
  121. public ulong MAX_FLOW_PER_HOUR; // uint64_t 对应 ulong
  122. // 当前时间距离上次准确识别时间内的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
  123. public ulong MAX_FLOW_threshold; // uint64_t 对应 ulong
  124. // 09(本次结果)图像倾斜角度
  125. public short lean_angle; // int16_t 对应 short
  126. // 8字节整数,表示识别结果,最小单位分升,即1dL=0.1L=1m³/10000),万分之一立方;
  127. public ulong AI_result; // uint64_t 对应 ulong
  128. // 传入的ai_result的值是否是可信的前值(来源于AfterAI);
  129. public byte is_OK_preValue; // uint8_t 对应 byte
  130. // 11(上次结果)数字区域的xmin、ymin、xmax、ymax坐标值
  131. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  132. public ushort[] num_region; // uint16_t 对应 ushort, 4 个元素的数组
  133. // 12 是否需要上传整图?0=不需要;1=需要;
  134. public byte is_get_whole_image; // uint8_t 对应 byte
  135. // 上传日志的printf回调函数
  136. public IntPtr printfAiLog; // 回调函数指针, 用 IntPtr 表示
  137. // 14(配置信息)公司平台上传的图片的存储大小?(1:BMP彩色图; >1:JPG彩色图)
  138. public ushort PingTai_image_size; // uint16_t 对应 ushort
  139. // 15(配置信息)上传图像尺寸大小 = 数字区域区域外扩 PingTai_image_margin 像素
  140. public byte PingTai_image_margin; // uint8_t 对应 byte
  141. // 16(配置信息)数字区域的xmin、ymin、xmax、ymax坐标值
  142. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  143. public ushort[] config_num_region; // uint16_t 对应 ushort, 4 个元素的数组
  144. // 17(配置信息)图像倾斜角度
  145. public short config_lean_angle; // int16_t 对应 short
  146. // 18(配置信息)在识别过程中,是否使用 config_num_region、config_lean_angle变量值
  147. public byte is_use_config_info; // uint8_t 对应 byte
  148. // 19(配置信息)是否上传CNN模型的检测结果到服务器?(0=不上传;1=上传)
  149. public byte is_upload_cnn_output; // uint8_t 对应 byte
  150. // 20(配置信息)对CNN输出进行解码时,使用的NMS阈值(默认值=10)
  151. public byte nms_threshold; // uint8_t 对应 byte
  152. // 21(配置信息)是否使用检测到的大框来排除数字(0=不用;1=用)(默认值=1)
  153. public byte is_use_detected_num88;// uint8_t 对应 byte
  154. // 22(上次结果),存储每个指针区域的xmin、ymin、xmax、ymax坐标值。最多存储10个指针
  155. //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  156. //public ushort[,] indicators_regions; // uint16_t[10][4] 对应 ushort[10, 4]
  157. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
  158. public ushort[] indicators_regions; // 对应 uint16_t[10][4] 展开成一维数组
  159. // 图片亮度
  160. public float bright_factor; // float 对应 float
  161. // 仪表类型,模型类型
  162. public byte meter_type; // uint8_t 对应 byte
  163. // 人工配置的水表参数使能开关
  164. public byte manual_parameter_enable; // uint8_t 对应 byte
  165. // 大图JPG图像的最大字节数
  166. public ushort big_jpg_max_size; // uint16_t 对应 ushort
  167. // AI输出JPG图是,使用测试图标记,1:使用,0:不使用
  168. public byte use_test_jpg_flag; // uint8_t 对应 byte
  169. // 表具中心点x
  170. public float center_x; // float 对应 float
  171. // 表具中心点y
  172. public float center_y; // float 对应 float
  173. // 数字水表图像放大倍率,中心点为图像中心
  174. public float number_image_zoomrate; // float 对应 float
  175. // 指针水表图像放大倍率,中心点为拟合圆圆心
  176. public float indicator_image_zommrate;// float 对应 float
  177. public float image_zoomrate;//图像放大倍率,中心点为拟合圆圆心
  178. // 水表中数字区域位于上半部?1=位于上半部分;0=位于下半部分。 默认值为1
  179. public byte is_nums_in_upper; // uint8_t 对应 byte
  180. // 数字+指针水表中“数字”部分读数;全指针水表中“黑色”指针部分的读数;全数字水表中“数字”部分读数
  181. public ulong result_of_1st_part; // uint64_t 对应 ulong
  182. // 数字+指针水表中“指针”部分读数;全指针水表中“红色”指针部分的读数;用来判断此水表是否在动
  183. public ulong result_of_2st_part; // uint64_t 对应 ulong
  184. // 压缩JPG的索引,来自after_struct,首次索引为0
  185. public byte compress_jpg_index; // uint8_t 对应 byte
  186. // 是否上传红色指针部分的数据(0:不上传;1:上传;默认1)
  187. public byte is_upload_red_ind_part;// uint8_t 对应 byte
  188. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)]
  189. public ulong[] history_result; // 对应 uint16_t[10][4] 展开成一维数组
  190. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
  191. public ulong[] history_digit_statistics;
  192. }
  193. //After结构体
  194. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  195. public struct AfterAI
  196. {
  197. public byte NUM_DETECTED; //01(本次结果)检测到的数字个数(黑色+红色)
  198. public byte IND_DETECTED; //01(本次结果)在数字+指针水表中,检测到的指针个数,全指针水表不用此值(2024.05.06增加)
  199. public byte NUM_BLACK_DETECTED; //01 (本次信息)检测到的 数字个数(黑色)
  200. public ulong AI_result; //识别最终结果,经过校正步骤后的最终结果,单位分升dL
  201. public byte is_OK_preValue; //ai_result的值是否是可信的值, add by djs 20240417
  202. public ulong init_AI_result; //网络直接输出的、没有经过校正的最初识别结果,单位分升dL
  203. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] // AI_result_array[2][12] 转成一维数组
  204. public byte[] AI_result_array; //03(本次结果)int数组的识别结果(2维数组,第一行元素为类别、第二行为识别概率)
  205. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  206. public ushort[] num_region; //04(本次结果)数字区域的xmin、ymin、xmax、ymax坐标值
  207. public short lean_angle; //05(本次结果)图像倾斜角度,和Before_AI_struct_RX结构体中的brightness一起维护图像倾斜角度
  208. public byte is_get_ShuiLiSuo_image; //06(本次结果)20220620 new add by lyj 是否生成了水利所的小图, 0=没有生产 1=生成了
  209. public byte is_get_KaoJiPingTai_image; //07(本次结果)20220620 new add by lyj 是否生成了拷机平台的中图,0=没有生成 1=生成了
  210. public byte is_get_whole_image; //08(本次结果)是否生成了上传的整图?0=没有生成;1=生成了
  211. //生成大图的条件:邓金生要求生成、或廉永健识别失败0.91、0.92
  212. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  213. public byte[] AI_ver; //由日期改为->类型加版本号
  214. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1200)] // CNN_output_array[200][6] 转成一维数组
  215. public ushort[] CNN_output_array; //10(本次结果)CNN网络的输出数据
  216. public byte num_conf_valid_target; //11(本次结果)CNN网络的输出数据中有效目标的个数
  217. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] // indicators_regions[10][4] 转成一维数组
  218. public ushort[] indicators_regions; //12(本次结果)存储每个指针区域的xmin、ymin、xmax、ymax坐标值
  219. public ulong MAX_FLOW_PER_HOUR; //每小时的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
  220. public ulong MAX_FLOW_threshold; //当前时间距离上次准确识别时间内的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
  221. public uint UNIT_OF_THE_LAST_NUMBER; //尾数单位的含义,最小单位1分升,1dL, 0.1L(万分之一立方)
  222. public float center_x; //表具中心点x
  223. public float center_y; //表具中心点y
  224. public float image_zoomrate; //图像放大倍率,中心点为拟合圆圆心
  225. public float bright_factor; //图片亮度
  226. public byte meter_type; //仪表类型(0:不是水表图片,1:数字+指针,2:全指针 3:全数字)
  227. public ulong result_of_1st_part; //数字+指针水表中“数字”部分读数;全指针水表中“黑色”指针部分的读数;全数字水表中“数字”部分读数
  228. public ulong result_of_2st_part; //数字+指针水表中“指针”部分读数;全指针水表中“红色”指针部分的读数;全数字水表中“数字”部分读数
  229. public ulong offset_1st_of_result; //暂时不用,数字+指针水表中“数字”部分的变化量;全指针水表中“黑色”指针部分的变化量
  230. public ulong offset_2nd_of_result; //数字+指针水表中“指针”部分的变化量绝对值;全指针水表中“红色”指针部分的变化量
  231. public byte compress_jpg_index; //本次压缩的使用的索引
  232. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
  233. public ulong[] history_digit_statistics;
  234. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  235. public ulong[] predicate_value;
  236. public byte is_clean_history;
  237. }
  238. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  239. public struct SmallImage
  240. {
  241. public ushort size_of_JPEG_data; //01(本次结果)数字区域的JPG数据长度
  242. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 841)]
  243. public byte[] JPEG_data; //02(本次结果)数字区域的JPG数字部分
  244. public byte number_region_index_of_header; //03(本次结果)JPG压缩头编号 (如果此值0-9,说明是彩色图,JPG文件头589字节;10-19,说明是灰度图,JPG文件头514字节)
  245. public int image_height; //04(本次结果)图像高度
  246. public int image_width; //05(本次结果)图像宽度
  247. }
  248. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  249. public struct BigImage
  250. {
  251. public ushort size_of_JPEG_data; //01(本次结果)JPG格式的整张图片数据长度 (包括JPG数据, 包括文件头)
  252. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50 * 1024)]
  253. public byte[] JPEG_data; //02(本次结果)JPG格式的整张图片(包括JPG数据, 包括文件头)
  254. public byte whole_image_index_of_header; //03(本次结果)JPG压缩头编号。(如果此值0-9,说明是彩色图,JPG文件头589字节;10-19,说明是灰度图,JPG文件头514字节)
  255. public ushort image_height; //04(本次结果)图像高度
  256. public ushort image_width; //05(本次结果)图像宽度
  257. }
  258. // 声明打印回调的委托
  259. public delegate void PrintfCallback(string message);
  260. //已改为使用动态加载方式,暂时把静态的注释掉
  261. // 引入 C 函数
  262. [DllImport("freeAI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  263. public static extern int recognition(
  264. [In] short[] rgb565,
  265. ref BeforeAI beforeAI,
  266. ref AfterAI afterAI,
  267. ref SmallImage smallJpg,
  268. ref BigImage bigJpg,
  269. [MarshalAs(UnmanagedType.LPWStr)] string modelPath,
  270. PrintfCallback callback
  271. );
  272. }
  273. }