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

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

[复制链接]
lebment 发布时间:2019-5-17 23:14
  写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。
. N/ T! O# R6 W( z7 S/ {- o& ^9 x4 }  接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。: N( p6 Z+ m7 u8 t

: z$ j. G, y) D1 }9 ?/ b- r& z                GUI_Init();
6 e" C) `0 R, L- U. O  Y8 m                GUI_SetBkColor(GUI_BLUE_98);
4 i0 ]3 @. i* {3 Y                GUI_Clear();
* u+ k% M& p0 p, M& X- i" L       
! M2 X! R' q1 [% F                GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);, j. W4 a$ }- D9 h9 J% e* c
                SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0);
+ I6 w& @6 x5 [( ]+ W                if(SDRes!=FR_OK)
5 y, |9 F! T7 O! v: l                {
8 \% I( g5 L7 s* `, Z$ D; K3 Q                Error_Handler();
/ s1 u4 ^4 p* O2 B+ X                }
2 _0 G8 C. x1 |1 T) z- p4 ~" ~; j  MX_X_CUBE_AI_Process();
0 m7 m0 b* ^  {/ h. n" w  /* USER CODE END 2 */
% `- x" `' U0 U( U$ Z# w  /* Infinite loop */! P  e# ]7 u! z2 y" Y
  /* USER CODE BEGIN WHILE */, z! N2 S3 V. f% f4 q! }
  while (1)* h0 V7 ]' n: N+ K, N
  {8 C3 U- j) z3 s# k; ]
    /* USER CODE END WHILE */
1 G- w  _! ]! f3 Y3 @% p% ^                         GUI_Delay(10);7 p+ S  a' S1 g- S! z
    /* USER CODE BEGIN 3 */
# t) q: x' E* [$ s2 |, x( m1 v, u* r  }( W8 X  q5 `/ s  i. ?

: m  V1 H+ r3 m0 B简单的主函数。  c9 f0 c7 w( B+ F2 e+ W) I  l

) \$ g& R2 j3 Z
% g4 }) j' A5 g4 j0 Z+ R2 s7 n  进入MX_X_CUBE_AI_Process();
2 a; t$ f6 x4 J: I0 o7 z( W0 R1 L  H. Q! p: Y6 \  n  U8 ]" T

3 U! Q5 |7 T4 d1 j    ai_buffer ai_input;8 t* U( {2 d4 |- t
    ai_buffer ai_output;) h3 L: _( E0 W" S+ u/ h
    ai_i32 batch;
4 E; u0 H% B/ o/ Q* E* g& E    char str_tmp[16];2 N) g: [' W6 I
     for(uint8_t i=0; i<10; i++)
+ T4 [, W2 R  G            {
; X# m' q) \4 P                                                sprintf(str_tmp,"%1d.bmp",i);
+ Z$ u+ w+ L* t- a6 \1 d6 C                                          _ShowBMPEx(str_tmp);! Q2 y3 v. S$ v8 L1 J, D
                                                LCD_ShowBMP(str_tmp);
  N% h) `/ X( J+ T                                                for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ )5 X! ^  X. B3 M. X7 N2 @
                                                {6 k0 h9 P8 l3 K9 W' `2 d- |6 W
                                                                in_data[i] = *bmpBuffPtr++;
' a+ K3 e' V% \9 y5 T6 w                                                }
2 ?; z; ~( d6 Q6 y) H1 B3 ^9 B8 G! [                                                ai_input.n_batches  = 1;3 }4 L6 w! R' M; p; q1 t
                                                ai_input.data = AI_HANDLE_PTR(in_data);
! _8 x( D6 U6 s' Z2 p9 l8 z                                                ai_output.n_batches = 1;
8 U$ {1 m5 b$ ]8 `                                                ai_output.data = AI_HANDLE_PTR(out_data);3 \; m( M5 m. m  ~
                                                batch = ai_lenet_run(handel, &ai_input, &ai_output); : Z" ~9 [9 @0 ]. u
                                                if (batch != 1) $ F0 h. G. ^+ S- q: X
                                                {
$ V0 R1 h1 j9 u8 t5 k" Z7 A4 R4 @, ~                                                                err = ai_lenet_get_error(handel);
( h$ R, _: R8 G1 t4 T4 R4 S7 v/ C                                                                if( err.code )
4 M( w- V2 F) O                                                                {  `  C# U5 u! W0 v
                                                                                while(1);( D5 X2 d4 ]0 S9 S4 J
                                                                }5 O' I/ s, x- O& z8 ^7 R& m. C
                                                }# v* M2 a: y* d  b8 ?  N5 k" M
                                         uint8_t count=0;9 s$ w3 C$ x8 R) B# w" r
                                         for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)
