#ifndef _READING_RECOGNITION_H_ #define _READING_RECOGNITION_H_ #include "stdio.h" #include "math.h" #include "string.h" #include "stdint.h" #include "stdlib.h" //#include "aimr_config.h" //---------------------------------------------------------------------------------------- #define IMPOSSIBLE_MAX_VALUE 99999999990000 //(uint64_t):水表永远不可能达到的最大值,99999999990000代表10位水表的最大值。为什么14位呢?因为在我们的计算中单位以公升计算,这样避免了浮点运行造成的精度损失 #define IMPOSSIBLE_VALUE 888 //(int16_t):(1)数组中行数据无效标志值;(2)不可能出现的旋转角度(合理的角度=[-359,359]);(3)不可能出现的坐标值(合理的坐标值=[0,319]) #define IMPOSSIBLE_NUM_NUMBER 88 //(uint8_t):水表中不可能出现的数字(指针)个数(合理的个数=[0,10]) #define BMP_BRIGHT_FACTOR_DEFAULT (1.2f) #define ONE_STERE 10000 //1立方米 = 10000立方分升 //320BMP的大小 #if 0 #define BMP_SIZE_320BMP (320*320*3) extern uint8_t runapp_buffer[1536*1024]; uint8_t *mBuffer1_320BMP = runapp_buffer; uint8_t *mBuffer2_320BMP = runapp_buffer + BMP_SIZE_320BMP; uint8_t *mBuffer3_320BMP = runapp_buffer + BMP_SIZE_320BMP*2; #endif typedef int (*printf_ai_log)(const char *format, ...); #pragma pack(1) typedef struct { uint8_t METER_TYPE; //仪表类型, // uint8_t NUM_NUMBERS; //数字个数(黑色+红色) uint32_t UNIT_OF_THE_LAST_NUMBER; //最后一个数字的单位,最小单位1分升,1dL, 0.1L(万分之一立方) // uint8_t NUM_INDICATORS; //指针个数(黑色+红色) uint32_t UNIT_OF_THE_LAST_INDICATOR; //最后一个指针的单位,最小单位1分升,1dL, 0.1L(万分之一立方) // uint32_t HOURS_FORM_LAST_1278; //当前时间 离上一次1278结果的 间隔小时数 uint64_t MAX_FLOW_THRESHOLD; //当前时间距离上次准确识别时间内的最大流量,最小单位0.1L(1m³/10000), (万分之一立方) // uint64_t AI_RESULT; //最终的、经过校正步骤的结果,单位分升dL。 IS_UPLOAD_RED_IND_PART决定:AI_RESULT 是否等于 AI_COMPLETE_RESULT uint64_t AI_COMPLETE_RESULT;//最终的、完整的、经过校正步骤的结果,单位分升dL。 所谓完整是指:数字+指针表=数字和指针部分的结果;全指针表=黑色指针和红色指针的结果 // uint16_t CONFIG_NUM_REGION[8];//数字区域的左上角(x,y),左下角(x,y),右下角(x,y),右上角(x,y) // uint16_t CONFIG_TWO_IND[4];//配置的第一个指针、最后一个指针的坐标(x,y),(x,y) // uint16_t CONFIG_METER_REGION[4];//配置的表盘区域的xmin、ymin、xmax、ymax坐标值 // float BRIGHT_FACTOR; //图片亮度 // uint16_t BIG_JPG_SIZE; //大图JPG图像的最大字节数 uint8_t USE_TEST_JPG_FLAG; //AI输出JPG图是,使用测试图标记,1:使用,0:不使用 // uint8_t COMPRESS_JPG_INDEX;//上一次JPG的压缩索引 // uint8_t IS_UPLOAD_RED_IND_PART; //是否上传红色指针部分的数据(0:不上传;1:上传;默认1) // uint8_t IS_NUM_IN_UPPER;//数字区域在图像的上半部分还是下半部分?(0:上半部分; 1:下半部分; 默认0) // printf_ai_log printfAiLog; //上传日志的printf回调函数 }Before_AI_struct_RX; #pragma pack() // ----------调用---------------- // AI程序内部可以这样处理(不是在这个头文件中) // 1.定义 // #define printf PrintAiLog // printf_ai_log PrintAiLog; // 2.赋值 // PrintfAiLog = before_AI.printfAiLog; // 3. // 正常调用printf即可 // ---------------------------- //---------------------------------------------------------------------------------------- #pragma pack(1) typedef struct { uint8_t METER_TYPE; //仪表类型,模型类型 uint8_t RESULT_TYPE; //结果类型 // uint64_t AI_RESULT; //最终的、经过校正步骤的结果,单位分升dL。 IS_UPLOAD_RED_IND_PART决定:AI_RESULT 是否等于 AI_COMPLETE_RESULT uint64_t INIT_AI_RESULT; //网络直接输出的、没有经过校正的最初识别结果,单位分升dL uint64_t AI_COMPLETE_RESULT;//最终的、完整的、经过校正步骤的结果,单位分升dL。所谓完整是指:数字+指针表=数字和指针部分的结果;全指针表=黑色指针和红色指针的结果 // uint8_t IS_VALUE_CHANGED; //与上一次比较,水表读数是否在变化?变化范围包括数字+指针部分,也就是比较上次和本次的 AI_COMPLETE_RESULT // uint8_t AI_RESULT_ARRAY[2][12]; //03(本次结果)int数组的识别结果(2维数组,第一行元素为类别、第二行为识别概率) // uint8_t COMPRESS_JPG_INDEX;//上一次JPG的压缩索引 // uint8_t AI_VER[4]; //AI程序的数字版本号 //--2025年4月25日新增--------------------------- uint16_t CONFIG_NUM_REGION[8];//数字区域的左上角(x,y),左下角(x,y),右下角(x,y),右上角(x,y) // uint16_t CONFIG_TWO_IND[4];//配置的第一个指针、最后一个指针的坐标(x,y),(x,y) // uint16_t CONFIG_METER_REGION[4];//配置的表盘区域的xmin、ymin、xmax、ymax坐标值 }After_AI_struct_TX; #pragma pack() #pragma pack(1)//水利所小图841RGB typedef struct { uint16_t size_of_JPEG_data; //01(本次结果)数字区域的JPG数据长度 unsigned char JPEG_data[841]; //02(本次结果)数字区域的JPG数字部分 uint8_t number_region_index_of_header; //03(本次结果)JPG压缩头编号 (如果此值0-9,说明是彩色图,JPG文件头589字节;10-19,说明是灰度图,JPG文件头514字节) int image_height;//04 (本次结果)图像高度 int image_width;//05 (本次结果)图像宽度 }Num_Region_Image_ShuiLiSuo_struct_TX; #pragma pack() //---------------------------------------------------------------------------------------- #pragma pack(1)//大图5700RGB typedef struct { uint16_t size_of_JPEG_data ; //01(本次结果)JPG格式的整张图片数据长度 (包括JPG数据, 包括文件头) unsigned char JPEG_data[50*1024]; // 02(本次结果)JPG格式的整张图片(包括JPG数据, 包括文件头) uint8_t whole_image_index_of_header; //03(本次结果)JPG压缩头编号。(如果此值0-9,说明是彩色图,JPG文件头589字节;10-19,说明是灰度图,JPG文件头514字节) uint16_t image_height;//04 (本次结果)图像高度 uint16_t image_width;//05 (本次结果)图像宽度 }Whole_Image_struct_TX; #pragma pack() //---------------------------------------------------------------------------------------- #pragma pack(1)//拷机平台显示的 JPG图像 typedef struct { // JPG图像部分 uint16_t size_of_JPEG_data; //01(本次结果)数字区域的JPG数据长度 unsigned char JPEG_data[20000]; //02(本次结果)数字区域的JPG数据部分 uint8_t number_region_index_of_header; //03(本次结果)JPG压缩头编号 (如果此值0-9,说明是彩色图,JPG文件头589字节;10-19,说明是灰度图,JPG文件头514字节) uint16_t image_height;//04 (本次结果)JPG图像高度 uint16_t image_width;//05 (本次结果)JPG图像宽度 }Num_Region_Image_KaoJiPingTai_struct_TX; #pragma pack() //---------------------------------------------------------------------------------------- #pragma pack(1)//2022年10月20日廉永健为了作为训练数据集使用的 BMP图像 typedef struct { uint16_t size_of_BMP_data; //01(本次结果)数字区域的BMP 数据长度 unsigned short BMP_data[320*120]; //02(本次结果)数字区域的 BMP 565彩色图 数据部分 }BMP_Image_struct_TX; #pragma pack() //---------------------------------------------------------------------------------------- //函数名:readingRecognition():进行AI识别的入口参数 //输入参数1:unsigned short bmp_320240_data[]:摄像机拍摄的水表图像,大小为320*240 //输入参数2:Before_AI_struct_RX *param_before_AI: 水表配置信息,以及上次检测结果 //输入参数3:After_AI_struct_TX *param_after_AI: 保存本次的检测结果 //输入参数4: Num_Region_Image_ShuiLiSuo_struct_TX *param_num_region_image_ShuiLiSuo_AI:水利所上传JPEG小图像:841字节 //输入参数6: Whole_Image_struct_TX *param_whole_image_AI:保存生成的完整的水表JPEG大图像:4860字节 void readingRecognition( unsigned short bmp_320240_data[],//1 Before_AI_struct_RX *p_before_AI,//2 After_AI_struct_TX *p_after_AI, //3 Num_Region_Image_ShuiLiSuo_struct_TX *p_num_region_image_ShuiLiSuo_AI,//4 Num_Region_Image_KaoJiPingTai_struct_TX *p_num_region_image_KaoJiPingTai_AI,//5 Whole_Image_struct_TX *p_whole_image_AI,//6 BMP_Image_struct_TX *p_BMP_Image_TX //7 ); #endif /* _READING_RECOGNITION_H_ */