写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。1 X1 M1 @ D3 } 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。 $ I5 ~# _3 l$ c* j1 g* M" s7 { GUI_Init(); GUI_SetBkColor(GUI_BLUE_98); GUI_Clear(); ) n% w& A8 D; b. v( D5 Y0 C, ? GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);; q$ ^- A8 a. w+ S SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); if(SDRes!=FR_OK)! c3 j O! X4 b( n& _1 _2 C8 b {6 x4 ]+ ^$ ^# k' P& R! ]! ? Error_Handler(); } MX_X_CUBE_AI_Process(); /* USER CODE END 2 */ /* Infinite loop */6 ^& A& }: N: i; ~+ Q /* USER CODE BEGIN WHILE */ while (1) {' {# b( [6 h/ f3 |$ l /* USER CODE END WHILE */ GUI_Delay(10);4 t# W: O2 u0 j$ d$ `4 y* B /* USER CODE BEGIN 3 */) F) f0 o1 e+ x- L- L# l) c( Y } 简单的主函数。; U" b7 n* i7 ^0 A) l- d" I" v$ W9 M 进入MX_X_CUBE_AI_Process(); ; c0 M, V' l4 ?( @2 `$ M! S0 Y, `5 X ai_buffer ai_input;) r. r# m9 O' \. x ai_buffer ai_output;" ?1 g! L8 o- c$ [+ M ai_i32 batch; char str_tmp[16]; for(uint8_t i=0; i<10; i++)" M R0 _, ]. @5 q7 j1 I$ M' f {# N, y2 J' t; X) Q. C+ n sprintf(str_tmp,"%1d.bmp",i);7 _3 {; S" N3 \- O n+ q+ |1 z, n$ V# `: q _ShowBMPEx(str_tmp); LCD_ShowBMP(str_tmp); for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ ) {5 H; y$ b; S5 W2 s+ u in_data[i] = *bmpBuffPtr++; }1 v7 a$ ]3 `( w ai_input.n_batches = 1; o+ G1 E8 U n5 e$ e ai_input.data = AI_HANDLE_PTR(in_data);' P% {4 _; N' K5 J7 } ai_output.n_batches = 1; ai_output.data = AI_HANDLE_PTR(out_data); batch = ai_lenet_run(handel, &ai_input, &ai_output); 6 @& P: z- m. J, R+ c if (batch != 1) {+ [, |( M; e; B* |+ \3 {" ~ err = ai_lenet_get_error(handel);# K8 Q K" W1 _# N if( err.code ) { while(1); } } uint8_t count=0;% f6 h I* {1 s5 E% ] for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)$ @. I/ x: r8 z3 H {$ u" ], d% G; ^% @% V if( out_data[i] >=0.9f)1 L p+ {3 Y3 `- ]% D {3 }6 ?5 h" k4 P5 A sprintf(str_tmp,"Num:%d",i);5 c. Z. {; Z$ u' \ GUI_SetFont(GUI_FONT_32B_ASCII); {, }. q; ?5 O0 r5 ~9 V GUI_DispStringAt(str_tmp,200,0);! F% ?2 q3 N$ w9 n GUI_SetFont(GUI_FONT_16B_ASCII);* Z2 F2 B) @8 j& |6 \+ \4 Y count++;$ l# u. @2 g. K% T% K }3 f( j& e8 H" A. s, A$ u# s' x } if(count!=1)/ F8 }! b r* K8 y+ {2 ` { GUI_SetFont(GUI_FONT_32B_ASCII);& ^6 u" H7 ?6 d2 f GUI_DispStringAt("err",200,0); GUI_SetFont(GUI_FONT_16B_ASCII); }# A, F7 }) G& k/ P free(bmpBuffPtr); HAL_Delay(2000); } 熟悉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 |" W: Z8 A8 O) }# ^ 流程介绍完毕,下面说一说cubeAI的主要函数。 ai_lenet_create(&handel, NULL);+ ]3 [5 x6 {& W/ Q. ]) }9 ]. X/ C ai_lenet_get_info(handel, &report); ai_network_params params = { AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取6 Y5 X" A9 }0 c AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数9 B* z; S/ r8 N0 }. I7 g' n9 m( r }; v# _: M! j& e0 \! M ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。 err = ai_lenet_get_error(handel); {3 L, E% u$ N: A8 n. d * t1 G" ? p9 h# V batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批5 x5 r+ i# [5 A: N7 [2 A) H 3 H& h. V4 W" ?+ R$ H1 [6 [ 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。3 G/ F+ S; ]& p$ Z9 b 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。 {* T2 V. I9 r0 m8 O: D 附件:工程源码。3 y) \9 O' l/ Y, K , r1 F. j4 C9 _: ~1 u9 ^ |
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
谢谢支持