
写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。! z. a/ g/ P: q! M6 ~6 N7 {2 z3 @5 U GUI_Init();1 |1 r# D# i" R1 h GUI_SetBkColor(GUI_BLUE_98);$ ]" o' d& Z. ]0 I1 X1 y GUI_Clear(); GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);+ T! p1 f( k* z: b" a6 e/ M$ d SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); if(SDRes!=FR_OK) {5 p: S% i2 j" K5 z4 h' \; Z Error_Handler(); }" w: y* y3 i" N" ] MX_X_CUBE_AI_Process();' T$ S* u( D9 D8 L- G7 [ /* USER CODE END 2 */* I6 q ~ o5 F7 K+ A/ u /* Infinite loop */& A( b! K/ n$ s /* USER CODE BEGIN WHILE */% p' _7 j) x. j, W# g J: m while (1)$ G6 ]1 y) O; y0 G! B { /* USER CODE END WHILE */ GUI_Delay(10);6 j2 t; n% n3 N: X, l& P /* USER CODE BEGIN 3 */8 S7 j% Q" b. X8 S } 简单的主函数。1 W0 m, ^; w% h' X $ y) u) s( }; i) m 进入MX_X_CUBE_AI_Process();, M' q: f6 ^; p( k% | - z4 \0 {/ S6 w3 C/ k2 a ai_buffer ai_input; ai_buffer ai_output;! v1 F3 j7 L W, M ai_i32 batch;+ J+ ?& ]6 q7 D; q$ S! N2 b char str_tmp[16];# C7 P ]. h$ w) f for(uint8_t i=0; i<10; i++) {( q3 H2 I! T- ?2 ] sprintf(str_tmp,"%1d.bmp",i); _ShowBMPEx(str_tmp); LCD_ShowBMP(str_tmp);0 A* |: c3 m3 q' s9 Q( K for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ ) {* ~2 G8 D. g* n" y in_data[i] = *bmpBuffPtr++;3 v b1 D" f3 z3 ~$ | }( M# Z: o1 e$ z ai_input.n_batches = 1;0 F: O( J& W8 }3 T# T/ g2 y$ W, r ai_input.data = AI_HANDLE_PTR(in_data); ai_output.n_batches = 1; ai_output.data = AI_HANDLE_PTR(out_data); Z* U' E8 \+ ^" Z% C batch = ai_lenet_run(handel, &ai_input, &ai_output); 8 [- e9 x' [) _' z if (batch != 1) {. Z) `; y" f* ^" j% G, Q: n; b err = ai_lenet_get_error(handel); if( err.code ) {! R: u; s. G& M y6 V' }) \/ h while(1); }& Y/ B2 [& o/ O) \: L } uint8_t count=0;1 E: `1 I" c' j8 r4 W7 U for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++) { if( out_data[i] >=0.9f) { sprintf(str_tmp,"Num:%d",i);1 m; c" m( Q9 i$ L; f GUI_SetFont(GUI_FONT_32B_ASCII);+ I$ [8 m8 H! s/ Y GUI_DispStringAt(str_tmp,200,0); GUI_SetFont(GUI_FONT_16B_ASCII); count++;) g, i) \: W6 s2 P- D; \9 O }8 o3 k' w3 U* X1 i) s } if(count!=1)+ y* y1 }+ z; d8 @9 \ { GUI_SetFont(GUI_FONT_32B_ASCII); GUI_DispStringAt("err",200,0);3 ]/ g, X9 ?7 a GUI_SetFont(GUI_FONT_16B_ASCII); }& C" r% b; w5 E6 t6 n free(bmpBuffPtr);6 o* v' c" }$ q% J( X HAL_Delay(2000);. e3 n* P( }, @* z" p9 X8 L: c } 熟悉STemwin的大佬肯定知道我在干嘛,不断的读取SD卡中的bmp文件,然后显示,并且通过ai_lenet_run函数得到识别结果,输出是static ai_float out_data[AI_MNETWORK_OUT_1_SIZE]; 0-9有十个识别结果,这个向量大小是十。调试程序时,输出不像是我在PC ubuntu caffe环境中的输出结果,PC上主要是以softmax得到每个类别的置信度,所以PC上向量肯定全部都有值,置信度最高即为模型结果。在MCU上,输出结果只有零和一。让我很奇怪,既然是ai_float 型 何必不输出 所有的置信度。后面我将继续挖掘。4 o" N2 c' ~+ c# }& k& e, y0 k 流程介绍完毕,下面说一说cubeAI的主要函数。 ai_lenet_create(&handel, NULL);/ x# K# f E4 K Y O ai_lenet_get_info(handel, &report);) ]# ]2 J: |' f# H) j, A ai_network_params params = {- y/ J q' y$ z) u6 y4 b AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取 AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数1 F# Q( w) P1 J. a5 z };9 l; A, W0 v0 T ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。# w: m" H7 S2 m; z err = ai_lenet_get_error(handel);4 q+ Q' k3 x5 h batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批& d, r# k0 i( ~ , v8 f% o: t+ r, {" v: `# h7 s 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。- O5 I( I8 B$ L( m6 J- q 附件:工程源码。1 R, q" W' d5 ^! }8 Z+ X ; D( ~/ p( f' g) s. \: ?1 N4 {8 i& [ |
Minist.rar
下载10.2 MB, 下载次数: 150
【STM32N6570-DK评测】1.开箱测评
【STM32N6570-DK评测】1.你好N6
实战经验 | STM32 AI Model Zoo 的安装及实例介绍
【STM32H7S78-DK评测】移植AI框架TensorFlow【DSP指令加速篇】
【STM32H7S78-DK评测】移植AI框架TensorFlow【下篇】
【STM32H7S78-DK评测】移植AI框架TensorFlow Lite【上篇】
【STM32H7S78-DK评测】移植边缘AI推理框架——TFLM(TensorFlow Lite for Microcontrollers)上篇
破解边缘AI硬件与软件挑战,意法半导体解读三大创新要点
意法半导体助力企业产品智能化,加快边缘人工智能应用
STM32不至于芯,2023济南站研讨会
谢谢支持