+ J2 m- E4 m9 P' y  u                                                {
; \2 _- T! @' A. a* v                                                  if( out_data[i] >=0.9f)
) D& G6 N3 G" M  C" y7 g+ q& O: c- t                                                                {/ [9 t8 _" K+ R
                                                                         sprintf(str_tmp,"Num:%d",i);* s+ d" [! F7 b: ]8 f
                                                                         GUI_SetFont(GUI_FONT_32B_ASCII);* e* d( W9 Z3 E$ p" H& z
                                                                  GUI_DispStringAt(str_tmp,200,0);
. U$ N  c+ {  s" }) P/ c* e9 Z                                                                         GUI_SetFont(GUI_FONT_16B_ASCII);9 v! e8 Z5 H& e5 s
                                                                         count++;
7 n5 o& i6 r9 ]# W2 [: ^: N/ y                                                                }
  N  N  ]$ z* B5 S" o                                                }" l0 E3 w) U% s2 B4 K4 O
      if(count!=1)% _' ?( t4 C1 d$ _0 c; Q
                                                {
- O# ~4 k: v' }( S# t# \2 ]                                                        GUI_SetFont(GUI_FONT_32B_ASCII);
1 |+ u$ u# F2 w: E) n                                                        GUI_DispStringAt("err",200,0);: G! E) k8 |! T# ^
                                                        GUI_SetFont(GUI_FONT_16B_ASCII);
. o1 z* d7 }+ ?0 A8 l  o- I- E                                                }8 }; O5 t* i% f- l
                                                free(bmpBuffPtr);5 H  x. ^1 N/ o# D& D
                                                HAL_Delay(2000);
7 s6 Q" y  T1 h! U  H                                        }
, b0 L$ c$ o, ]2 d8 R- n% f5 l( ]6 ~3 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 型 何必不输出 所有的置信度。后面我将继续挖掘。
5 E5 G4 ]5 V# z# V/ T2 x( c
  Y* w' l. a# v, q0 D4 l5 F       流程介绍完毕,下面说一说cubeAI的主要函数。# Q# f9 {. A" W( c+ R. s
       ai_lenet_create(&handel, NULL);
& j. j$ W+ [, q; n3 W$ q, q% \1 ^      ai_lenet_get_info(handel, &report);
) A# r- p# M- ]' S8 m4 P7 E          ai_network_params params = {
8 j2 C/ o' y# g1 y6 @6 O- q3 g                                                          AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()),    //权重的获取$ S& N" T5 X! P; ?9 D/ S! ^% q
                                                        AI_LENET_DATA_ACTIVATIONS(activations)     // 激活函数0 k1 q) D3 R& s# F
                                                };
) ?; A' k, q6 P) h' y3 e% t          ai_lenet_init(handel, &params);  //lenet的初始化,估计是申请内存什么的,写flash。0 e- _# u8 K! Z2 y. g: s* D
                                                                         err = ai_lenet_get_error(handel);  a4 u2 s& I) d# c& w! \9 w& v
$ x$ n! y7 E( |" U; _, ]
         batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批
, ~7 x4 L, I) }) q# E* l1 t5 c2 D& \! b: [: g- g' b% m
" q1 A, a: r; ~4 R- s# Y
         总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。' z) ?* }% ?- i; V; f7 y) B5 D3 m
        这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15!  期待MP1,玩玩不用压缩的AI。' b7 x4 E$ Z- l  C5 A! |/ T) a+ Y
        附件:工程源码。5 B) d1 `, G, w0 I- k

6 n. d, \7 W8 }) ?
) J) {+ e* _' N$ I

Minist.rar

下载

10.2 MB, 下载次数: 150

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

举报

7个回答
happier_1995 回答时间:2020-7-30 08:17:50
兄弟,您这个代码运行最后的准确率能达到多少?我今天试了一下,10个数有9个识别错误的。
Bowen1028 回答时间:2019-5-18 09:02:09
支持下
lebment 回答时间:2019-5-18 10:34:28
strang 发表于 2019-5-18 09:02
% x+ Q; s+ l* t支持下
! Y0 \5 V; d# y( N4 ?: L
谢谢支持
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
学习学习!
! L. U$ N3 L4 _0 w. E

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版