你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

Cube.AI【3】——手写识别demo代码

[复制链接]
lebment 发布时间:2019-5-17 23:14
  写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。
" ^% l" C0 ?  s6 d1 u5 y  接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。
5 B( u: z' T3 F% @8 D
! S6 ?2 g6 g% `$ X                GUI_Init();
. H% I( l/ Q) t! Z$ x                GUI_SetBkColor(GUI_BLUE_98);
' w; d: D' u0 w                GUI_Clear();
$ p- R5 j& c! J       
+ B0 b) a1 d0 X( s8 \, H2 A                GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);
1 v4 e7 ^5 m2 t1 f" ]                SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0);
4 c4 ~! i# c0 E; |: g                if(SDRes!=FR_OK)
* w0 ~( a% p1 J: v. L1 _7 d/ m# R                {0 \2 c/ e: k/ \7 w6 D. G: A- R, d& j
                Error_Handler();
1 y; @) K5 n$ `) m+ Q                }
1 }6 ]) o% ]$ g" v# T4 M5 ^  MX_X_CUBE_AI_Process();4 y/ B( v9 ]7 Q9 f, k6 Z
  /* USER CODE END 2 */$ L. W: j: t- p$ S4 p8 g
  /* Infinite loop */8 l- Q- a. X) N# {
  /* USER CODE BEGIN WHILE */5 r% Y" w5 @/ D. S! C
  while (1)( k! s0 w: S3 [6 P7 A
  {) H2 j, V" W7 R7 t$ L
    /* USER CODE END WHILE */$ ^) ~( `# I3 }4 I
                         GUI_Delay(10);
0 D0 Z: I3 r( ~    /* USER CODE BEGIN 3 */. i. t' v  l$ H
  }. M# x) w3 s  N  Q. A$ Q

+ N" _9 W$ h+ Q简单的主函数。
! x+ y$ Q: b: |3 @. K' U. N+ n- c' a- B3 r2 f2 `
0 K+ }, M. ~8 m, ^- a" [
  进入MX_X_CUBE_AI_Process();0 B5 Y% i; W, o: {6 X% I- K

( K9 h0 ?$ P2 U3 N2 l  V( B+ E0 K  w4 C/ b+ k8 g% U* C
    ai_buffer ai_input;
1 ], v' c5 D7 W/ Y    ai_buffer ai_output;7 v; F# S. m. W8 T
    ai_i32 batch;
5 `5 B: ~; r' n( C; m    char str_tmp[16];. C3 ~! }# v, d8 F
     for(uint8_t i=0; i<10; i++)
* z" D$ j  ^( u% o2 G8 w+ T8 X3 O            {) ]. W3 M4 w! \. _; ?
                                                sprintf(str_tmp,"%1d.bmp",i);
9 m$ ?( Q1 c3 g                                          _ShowBMPEx(str_tmp);
) f: _- p% j( n- R                                                LCD_ShowBMP(str_tmp);$ h0 E# C: b$ U3 ]) Y! X
                                                for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ )9 b& i; a" R  y) w' j
                                                {4 f3 r; o7 z3 s* K
                                                                in_data[i] = *bmpBuffPtr++;( v& r  R6 D9 i  J( P$ f, G
                                                }! M* J  s6 P5 T$ F
                                                ai_input.n_batches  = 1;
8 _+ O! v% [; N: @) V! W9 t% k' m% t' _2 e                                                ai_input.data = AI_HANDLE_PTR(in_data);; d0 x; l+ q5 H* n/ V1 j0 ?
                                                ai_output.n_batches = 1;
! |+ r2 V) Y! I  f                                                ai_output.data = AI_HANDLE_PTR(out_data);
6 @1 I, ~& x, ~) @2 |                                                batch = ai_lenet_run(handel, &ai_input, &ai_output);
/ h: |2 l" y0 ]; L$ h" |0 n                                                if (batch != 1) , x* \0 o( \" g8 i
                                                {$ f$ Y4 I+ {. ^
                                                                err = ai_lenet_get_error(handel);& V" v7 }4 {& ^+ L( N: t; n8 \" I
                                                                if( err.code )8 s3 A7 T7 V2 q& J2 m2 F
                                                                {9 y% Y, A  j5 @* V5 y# b: }! q
                                                                                while(1);
; P. `4 s9 `! b7 N                                                                }; m2 x$ R) `( Z* v3 K: F$ L% j
                                                }
/ z: P4 R% F, F' w$ l8 ?                                         uint8_t count=0;
2 z. N2 x! H, h; j  T) P                                         for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)
$ h; ]0 V3 t7 P/ y                                                {6 p* J/ \4 r% b0 C
                                                  if( out_data[i] >=0.9f)' ?% X9 s$ o5 o& j; R$ _% j
                                                                {
+ S7 T( g. K7 R& Y5 B( t1 G                                                                         sprintf(str_tmp,"Num:%d",i);( M0 e( z& s+ B, }2 G. h
                                                                         GUI_SetFont(GUI_FONT_32B_ASCII);: m5 b6 Z) M: v* B
                                                                  GUI_DispStringAt(str_tmp,200,0);
1 D5 c! ?. `( N0 z; a6 \                                                                         GUI_SetFont(GUI_FONT_16B_ASCII);. j7 d% P! H. G2 S# I2 P
                                                                         count++;- a$ x8 ?$ x( [9 W" x, ^/ W7 O  z2 u- g  M
                                                                }/ h) n* w9 s* r7 c/ o  p4 A
                                                }7 A; V% {# t5 y3 v$ P. ~
      if(count!=1)9 g7 _8 K9 `  a& o. m
                                                {' t5 P  @) K( H8 P( E8 j# e$ e
                                                        GUI_SetFont(GUI_FONT_32B_ASCII);
. H( I8 N7 v: o" t8 t9 k5 C                                                        GUI_DispStringAt("err",200,0);( p' n/ N% b& N9 k
                                                        GUI_SetFont(GUI_FONT_16B_ASCII);! D5 y" |5 g) E  V3 U
                                                }3 ]3 Z( E/ {; k' Y8 \
                                                free(bmpBuffPtr);
' K7 m( h- I" g5 N3 O. s$ a                                                HAL_Delay(2000);
, L) ?: ^+ ]- U( c' ]                                        }
8 A; G/ r# r: I7 q: Q
! Z$ T* R5 A3 X5 ~+ }  a' m      熟悉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 型 何必不输出 所有的置信度。后面我将继续挖掘。
" b. E/ h% G# h/ _+ t9 ^/ Z2 C. N
; X% D5 {3 R+ M       流程介绍完毕,下面说一说cubeAI的主要函数。. g8 W* ?3 ^3 A  Y/ `- J$ i- H7 C
       ai_lenet_create(&handel, NULL);6 |3 ?* k" c# T+ C+ r2 }. B7 I
      ai_lenet_get_info(handel, &report);) G; I: k$ c- W/ F6 q) ~$ a7 w
          ai_network_params params = {
  {  I& z# Z% F                                                          AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()),    //权重的获取/ O* u1 [6 g4 b  c0 S8 ~4 ^/ Y: [
                                                        AI_LENET_DATA_ACTIVATIONS(activations)     // 激活函数1 T) w* h' e: i7 M! L* N
                                                };, ~0 Y  u3 U, z$ t1 u9 s
          ai_lenet_init(handel, &params);  //lenet的初始化,估计是申请内存什么的,写flash。% B6 Y3 f6 Y( T; K
                                                                         err = ai_lenet_get_error(handel);
/ u5 m3 c0 H5 q) g2 [0 E9 b
$ @" {( u  x+ ?" a9 A: Z         batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批
9 @" d2 S5 p# ~# ]* x$ w/ m* R
- a$ r. l) W% t2 V" H4 w# r5 N$ A1 e' \# x
         总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。/ O: H/ }5 r9 U' a
        这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15!  期待MP1,玩玩不用压缩的AI。
9 i. z" {/ I" x        附件:工程源码。
- @7 L7 @  m% f* H+ C4 c
9 K  g+ z# v6 \; W' _' `. J" Q3 `4 b2 K! ]0 |

Minist.rar

下载

10.2 MB, 下载次数: 150

收藏 评论7 发布时间:2019-5-17 23:14

举报

7个回答
happier_1995 回答时间:2020-7-30 08:17:50
兄弟,您这个代码运行最后的准确率能达到多少?我今天试了一下,10个数有9个识别错误的。
Bowen 回答时间:2019-5-18 09:02:09
支持下
lebment 回答时间:2019-5-18 10:34:28
strang 发表于 2019-5-18 09:02, C- Q& u7 \) E4 F+ u
支持下

2 k( a8 S1 j! e6 K- J! V( E" A& e谢谢支持
STMCU-管管 回答时间:2019-6-3 15:31:26
支持支持
TLLED 回答时间:2019-6-11 09:40:41
支持下         
happier_1995 回答时间:2019-6-21 14:03:53
加油楼主,我也在研究这个CUBE AI,进度没有你快
sumoon 回答时间:2021-9-11 11:11:24
学习学习!
( d. b6 X& R' t3 k4 j; C# f
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版