在经历完各种准备工作后,现在终于来到了正主。直接部署Tensorflow Lite Micro那一套玩意确实没啥问题,但是太麻烦,要添加一大堆文件,还得用它家训练生成模型,然后转换,麻烦的很,在ST平台,怎么能不提到用ST自家工具去部署模型,方便快捷,简单实用。2 D- b* R+ [3 |: [' `& S
拿出之前准备的工程,选取ai开发需要支持的软件包cue-ai,在software packs点select components
* o5 z+ x- f6 M0 q
' `0 y8 l* Q, ]" Z* ?( K& n- u, I
8 a4 i' H0 C( D+ q Q% w- S" M0 @4 C9 I
% j4 y& e) |4 ~6 a) i& O在X-CUBE-AI行下core勾选,点OK完成% a1 [ ]. ]- E4 G
' D I [6 ^- G6 }6 m; o! |4 O7 W* h
7 E: A) c: p% ]. [9 G3 | S3 b/ }5 z7 E! [' K3 W9 T6 _, R! U
回到引脚配置页面,最下方就是上面导入的CUBE-AI工具包" t: p5 \9 z/ e2 d- j0 h+ y7 I
; T0 [) {. ^' [% u2 D
2 w9 h3 U) b. ]* I4 z+ F7 t6 l+ k) a# H2 m7 t
" B; C2 d G C! b% x$ p点击+添加,这里要根据自己使用的模型,以及模型特点选择,如下图选择的是原始模型2 L" q6 P+ R: o' ^; B$ J: J
) W1 z# L. M9 @, E
+ c9 {. r5 X9 Q这里选择的是量化后的模型(量化可以减少模型的要求,但是精度会下降),点击分析
8 a! e' C# ]1 i K
2 K, d+ c. `& k7 Q9 O
1 ?' S/ m% t5 F" K7 @5 M
分析中$ c* L# B! M4 _7 b Q
% H" Z: u2 M$ `; o9 T( b2 P+ \, t! P2 f$ @* c# s
分析完成会显示是否可以部署到设备上,以及资源使用情况。
5 P \ L( z& u* ^8 f2 b2 ^ x+ |
5 h/ n! {; D8 g Z3 t
2 C3 S: ^* N$ }( o回到工程,有个小bug(使用的STM32CubeMX版本为6.6.1,X-CUBE-AI版本为7.2.0),下图的几个文件路径老是生成错
8 U/ F: I( j6 s5 o: K1 b
+ a) W4 O9 C7 i) ^0 Z' x; B Y" n7 x" ^4 L |
' c( j/ E: F7 j& X% v
: W5 k# m# H( J2 r, N+ s4 u' G; }
右键文件打开设置,修改一下路径就行* x, k3 P+ E/ R {* l
6 q/ Z) n7 a z5 W: x% l1 o2 S
6 s# X" d/ c9 E: ~7 d
* B$ z4 w* Y- g7 c# C, J! x头文件路径也有一样的问题) g, A$ `0 m) @ a' \
7 ^+ X6 k8 j2 E+ j" | s
9 D# b6 z$ E9 C; @! F初始化模型- ai_handle ai_init(void)
9 U% h& x7 ^6 H" Z% r' J# _2 Y& Y - {
% d1 f4 X% o* T4 z# V - network_handle = AI_HANDLE_NULL;
! a1 r: E5 _3 d5 F& V4 A - , r* ?4 L( _: ]/ h
- /* Creating the network */ U! L) E* B! u8 x8 c+ h2 T- e
- ai_network_create(&network_handle, AI_NETWORK_DATA_CONFIG);% H$ m) w0 f* j; N& q3 |# G& p
- ) v7 K' x: Y! B6 P& v
- /* Initialize param structure for the activation and weight buffers */
9 O, { ~- c9 ?4 T0 G7 K" _ - const ai_network_params params = AI_NETWORK_PARAMS_INIT(
/ ^" O3 ?& N: n2 M- x - AI_NETWORK_DATA_WEIGHTS(ai_network_data_weights_get()),
8 B5 \+ _& b% Y; k, l - AI_NETWORK_DATA_ACTIVATIONS(activations)5 W: ~1 Z! f3 U, k+ t/ y
- );- g5 i4 [) s5 _ k6 C
) |/ f# O$ L0 F- /* Initializing the network */, g% O& b/ x2 p$ q
- ai_network_init(network_handle, ¶ms);" P) e- M0 A q- C! G* J
-
% J, k3 f. v/ t7 F: q - /*Retrieve network descriptor*/' S* `7 c H( {$ U7 B
- ai_network_get_info(network_handle, &desc_report);9 z6 I1 A: J: S4 W: i
-
2 n% |1 s4 [+ H - /*Copy descriptor info*/- s. N5 v0 l# y5 W0 r! n
- ai_input[0]= desc_report.inputs[0];/ Z) R8 t$ n! K J4 d
- ai_output[0]= desc_report.outputs[0];
, A, B: [0 G' K$ s6 x& k -
* Y& ^) {: z% H$ W7 p+ Y - return desc_report.inputs->data;
3 L7 k5 Q0 n d8 U2 _1 C - }
复制代码
6 `: ~$ ^! n; ?2 o$ @1 G运行模型$ o2 l* m: a' n, W3 O
- void ai_run(void* input, void* output)
+ }1 U- w" B, j, Z6 F% b& V- G2 n - {
9 W1 F( s$ K' h S6 Y& Q2 n - ai_i32 nbatch;/ F" U: } U* ]
-
- y* F0 z+ J2 h& Z& c- v - ai_input[0].data = AI_HANDLE_PTR(input);3 S6 p: F6 u7 J! k
- ai_output[0].data = AI_HANDLE_PTR(output);4 B# \" }/ h9 v# c( j! s: H
- - q$ n# Y7 n6 ?: P+ Y
- nbatch = ai_network_run(network_handle, &ai_input[0], &ai_output[0]); y# r: C4 w) J% ~- [1 e6 ]
- 1 i( j% H$ ?! B/ B2 m
- if (nbatch != 1) {
8 k. T( s* B$ Q. ?9 t% l - while(1);
1 I/ P) x7 @5 x5 }4 `; T! s - }8 F' W+ t* I+ P2 j) I5 Y
- }
复制代码 ( {" Q0 V. h1 D" _1 r( ]3 E
图像接收处理,这个模型要求输入224*224的RGB888的图像,把数据转换一下。0 o% x9 A9 `9 R- s+ F! x
- void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)/ a' }6 Y+ O' p( @5 N7 h0 a
- {2 s" O1 e0 ?. U4 g
- uint8_t person_flag;9 f$ T2 d3 J) e
- int i,j;) m3 r# W$ _0 n
- for(i=0; i<224; i++) ~+ c& X8 G3 O5 U, E& t% Y
- {3 ]3 _- J5 V2 o
- for(j=0; j<224; j++)% k8 C# d% g9 L2 p. b% R
- {
, O4 W3 N: E! Q; w2 l1 |. y6 a) y - uint16_t bg_color = ((uint16_t *)_OV2640->frame->buffer)[i*320 + j];
: X/ K% y; i: A' U& L) h9 E - network_input[3*i*224 + 3*j + 0] = ((bg_color>>11)&0xff)<<3;
( Y* n+ T2 O+ O( R" c$ g - network_input[3*i*224 + 3*j + 1] = ((bg_color>>5)&0x3f)<<2;
. t- R' X5 S$ e$ H+ X' q- e - network_input[3*i*224 + 3*j + 2] = (bg_color&0x1f)<<2;
: X) {# Q( K* I0 F6 r8 D( } - }
( I: u: u$ K2 N7 L( O# Q1 i - }# j. G# G& Q, O) q. k0 S0 S
- ai_run(network_input, network_output);$ q/ j+ Q) q- f
d( T1 j; c- v$ i- LCD_Draw_Image(0, 0, 320, 240, (uint16_t *)_OV2640->frame->buffer);
3 g. f3 C% q. }# l; ~ - LCD_Draw_String(0, 0, 320, 240, 32, output_labels[network_max()]);
7 M3 a' P7 Z2 Y6 D4 @ -
7 `3 E5 @9 Z& i. D$ _7 w9 ^ - OV2640_DMA_Config(_OV2640->frame->buffer, (_OV2640->frame->length)/4);* F4 G3 E1 O- K2 i# C7 f3 e
-
3 e. c2 t- O' L. A2 { - }
复制代码
/ M$ s+ h% u0 v1 ^; Z5 \' j' {( x3 }
运行效果(一共能识别18种食物,这里选了几个看看)" Y4 p! @& ?" f3 d1 O3 I8 E9 ^' }
' W' J' S6 ?. d3 Z" G
空# A% f7 h& b% H* |! O* u; b0 w) B- O
" Y5 }) Q4 H" t+ y7 X可乐# I* h8 y5 M+ P0 z2 Y& H0 i
0 `4 h$ Y1 k" e( `: @6 [8 D4 O# ^. u0 K2 F( z) d# U \' `
甜甜圈3 T# l- E- A2 L: J; N7 x2 C+ F; g) k
8 `' H1 k! e6 y" y+ _, n
& A" h& F/ D- m t3 x汉堡包( N1 R3 ^* G/ q5 ~5 v
" W( k) m# j( `; Y( A# l$ L4 r
- H* A' C5 e9 R3 T薯条+ V. c' V2 z& P
4 b& F/ p/ q. m& K1 K
+ B% c$ G; B0 R$ e; ?# C1 v
; m, o* b9 E* T5 g w% `8 ]1 H
小结:STM32Cube.AI工具真的太香了,这里仅仅演示了模型的部署,其实可以快速验证AI模型在目标板上的运行情况,只用串口连接,直接把输入发送到单片机,然后运行完后把结果返回来,全部都集成到了一起,快速验证模型运行情况。很是方便(本文未涉及,有需要的可以在X-CUBE-AI行下勾选时,application里面选择validation,回到配置界面后设置通信接口即可)
4 t: b/ ?2 n5 X7 pWio Lite AI视觉开发套件确实是开发AI的很好的选择之一,板子虽小五脏俱全,拿来做单片机视觉绰绰有余,但是不得不吐槽的一点是资料支持太差了,原理图,代码全都藏起来,前期调驱动花了很长的时间,后来管管给了一个例程后好转了一些(但是已经晚了。。。),Ai在单片机上应用已经有很多厂商都推出类似的解决方案了,ST这一个环境很优秀,就是如果相关的培训跟资料再多一点就好了。
4 a3 z! i& i l( c- b$ a1 b% I |
up有没有原理图资料~
求求了
[md]好久之前做的了,资料都忘了放哪里了。。。你可以在网上找找,或者找卖家要
up 有更详细一点的建文件工程的教程吗? 还有模型怎么弄上去, 求解
按这个文章操作就行