在经历完各种准备工作后,现在终于来到了正主。直接部署Tensorflow Lite Micro那一套玩意确实没啥问题,但是太麻烦,要添加一大堆文件,还得用它家训练生成模型,然后转换,麻烦的很,在ST平台,怎么能不提到用ST自家工具去部署模型,方便快捷,简单实用。! F! x+ g1 \! P% f# f- a
拿出之前准备的工程,选取ai开发需要支持的软件包cue-ai,在software packs点select components
2 J: h% k: M8 d: ]. f$ n. p& n
! ]4 }0 o5 R4 V' A9 {1 R R
0 y! @* g9 c' o; N
. r$ u8 b6 \* p+ Y6 \( k3 h3 A) z) d' z
在X-CUBE-AI行下core勾选,点OK完成% [* Q, l2 x2 s8 Y5 i
- [+ d6 M8 P; r& L$ ~# O0 Z6 F+ j3 R& Q/ _
0 f3 s: m' E9 K% d7 c4 m& q! L+ W
回到引脚配置页面,最下方就是上面导入的CUBE-AI工具包* C& M. l: [/ [
0 }' B1 C7 ^ m4 _# J2 ]
8 A9 |- E7 o1 Q: C! B) P
; V+ _' O, ?# H8 V. h. d2 F* t c1 b) `# K: Y e, K8 t8 T, o1 y
点击+添加,这里要根据自己使用的模型,以及模型特点选择,如下图选择的是原始模型: }7 p# @! J2 t; n) X. T" x1 m1 M9 y
7 V4 F! @; U6 b* P' Y9 Y. M; U! ^, a9 S4 n
这里选择的是量化后的模型(量化可以减少模型的要求,但是精度会下降),点击分析
" a% _& }( H1 u8 o G4 [. s! m
) B8 Y0 p; {5 z1 g" S8 \
; B0 l+ z: {5 B/ @分析中
& |- r' e: \0 W# D: ]6 S. t
% e! Q5 x# e" M) j
: Q5 R6 V. L6 @
分析完成会显示是否可以部署到设备上,以及资源使用情况。3 r- [/ Y2 K* v: B1 ~) D
" ?7 q. N, Q- R( ?- E; t% m( O% H' b
. J n# X6 W4 Y回到工程,有个小bug(使用的STM32CubeMX版本为6.6.1,X-CUBE-AI版本为7.2.0),下图的几个文件路径老是生成错2 m0 {$ a. j" y& l2 h
( v( ^0 b9 A# o2 ^# I& Y- O6 c/ Q- n& f5 x/ G* A! ^
5 i0 Q* e2 G$ }
9 V. b) {1 L1 _! t% ]' R
右键文件打开设置,修改一下路径就行
0 X0 d1 |# j+ y6 [5 {
7 @9 Y# F# e7 @: i) k
5 Z; F. q9 F1 `& n2 n
+ w% X1 y/ G( l
头文件路径也有一样的问题: ^# D- s& c4 Q' R" }
' d% H4 w6 h- _
8 L3 g9 l% l" t1 ^
初始化模型- ai_handle ai_init(void)
$ ~* ~6 x1 C( q* s9 r9 d( H1 z0 a6 B - {" Y5 T; h- M* x' X. }# {6 n
- network_handle = AI_HANDLE_NULL;( S! o' L4 O; J8 K
9 _9 ^) T9 Y) V( e. o: F- /* Creating the network */
/ D% Y7 p. V+ r2 ^* C) L/ Q - ai_network_create(&network_handle, AI_NETWORK_DATA_CONFIG);0 H3 P$ _* G: G
; J; C* I k8 f6 I0 y- /* Initialize param structure for the activation and weight buffers */0 d6 x. m3 b1 Q- `- f
- const ai_network_params params = AI_NETWORK_PARAMS_INIT(
( Z3 w7 j% K% B/ f5 N9 a6 D: n - AI_NETWORK_DATA_WEIGHTS(ai_network_data_weights_get())," O% X1 t4 p, l) v( b8 I. K( L
- AI_NETWORK_DATA_ACTIVATIONS(activations)
% }2 Y, U' n; J* z, M* J - );+ V8 o' T% N( |/ A J
- - I, I( w5 I2 n* e0 d
- /* Initializing the network */3 J; s0 B8 u% d! Z7 s
- ai_network_init(network_handle, ¶ms);
- ]" ]' \& W! j -
; V* Q, E, F- `; \+ M" n - /*Retrieve network descriptor*/
, H Z H" m. l3 O - ai_network_get_info(network_handle, &desc_report);
: \- ~& d9 ^0 K3 t U -
9 E9 V# r4 c# F - /*Copy descriptor info*/
: d0 m4 W$ k. H) l1 D4 A - ai_input[0]= desc_report.inputs[0];
7 h1 U7 w* Z4 { y! ~* k" O - ai_output[0]= desc_report.outputs[0];3 z5 i9 F" \" {+ p$ h; m+ L+ C K% L! ?. S
-
$ M O' m% T- m! U - return desc_report.inputs->data;
1 ^; I- _7 i. o - }
复制代码
2 A: t$ y2 H* p运行模型
+ K8 w7 Z/ }1 l7 l4 x- void ai_run(void* input, void* output)
! x8 P, t. {+ u8 A1 L, a - {* f& J0 C! G" S( O9 Z0 u! B; o# }3 o& |
- ai_i32 nbatch; {" `+ Y' A3 Y2 u+ g) T/ ~9 B
- 0 H! ?0 _5 K0 U+ l. f
- ai_input[0].data = AI_HANDLE_PTR(input);+ ~% |' T# P0 l6 `5 j9 f
- ai_output[0].data = AI_HANDLE_PTR(output);
/ H1 D# p0 Q2 @. Y# i! C3 z - h) M) m$ k" |6 }/ x5 E! ?+ b
- nbatch = ai_network_run(network_handle, &ai_input[0], &ai_output[0]);
* r( ~$ ^+ ?" h& t4 a - 8 _1 M8 {& s* T" C. k6 M! H
- if (nbatch != 1) {4 E; i" b; V6 D
- while(1);5 d, _# q) L" ~: }
- }' [: I9 x( q7 o, h% M" _! g/ w" K
- }
复制代码 1 N m* K) D! b' V3 z
图像接收处理,这个模型要求输入224*224的RGB888的图像,把数据转换一下。# \6 |& j6 s8 f" g; X7 a
- void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
2 R. y M' k7 U& L4 r - {5 V: ^9 I: g; r% Q" I* S2 w
- uint8_t person_flag;' N2 A& D; ~/ d5 {- H0 I( a8 G5 i
- int i,j;
3 u, } D @" k. R - for(i=0; i<224; i++)9 P, q' L1 D$ ^1 C$ T! z
- {2 {2 P' F: ]3 O7 u/ S- L# A/ c
- for(j=0; j<224; j++)
v& r _+ G4 B. x1 j5 Y - {+ x; Q" r$ B! V' J. b# \
- uint16_t bg_color = ((uint16_t *)_OV2640->frame->buffer)[i*320 + j];
) t- {+ S. ? i: c" \; e - network_input[3*i*224 + 3*j + 0] = ((bg_color>>11)&0xff)<<3;
0 h7 x2 N( Y. r" \ - network_input[3*i*224 + 3*j + 1] = ((bg_color>>5)&0x3f)<<2;$ r# e8 j2 ~1 m6 Y; O9 R
- network_input[3*i*224 + 3*j + 2] = (bg_color&0x1f)<<2;
; X0 `' Y4 J& `7 R9 G. A$ t0 B6 o - }* T1 J" g- m) K M9 W
- }
& h2 ^# g: |1 ~! Y# p+ Q - ai_run(network_input, network_output);
; t! d( c% Q6 |+ @; q+ _$ ~ - + Z- I; x, B! l* _7 Q: B" q
- LCD_Draw_Image(0, 0, 320, 240, (uint16_t *)_OV2640->frame->buffer);
- X# F5 H) ^. s/ | - LCD_Draw_String(0, 0, 320, 240, 32, output_labels[network_max()]);
/ \0 j9 ~! m. A+ g -
7 M2 m* i" S6 X; k - OV2640_DMA_Config(_OV2640->frame->buffer, (_OV2640->frame->length)/4);4 Y1 q6 l% S" @, o; U: g! M3 Y7 |
-
# R6 e5 j3 G; v% O - }
复制代码 + e" F, M" c' b+ E
4 n! m% U: @) v0 `3 m4 n
运行效果(一共能识别18种食物,这里选了几个看看)! C4 O/ `' f1 C
3 h' C' F: }1 ?( O* j' ]1 T; K0 U1 g
空
9 u1 w# d% v |6 |
- t2 K) z* q0 o! b
可乐
! `4 N# M* q, y
9 u4 a* q9 A; n) l; V
2 P/ }# X, k; d( ^2 [: g甜甜圈
9 o2 S) Y! U7 d5 I
% K+ h, f/ i, ]- Z' U& d0 q: N( W$ D( i; I$ R7 t
汉堡包
4 @4 n" y4 B# s# t+ ?
/ e2 |6 q, C J- H$ F
# w! M1 X. w M: \4 a, d薯条- M2 b/ \ D; O1 H, ^) @% M
$ |' A* K$ e$ u, |5 P( q2 a; B1 c2 L* v- A
7 A' G- k* ]5 s小结:STM32Cube.AI工具真的太香了,这里仅仅演示了模型的部署,其实可以快速验证AI模型在目标板上的运行情况,只用串口连接,直接把输入发送到单片机,然后运行完后把结果返回来,全部都集成到了一起,快速验证模型运行情况。很是方便(本文未涉及,有需要的可以在X-CUBE-AI行下勾选时,application里面选择validation,回到配置界面后设置通信接口即可), W1 |7 D- q" m% _7 j$ x: m5 ]
Wio Lite AI视觉开发套件确实是开发AI的很好的选择之一,板子虽小五脏俱全,拿来做单片机视觉绰绰有余,但是不得不吐槽的一点是资料支持太差了,原理图,代码全都藏起来,前期调驱动花了很长的时间,后来管管给了一个例程后好转了一些(但是已经晚了。。。),Ai在单片机上应用已经有很多厂商都推出类似的解决方案了,ST这一个环境很优秀,就是如果相关的培训跟资料再多一点就好了。
1 o+ w% m9 R1 R% I |
up有没有原理图资料~
求求了
[md]好久之前做的了,资料都忘了放哪里了。。。你可以在网上找找,或者找卖家要
up 有更详细一点的建文件工程的教程吗? 还有模型怎么弄上去, 求解
按这个文章操作就行