写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。6 |1 b8 D/ w. K. H 5 s9 j3 p Q C6 z# \ W. a GUI_Init(); GUI_SetBkColor(GUI_BLUE_98); GUI_Clear();6 p+ c/ h$ Z. W , [+ M+ \4 x; }2 K GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);9 G: a9 n! R: ?: M0 ], y6 f: y& q SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); if(SDRes!=FR_OK) {5 z$ j/ v" h& K7 B Error_Handler(); }' W$ R4 B* [4 r4 D' H MX_X_CUBE_AI_Process(); /* USER CODE END 2 */! b9 Y# _3 i+ d4 y0 M( k! r. O/ [+ ` /* Infinite loop */" u( c% _1 u& u( S /* USER CODE BEGIN WHILE *// \7 J( i. q8 Z2 U8 K f8 G while (1)+ m7 l5 e* G5 x7 ^1 F$ n/ N2 B { /* USER CODE END WHILE */$ g$ n+ B: b' J; k4 _7 ?+ h. F GUI_Delay(10);! ^$ x2 J3 M2 p! C- p6 i6 v J/ T/ |6 y /* USER CODE BEGIN 3 */ }0 x% z1 u- O* w/ {3 W; G 简单的主函数。 , ^; Q' p8 T* [! N$ U6 K 进入MX_X_CUBE_AI_Process(); ~. ?9 D7 U. ~2 _, D6 X j6 ? ai_buffer ai_input;% r/ Q9 V3 N7 w7 k; ~2 f1 f4 l ai_buffer ai_output; ai_i32 batch; char str_tmp[16]; for(uint8_t i=0; i<10; i++) {4 Z# r7 T" `! {7 I! K8 K sprintf(str_tmp,"%1d.bmp",i); _ShowBMPEx(str_tmp);: K+ z9 b0 p O9 H1 | LCD_ShowBMP(str_tmp); for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ ) {+ T! O- P T: Y% D2 V$ g in_data[i] = *bmpBuffPtr++;; g* S# ?0 W2 U5 _+ x' Z0 M } ai_input.n_batches = 1;6 `0 \8 b: Q& r) I$ I& B3 @ ai_input.data = AI_HANDLE_PTR(in_data); ai_output.n_batches = 1;9 [ f8 Z7 u3 L2 B7 c+ o ai_output.data = AI_HANDLE_PTR(out_data);+ Y* ?+ K3 D' ^/ n- t batch = ai_lenet_run(handel, &ai_input, &ai_output); if (batch != 1) {" {6 d9 q7 V% v4 Q& E. N err = ai_lenet_get_error(handel);0 r" Y, E4 n N if( err.code ). ~/ t8 l! U) ?: r7 E$ J {. c; a8 ~9 h9 X' d while(1);' i( c: N1 u* c( ]+ ~ }0 Q% I' n* d" P! i4 c- J }$ E: x" `5 f. W5 u) V: ~( s! U9 a uint8_t count=0; for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)1 v; J4 b f% M: V! w" b+ H9 C l; | {' C- a: [. ?2 l' H0 }5 h3 R if( out_data[i] >=0.9f)8 O. V- A# _" T9 o {4 g6 r) L& s2 S3 H4 R: [* t9 q1 y( K sprintf(str_tmp,"Num:%d",i); GUI_SetFont(GUI_FONT_32B_ASCII); GUI_DispStringAt(str_tmp,200,0);& _& u7 I+ b2 l+ ]' P2 [5 r/ ]+ F GUI_SetFont(GUI_FONT_16B_ASCII);) e" T' V5 L1 ^& B8 V count++; } } if(count!=1) {7 U, }4 x% q4 g" L6 h w3 t' v GUI_SetFont(GUI_FONT_32B_ASCII);2 X2 x q' v7 T GUI_DispStringAt("err",200,0); GUI_SetFont(GUI_FONT_16B_ASCII);$ _+ D) G/ ^% v+ G: N }8 [/ h& P# h+ f! E# h" e* C$ v free(bmpBuffPtr); HAL_Delay(2000);$ p' o* o9 G ]8 p } / o3 c" J( G6 e, u 熟悉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 型 何必不输出 所有的置信度。后面我将继续挖掘。6 ]6 N% e% q' g: H/ F - C* q: d! v$ `0 S9 f 流程介绍完毕,下面说一说cubeAI的主要函数。& L O3 q* }* B% W4 M7 r) Y! H ai_lenet_create(&handel, NULL); ai_lenet_get_info(handel, &report);6 _) ^& D- W# c; X; _) O* C4 K: `4 `! V ai_network_params params = {( T- F0 G3 k9 a1 f. Z' U% s AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取0 T( c7 l! ?* x6 X; v: ` AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数 };! {6 K7 o' o# w+ l& p5 G, ^ ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。 err = ai_lenet_get_error(handel); ' g( i- p' o# s. Z batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批0 @1 {% A# c* h! } $ d9 m4 |6 M3 c8 g1 B( u 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。0 q0 B g/ O; r 附件:工程源码。, C G; u' j# _$ K- Q6 k% @- Q- e 4 L0 j1 T# @0 \3 T4 W % a3 v4 `2 G- Z- S |
Minist.rar
下载10.2 MB, 下载次数: 150
破解边缘AI硬件与软件挑战,意法半导体解读三大创新要点
意法半导体助力企业产品智能化,加快边缘人工智能应用
哪些传感器嵌入式功能适用于我的应用?
线下实训 | ST端侧人工智能之视觉检测
意法半导体嵌入式 AI 解决方案增加简化机器学习开发的高级功能
【Wio Lite AI视觉开发套件】+摄像头图像采集
全站首个NanoEdge_AI试用(dogs)
线下实训 | ST端侧人工智能之计算机视觉实践课程
Cube.AI【4】cifar10 在魔改Nucleo STMF767平台上的测试
基于STM32的机器学习工具 - NanoEdge AI Studio
谢谢支持