在经历完各种准备工作后,现在终于来到了正主。直接部署Tensorflow Lite Micro那一套玩意确实没啥问题,但是太麻烦,要添加一大堆文件,还得用它家训练生成模型,然后转换,麻烦的很,在ST平台,怎么能不提到用ST自家工具去部署模型,方便快捷,简单实用。# C& i5 }" w/ K
拿出之前准备的工程,选取ai开发需要支持的软件包cue-ai,在software packs点select components, s2 y! J& J5 X b F1 j6 C
9 e0 d8 S# w. F5 c$ l- e) r! Z' W6 c9 ^' I n. P+ q
, a- Y- W6 z7 @" P/ m- x
9 C+ ?5 Q0 D1 Q4 c# b7 F% k+ n
在X-CUBE-AI行下core勾选,点OK完成& K, c b \3 ^
4 d7 \6 d5 P+ ]+ O- r
" l& F, g0 v q$ t% h; j; I
" N% E4 y& z, y! D1 [( t回到引脚配置页面,最下方就是上面导入的CUBE-AI工具包! ^: \ ~, ^0 w
$ ]+ H O/ F: y0 O @
& ~0 U1 t3 j% }' n+ w0 Z2 O- F" s
6 k1 R$ o: H/ t. U' c, o5 U: f4 b/ l5 H; w% i
点击+添加,这里要根据自己使用的模型,以及模型特点选择,如下图选择的是原始模型
( z9 ^& e+ A5 t/ \
0 n0 l9 n& S" q+ H
, R; [4 r" j, G! z
这里选择的是量化后的模型(量化可以减少模型的要求,但是精度会下降),点击分析' k. |" l' a7 k$ k5 l2 V
& c. t- ^8 j* [9 n2 Y& Y
9 r |7 t5 _/ p- c8 M+ R
分析中9 b2 H( l1 \6 \; m) n/ }" ?
1 S' W* w0 ] x6 A% Q/ |9 r; N" ?( s3 o) w9 s/ P2 M2 W
分析完成会显示是否可以部署到设备上,以及资源使用情况。4 k- i9 m+ A# y1 K, O* \5 I
" L" E5 y. U, y/ r1 [" b7 ~3 Q
, g, U- w8 Y+ ?# G% l回到工程,有个小bug(使用的STM32CubeMX版本为6.6.1,X-CUBE-AI版本为7.2.0),下图的几个文件路径老是生成错' p: V, f- `; `( H1 D) R) F
+ I4 U3 p. C) P5 w$ z" a. U$ ~* f! }7 L/ p4 a( i1 @
# [: C$ m q0 u2 O) Y
$ g* f2 h# @* f右键文件打开设置,修改一下路径就行
+ D) W- V( ? s8 D
3 D; W+ S2 }& [8 j. t1 ^
( Y6 L! |' T5 \4 G% F) j
1 x! r" V3 g, p; \ k z' x
头文件路径也有一样的问题" P) Z3 N8 Y7 B. D9 N) a6 M* Y
+ P# W$ w( ^1 U# b
Q& p$ i. }# w; b" Q5 D/ Q6 o5 _
初始化模型- ai_handle ai_init(void)" \9 e! V/ i3 M' _
- {
; P2 x( j, M7 d r - network_handle = AI_HANDLE_NULL;" H) H4 h/ E: O* A5 y! X" N
5 O- l& ~5 a1 \' p9 u- /* Creating the network *// g) M3 m4 R4 @& n' A9 z! {+ [
- ai_network_create(&network_handle, AI_NETWORK_DATA_CONFIG);6 r# X4 H8 w+ {: N: R/ b6 S
- ( q8 b% g0 E9 e% @8 k0 P6 P8 q
- /* Initialize param structure for the activation and weight buffers */
4 r) W5 ` d' k, S' g: _ - const ai_network_params params = AI_NETWORK_PARAMS_INIT(
9 s k1 |* e& r7 x! ? - AI_NETWORK_DATA_WEIGHTS(ai_network_data_weights_get()),
) b: H4 r; G& o3 e0 i1 v" Z; s - AI_NETWORK_DATA_ACTIVATIONS(activations)
8 U& H2 {9 _% `9 U4 Q - );1 |/ I- ]: v8 x1 x) w9 D% I
- " `, i- \ X9 {) u2 Z, T( c+ i- @
- /* Initializing the network */
' o$ Q/ }. Y6 c' Z, R0 A - ai_network_init(network_handle, ¶ms);! A1 J0 O3 P+ s/ G9 Y6 q
-
7 T; j+ B' E& j; v8 H, N3 g - /*Retrieve network descriptor*/7 q! o. f& G" m$ H2 v/ q4 y7 i
- ai_network_get_info(network_handle, &desc_report);$ K" w$ F" Z0 @
-
- G6 O8 j2 Q/ _; ` - /*Copy descriptor info*/- D9 F! H' I; z |; H9 N
- ai_input[0]= desc_report.inputs[0];
/ z8 w2 `5 H1 Y+ S9 M - ai_output[0]= desc_report.outputs[0];
0 Z% e, L; b! P+ y' [. d - 3 C* R3 u8 {) n4 j+ f3 R0 C
- return desc_report.inputs->data;; q$ D$ t7 Q7 i- R# f
- }
复制代码
: s# F& }, m( [$ @. ]5 r7 X运行模型: _* J- K% ?& g3 M t# F
- void ai_run(void* input, void* output)) Q2 y9 @5 k, v+ f Y0 s
- {) K" `& b; }2 K4 z& ~. f
- ai_i32 nbatch;
: J$ e& q# L) T% v# [. u - 1 z2 a1 M, G( e, O- W
- ai_input[0].data = AI_HANDLE_PTR(input);) W$ y3 A1 B- }. ]" b
- ai_output[0].data = AI_HANDLE_PTR(output);
# ^* g* u$ [) d& C' B/ e: G3 R' A3 T -
M' U) L8 h; c% N - nbatch = ai_network_run(network_handle, &ai_input[0], &ai_output[0]); ?3 k/ x* P, p2 ~, C# O! T1 q
-
( ^; Z i) K% l+ r - if (nbatch != 1) {( ?* b) R3 u( c
- while(1);5 E1 t, k1 e6 q0 D9 e9 P1 ]
- }
6 n7 a5 f7 i+ R% ]. u - }
复制代码
' m) `4 n) w2 U5 e6 K$ S, r0 c图像接收处理,这个模型要求输入224*224的RGB888的图像,把数据转换一下。9 r: y. a3 l8 h: J0 R
- void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)% o4 F$ C5 j; K
- {) M, D! z. x5 k0 r- [) C; E7 @
- uint8_t person_flag;* G$ q9 }* s5 l: z# x
- int i,j;, o9 P3 ^5 i2 v5 I' n
- for(i=0; i<224; i++)
+ B Y6 Y0 a8 B9 j( b- k: h/ V - {
, Z! w( f: G! _* i+ Z - for(j=0; j<224; j++)* b, C# m* H; D% ~
- {" R q% k- N( ~
- uint16_t bg_color = ((uint16_t *)_OV2640->frame->buffer)[i*320 + j];* x+ } \5 t6 X
- network_input[3*i*224 + 3*j + 0] = ((bg_color>>11)&0xff)<<3;: Y5 _0 T) j) Z9 L6 ]/ v! E
- network_input[3*i*224 + 3*j + 1] = ((bg_color>>5)&0x3f)<<2;
; E( M0 h9 S* h* ~! R- R - network_input[3*i*224 + 3*j + 2] = (bg_color&0x1f)<<2;
7 q' k% d6 P" V( v/ ?3 } - }& G; x7 ^- w! f- o v: @+ K- L" {
- }) t* ^, [0 i- K, I$ p" o
- ai_run(network_input, network_output);) x: l: q$ K* X- ?' N2 }
- q: S' ]/ M! ]
- LCD_Draw_Image(0, 0, 320, 240, (uint16_t *)_OV2640->frame->buffer);3 I% Q. |" q, `. I9 C& I5 ?. y* D7 D
- LCD_Draw_String(0, 0, 320, 240, 32, output_labels[network_max()]);2 L8 `3 i1 g/ z2 o
- : @& x- X3 z$ S
- OV2640_DMA_Config(_OV2640->frame->buffer, (_OV2640->frame->length)/4);
7 `9 S( o. M+ a: f -
4 p- k; T& C+ z) n - }
复制代码 ( E7 l$ B$ [5 j
) \! L$ Q3 c/ p9 n$ U运行效果(一共能识别18种食物,这里选了几个看看)2 V$ J U, I& E0 j1 p1 [+ I
$ }* E! ~% h1 R
空% V4 b0 T. e3 r( u
8 G* @8 k5 |. r0 s- y3 l G& x! h
可乐' Y9 P. G8 J* A' m9 o
/ N6 u3 Z, V( X' A6 I$ a5 I* Q$ }+ @; L
甜甜圈. l Z* I* ]5 p' Y
2 M0 A: T; S7 y, b9 C5 {, B( f! h" N6 [# O
汉堡包+ s( Z. {' |9 @. @
' w4 m P- B0 h+ e2 L
& K$ J( |( X$ c4 u8 T' G3 }) F
薯条& W9 |. _; D1 _; ?2 W- E* N
% f2 y+ |3 W2 B, S( H7 g; h3 }- m" Q) e
8 Y2 E% G0 c$ M6 s6 a7 i
小结:STM32Cube.AI工具真的太香了,这里仅仅演示了模型的部署,其实可以快速验证AI模型在目标板上的运行情况,只用串口连接,直接把输入发送到单片机,然后运行完后把结果返回来,全部都集成到了一起,快速验证模型运行情况。很是方便(本文未涉及,有需要的可以在X-CUBE-AI行下勾选时,application里面选择validation,回到配置界面后设置通信接口即可)
% l( G5 p' ~! S, l: CWio Lite AI视觉开发套件确实是开发AI的很好的选择之一,板子虽小五脏俱全,拿来做单片机视觉绰绰有余,但是不得不吐槽的一点是资料支持太差了,原理图,代码全都藏起来,前期调驱动花了很长的时间,后来管管给了一个例程后好转了一些(但是已经晚了。。。),Ai在单片机上应用已经有很多厂商都推出类似的解决方案了,ST这一个环境很优秀,就是如果相关的培训跟资料再多一点就好了。
6 l4 n0 Q8 a( \: T! P! p0 v |
up有没有原理图资料~
求求了
[md]好久之前做的了,资料都忘了放哪里了。。。你可以在网上找找,或者找卖家要
up 有更详细一点的建文件工程的教程吗? 还有模型怎么弄上去, 求解
按这个文章操作就行