写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。+ z2 J/ _$ u) D' @ 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。- S7 d7 X) U; y8 B : A) g& e! q, K5 Z2 I GUI_Init();+ q3 i- q. k% B% C a4 A& e- R GUI_SetBkColor(GUI_BLUE_98); GUI_Clear();2 k6 c5 d/ w; f; B. } : F2 P& \2 E! s5 J; b GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2); SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); D, n* R+ [* z% I if(SDRes!=FR_OK)# d! Z1 I# c8 p) Z% a- N( M9 M {/ F% B$ `9 A/ S% _9 l Error_Handler(); }2 k* b! Q: w7 F1 H2 R' z1 q7 z1 k MX_X_CUBE_AI_Process(); [; s- _; o& W |1 w( ] /* USER CODE END 2 */7 V% ^- o! O1 |" P5 i \# G- h /* Infinite loop */0 J) U( k$ O% x3 Y" y /* USER CODE BEGIN WHILE */$ l5 Q9 [, ]2 w4 m* T i7 t' B while (1)8 X/ s" {9 e7 P, `( k* ~8 o! H& g3 \& H- U { /* USER CODE END WHILE */4 K- }# H1 A2 {! r5 D4 ^ GUI_Delay(10);' P7 k4 T* v5 b. X b1 ~, p1 `8 l /* USER CODE BEGIN 3 */ } - E; w1 R; {/ m; D) {3 u ^ 简单的主函数。 # B* g$ x8 j% U3 j2 d 进入MX_X_CUBE_AI_Process(); ) B' z3 B. f* S+ Y: D ' E4 N' h! ?" N$ e( ~' L ai_buffer ai_input; ai_buffer ai_output; ai_i32 batch;/ J% E$ U) n3 d$ v0 E! l+ j char str_tmp[16];# R3 r4 ~( j$ z, M% Y0 X for(uint8_t i=0; i<10; i++) {) ~3 c0 G+ z5 M3 M sprintf(str_tmp,"%1d.bmp",i);6 o% O) K6 o" k/ M! I! D _ShowBMPEx(str_tmp); LCD_ShowBMP(str_tmp);! K$ [; r( b* Q9 R. d for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ ) {8 A/ A, t( V9 B! F8 f( @ in_data[i] = *bmpBuffPtr++; }) f" O1 L( [4 x1 m8 F ai_input.n_batches = 1;/ a1 z. h2 j! q4 Y2 v9 J# i3 l ai_input.data = AI_HANDLE_PTR(in_data);* R# B; t5 C9 @ ai_output.n_batches = 1; ai_output.data = AI_HANDLE_PTR(out_data);( K; |4 X3 r O batch = ai_lenet_run(handel, &ai_input, &ai_output); if (batch != 1) 1 r) C; f" Z* o# o7 m { P* Y% |: Q' e% D err = ai_lenet_get_error(handel);& e( z; L6 w9 N! C8 A: M5 c if( err.code ) {& H' z! i. a1 x: j while(1);% k0 W0 f o* Q7 F; U } } uint8_t count=0; for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)8 A. w5 G4 B/ g {' j1 j5 z% N1 b o: w c if( out_data[i] >=0.9f) { sprintf(str_tmp,"Num:%d",i);- R( }' ]1 A X8 \( l8 w" o1 w GUI_SetFont(GUI_FONT_32B_ASCII); GUI_DispStringAt(str_tmp,200,0); GUI_SetFont(GUI_FONT_16B_ASCII);- L6 ~3 N6 H/ V count++;3 o1 T6 m5 r, j9 i5 q$ i } }) t- O* O& h, E/ ^! K1 a/ N if(count!=1) { GUI_SetFont(GUI_FONT_32B_ASCII);+ r/ r, x0 k! r! J) s GUI_DispStringAt("err",200,0);( ^0 P% `( H1 f. m8 z, D$ I) E GUI_SetFont(GUI_FONT_16B_ASCII);: d1 t$ G! D5 x9 w }3 I" \, b( N, {& s( E; ?* q free(bmpBuffPtr); HAL_Delay(2000);2 w v$ s+ X8 m S2 e: D3 N } 熟悉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 型 何必不输出 所有的置信度。后面我将继续挖掘。/ }3 g0 r* {, |! e9 \6 W # ^- v, n& ?6 G- _7 B 流程介绍完毕,下面说一说cubeAI的主要函数。 ai_lenet_create(&handel, NULL); ai_lenet_get_info(handel, &report); ai_network_params params = {# |. F& |- n1 ^& U$ H$ O AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取' }% P# L: P! v+ ]; p AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数" Z6 u) o1 f) ~ };. }7 l4 l( i% @/ r, K ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。 err = ai_lenet_get_error(handel);5 f: b' _* c! H( \( A5 L0 r batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批 0 g2 G0 B. G# o% M9 G; \$ Y& N % L# l( Z& E9 E1 p$ r6 C$ v 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。! p. I8 [7 P# N$ B 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。9 {3 g: H4 e1 i6 u 附件:工程源码。- ?' L6 z3 x- Q r& ?+ Q 3 N9 F9 j! h2 D, C% g) {3 l* }2 X |
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
谢谢支持