
写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。4 ^* k' N# ^) |+ |( a4 A" ^ . a# j) W1 k* ^ GUI_Init();6 V! P* R' E5 L* f8 i* K GUI_SetBkColor(GUI_BLUE_98);' [: {5 C. b; ` GUI_Clear();5 x" g0 W: z, r2 q0 J, j3 ^% Y / u, U- \' D" i3 F6 \, _, Z1 | GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);8 N" G) B: Z6 y SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); if(SDRes!=FR_OK)' Y+ \. o! [. K- \* r$ e { Error_Handler(); }8 M' w |$ _" S! N9 [ MX_X_CUBE_AI_Process();$ G5 R4 U" l; i. K0 t6 K0 |" @ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */+ z1 Z) w6 @6 |/ j, r" x/ ?5 m! @ while (1)9 v/ I% L5 Q9 M8 k { /* USER CODE END WHILE */! i+ H+ J- K: u9 h: g9 } GUI_Delay(10);( q5 Y7 S+ R" R! X! k) M& b /* USER CODE BEGIN 3 */ }* `4 \; ]" p3 }8 O ( i' \$ T( y1 F- R$ S9 |( M 简单的主函数。 2 c/ x+ p) B9 ` 进入MX_X_CUBE_AI_Process();3 y4 w _ u8 m) R* r, i: L& U 9 w# X0 v" i* O ai_buffer ai_input;2 R. H! A& \5 N: t7 Y ai_buffer ai_output; ai_i32 batch;% G0 V/ I3 G$ A& N) n5 |1 y char str_tmp[16]; for(uint8_t i=0; i<10; i++)( P( z$ R2 t9 I5 X ^% `1 R; K { sprintf(str_tmp,"%1d.bmp",i); _ShowBMPEx(str_tmp);$ T* z3 C( K( A$ D4 \% x LCD_ShowBMP(str_tmp);+ c! _& c4 V2 ^" r' g for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ )6 |# c- @5 G. ? {( _; c# h5 N% H! F7 P5 w in_data[i] = *bmpBuffPtr++; } ai_input.n_batches = 1; ai_input.data = AI_HANDLE_PTR(in_data);$ t, \# N( J# U! Y' d! G. | ai_output.n_batches = 1; ai_output.data = AI_HANDLE_PTR(out_data); f, o6 r4 u% ^# V' P% X- C3 s; { batch = ai_lenet_run(handel, &ai_input, &ai_output); if (batch != 1) + r! U& e0 L* b { err = ai_lenet_get_error(handel);# m9 G% o6 s; c Z! S8 x if( err.code ) { while(1); } } uint8_t count=0;0 v$ P( X4 }. V! a for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++) {! f& l0 b: P9 S if( out_data[i] >=0.9f) { sprintf(str_tmp,"Num:%d",i);" D7 [ q% o0 i5 j6 d" C; C h! _ GUI_SetFont(GUI_FONT_32B_ASCII);0 u& |7 e3 d! V1 D" d9 ^ GUI_DispStringAt(str_tmp,200,0); GUI_SetFont(GUI_FONT_16B_ASCII); count++; }1 f! ?/ a B+ Q& P7 \$ R; a# j8 G } if(count!=1)8 B- U, {8 S0 c3 U, v' P/ } {+ ~% s0 c: c8 w* F GUI_SetFont(GUI_FONT_32B_ASCII);+ q- i" ^. d, f) m% J GUI_DispStringAt("err",200,0); GUI_SetFont(GUI_FONT_16B_ASCII);. o5 Z& ^4 \) G& D } free(bmpBuffPtr); HAL_Delay(2000); }$ X$ H) X' J% ~7 N4 e5 @ 熟悉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 型 何必不输出 所有的置信度。后面我将继续挖掘。+ c; Y. Y& K1 Z4 d! d 5 f8 \0 O9 F# w7 [' _ 流程介绍完毕,下面说一说cubeAI的主要函数。! P1 |& z0 N' @- S ai_lenet_create(&handel, NULL);$ M* w2 Y% S6 A8 z* Q* f h ai_lenet_get_info(handel, &report); ai_network_params params = {9 t" q* \4 v- g8 b# V; d. U7 {6 | AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取2 h( m @: w3 t7 A+ V( g AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数 }; ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。( R% q- E* E, U err = ai_lenet_get_error(handel); batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批 . N% t. }+ |6 W' _# H6 a5 S( c% z! E 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。5 V8 u! G: z6 _! i, N& i 附件:工程源码。+ c* q+ F) g2 ]9 \, t, G+ R+ j: x |
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济南站研讨会
谢谢支持