在经历完各种准备工作后,现在终于来到了正主。直接部署Tensorflow Lite Micro那一套玩意确实没啥问题,但是太麻烦,要添加一大堆文件,还得用它家训练生成模型,然后转换,麻烦的很,在ST平台,怎么能不提到用ST自家工具去部署模型,方便快捷,简单实用。4 Q; t+ K6 [# u, c. I
拿出之前准备的工程,选取ai开发需要支持的软件包cue-ai,在software packs点select components
( J2 d. Z/ g# ]0 l
0 c: R8 X+ w9 j; l" ]) b: e
, @! K2 @" B1 K- p+ P$ w
2 t0 z- t0 a; D7 ~ ^# e
( ^$ C: \0 i9 w ^+ ?2 |! Y$ l在X-CUBE-AI行下core勾选,点OK完成0 h1 g7 Q1 T* a! f4 t8 B
2 p1 `3 J9 F0 z4 K) ?/ @
) i# Z3 @ }! p# ~8 t8 l4 a
. |$ B$ G1 q; X) F: d回到引脚配置页面,最下方就是上面导入的CUBE-AI工具包
2 _3 @4 @ [, E1 s7 A3 V& L, ~
3 U+ B8 @% t0 k* h. _; Q) _2 j$ L5 `# Q
' t9 \ C4 }4 g5 l7 L6 s" Y
, y% f, k9 S) y2 F; Z9 G# I2 j8 N
点击+添加,这里要根据自己使用的模型,以及模型特点选择,如下图选择的是原始模型
, x9 r4 D& w, j+ E. ^1 P8 ?/ Z
$ `# F! T! C3 d9 r8 @: Q* B
7 e) E6 n$ |2 Z ~3 ^$ q2 S/ }* Y- Z这里选择的是量化后的模型(量化可以减少模型的要求,但是精度会下降),点击分析
( Q7 ? v+ M: l6 d% K; P1 q( S
+ g/ b1 D+ U5 T! H, T2 \
/ M" j( R& c# k( x/ ?
分析中
4 U5 s$ u& [3 @+ q: s) m9 {( R% y
7 i" K+ D3 d% D6 C! x1 H
2 G* [8 J% D. V% v1 Z, X0 p6 {
分析完成会显示是否可以部署到设备上,以及资源使用情况。* g. f! |% T+ A3 d$ F
7 t- V& ?' @: E4 L
. P' I7 H9 O5 R- ]6 G
回到工程,有个小bug(使用的STM32CubeMX版本为6.6.1,X-CUBE-AI版本为7.2.0),下图的几个文件路径老是生成错8 v5 q9 a( t' e i
! c) P" y& O, P* ~
5 u5 n! }! I; T" l' D" a6 U
1 ]) m+ G- i0 S3 K( }+ k b
: z5 H& N* E) r% @5 n+ a( @右键文件打开设置,修改一下路径就行/ a9 i/ g+ M/ I
5 N7 |. l- s8 l# Q: _( R6 C
/ S, d6 R W" O4 L
3 ?1 z. h' H4 ]6 x6 r' c- x头文件路径也有一样的问题
0 O( v3 t7 o6 `# }/ n1 ]
8 G. u6 E% ^2 f* ~. Y1 P6 x
7 n& Y* D A9 \
初始化模型- ai_handle ai_init(void)
1 N0 I$ R0 u+ N+ d9 h - {
& {9 Y& G+ Y+ ^& ^% {; k2 t - network_handle = AI_HANDLE_NULL;9 B- n( s0 n/ ]
- 7 _ Y( Q+ @- Q' Q/ o) L8 e6 j/ T
- /* Creating the network */
2 z4 K- X: @& ?$ O& P4 W - ai_network_create(&network_handle, AI_NETWORK_DATA_CONFIG);
# s+ o& u& n* M% L
9 B1 K& v8 F! g4 S- /* Initialize param structure for the activation and weight buffers */' G% J. A4 J( E9 M( k% ]
- const ai_network_params params = AI_NETWORK_PARAMS_INIT(, A( A `% S0 s
- AI_NETWORK_DATA_WEIGHTS(ai_network_data_weights_get()), f) c# e, C& _, A0 ?* g
- AI_NETWORK_DATA_ACTIVATIONS(activations)' f; r' @7 s, r4 n+ k. I
- );
( J7 h `8 {% i - % O6 R4 w' p0 y8 s' ]* g
- /* Initializing the network */8 k P6 H2 q# i* X7 q& D9 z
- ai_network_init(network_handle, ¶ms);& ^, K% C& I* N1 q4 v
-
! u* @# M/ j; g+ [5 d! B! F# h - /*Retrieve network descriptor*/0 u. V9 o* x4 y
- ai_network_get_info(network_handle, &desc_report);
: \( m+ @) t4 K& v6 i& a1 H+ m9 h - 6 w- U/ C% V0 C$ o
- /*Copy descriptor info*/" B# L2 @; y1 g9 `
- ai_input[0]= desc_report.inputs[0];& v, A( m& j1 s# O6 i6 u4 ?8 e8 a
- ai_output[0]= desc_report.outputs[0];. J- ~0 ~% k$ |( _2 R
- * l5 S. t. @, o4 K) A6 B- q
- return desc_report.inputs->data;
4 a O8 w+ t; S5 r+ o - }
复制代码
# m" c% g8 q; q0 i1 h运行模型
) R. f5 b0 N: `* S9 n- void ai_run(void* input, void* output)" @4 u" `8 Z' O/ x, f- m
- {5 V3 W9 J3 ]6 M4 {- Y7 m- Z
- ai_i32 nbatch;% [ A, s* L0 E B+ ^. e; s
- ' M9 I8 O1 I$ n# f* J
- ai_input[0].data = AI_HANDLE_PTR(input);
) y. g3 D: [% m/ y! i. E5 X% H - ai_output[0].data = AI_HANDLE_PTR(output);
" }9 J7 I w- w -
6 Y( c7 @9 W, M; N - nbatch = ai_network_run(network_handle, &ai_input[0], &ai_output[0]);
X. C5 e4 u$ W4 I - 8 R( R) {, q% \% v
- if (nbatch != 1) {0 D+ \& h$ R& j- c4 |3 A, }1 T' {1 D
- while(1);! m+ B7 j3 f- D5 _
- }
. ], S+ n: x, K$ h! P - }
复制代码
- {9 T4 t! X h+ c图像接收处理,这个模型要求输入224*224的RGB888的图像,把数据转换一下。
* v' o$ o$ R! f4 u: {4 P- void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)* M3 p) @2 Y; M1 t& C; H
- {: s( G0 z5 o, w7 Q- _
- uint8_t person_flag;
2 h4 L6 f# }* ^) g1 y, H, F - int i,j;9 g: d* |& x7 j, C/ Z4 X
- for(i=0; i<224; i++)
% c6 |( @/ o; N4 V" V - {5 s+ H. s. t) r" N$ s9 u2 _
- for(j=0; j<224; j++) f( l6 v7 `; ?) F5 H
- {- I7 T% O4 P& g: Z
- uint16_t bg_color = ((uint16_t *)_OV2640->frame->buffer)[i*320 + j];
, ?& h2 N$ g6 p* \. T* ~ - network_input[3*i*224 + 3*j + 0] = ((bg_color>>11)&0xff)<<3;& P! g* t) d/ r! f; Y$ K
- network_input[3*i*224 + 3*j + 1] = ((bg_color>>5)&0x3f)<<2;% s. ~9 d B; i5 P+ W4 C' T
- network_input[3*i*224 + 3*j + 2] = (bg_color&0x1f)<<2;
) s9 n6 A! ]# n4 v z, I% Q - }4 ~0 T, O, t! j: U
- }- M# G% R# o R
- ai_run(network_input, network_output);# @& V, e4 M: Y" @+ J0 u' u9 t
" ^7 a5 l0 s( h. }+ A- LCD_Draw_Image(0, 0, 320, 240, (uint16_t *)_OV2640->frame->buffer);
, i `) Q0 |1 J% a* L2 ? - LCD_Draw_String(0, 0, 320, 240, 32, output_labels[network_max()]);
8 _+ n$ w1 _3 A; h' W8 w7 u! y2 L - / I7 e0 N) m4 R, a- \
- OV2640_DMA_Config(_OV2640->frame->buffer, (_OV2640->frame->length)/4);. j" J7 C6 y! ` @5 G
-
0 e8 q, v# @+ K {0 f% b' Z - }
复制代码 / L; Y( K+ v* l4 X- _
6 { w' s8 O; _* K6 s3 F运行效果(一共能识别18种食物,这里选了几个看看)
: F$ P5 h: C% x2 ^) t7 m+ _" F" {" e
空
3 @1 `% e4 @% u' D, V: S1 H- j
4 J9 T9 P$ V3 B
可乐4 u7 ~" k* Z1 b1 {* J' o
+ w' C5 O% W& P; s1 D
: G& J% q7 a5 w( s. ~甜甜圈
2 C8 ` J0 @% y' _5 T4 e3 K
/ a6 z1 Y. q) `- Z0 d
- S% ?9 k5 ^2 {: o7 v6 L
汉堡包
4 a. E8 q) ]2 C1 o& z
" T+ v1 s' @- [% W6 ]) V6 P: D5 U
+ V+ s- N/ m: s' c: O% E薯条
' O. l1 i, w/ g' ?- S
8 I* e% T$ c! q5 S
& T: B5 b2 c2 t
" e/ M; o0 `2 l+ ^/ `! J- H" N
小结:STM32Cube.AI工具真的太香了,这里仅仅演示了模型的部署,其实可以快速验证AI模型在目标板上的运行情况,只用串口连接,直接把输入发送到单片机,然后运行完后把结果返回来,全部都集成到了一起,快速验证模型运行情况。很是方便(本文未涉及,有需要的可以在X-CUBE-AI行下勾选时,application里面选择validation,回到配置界面后设置通信接口即可)
; n8 K# x7 Y g! H0 ? j: zWio Lite AI视觉开发套件确实是开发AI的很好的选择之一,板子虽小五脏俱全,拿来做单片机视觉绰绰有余,但是不得不吐槽的一点是资料支持太差了,原理图,代码全都藏起来,前期调驱动花了很长的时间,后来管管给了一个例程后好转了一些(但是已经晚了。。。),Ai在单片机上应用已经有很多厂商都推出类似的解决方案了,ST这一个环境很优秀,就是如果相关的培训跟资料再多一点就好了。( F" S$ }9 t0 k; B1 \4 o
|
up有没有原理图资料~
求求了
[md]好久之前做的了,资料都忘了放哪里了。。。你可以在网上找找,或者找卖家要
up 有更详细一点的建文件工程的教程吗? 还有模型怎么弄上去, 求解
按这个文章操作就行