在经历完各种准备工作后,现在终于来到了正主。直接部署Tensorflow Lite Micro那一套玩意确实没啥问题,但是太麻烦,要添加一大堆文件,还得用它家训练生成模型,然后转换,麻烦的很,在ST平台,怎么能不提到用ST自家工具去部署模型,方便快捷,简单实用。
z: g) l- e- ~3 e; e. g拿出之前准备的工程,选取ai开发需要支持的软件包cue-ai,在software packs点select components
' d" c5 O" ]+ H1 C5 @
0 f+ M- ?% p+ z5 f- U9 V, u. S
: f& f; Y9 R6 k% r( U; u: n, ~ B) x( G3 i9 x' J* i
1 L4 n7 L4 k$ d. O0 R
在X-CUBE-AI行下core勾选,点OK完成! U/ G2 w) h/ \
1 [( \) D$ S( ]
0 Z8 m1 c. g; k' ^0 M% f& N
9 e% J) Q0 P% ~+ E回到引脚配置页面,最下方就是上面导入的CUBE-AI工具包. U3 f2 t3 t% T* ^
- g) y: [( I& p0 W8 K: \
: p8 |* g! r! C$ }0 ]1 ]+ g% l
% s. ]& n' p3 m6 X1 @, }# q9 J" H% I; b1 n+ V6 d# `
点击+添加,这里要根据自己使用的模型,以及模型特点选择,如下图选择的是原始模型. `4 D) [2 _& ?6 @& [, I' T
5 l; Z$ a4 h1 o5 t/ w2 J* P, t/ b4 I, Q) u
这里选择的是量化后的模型(量化可以减少模型的要求,但是精度会下降),点击分析
8 v3 R" p; k4 g; l' X2 h) T
, P$ o9 M& S1 q' V
1 J5 R) N1 l8 e9 T* A
分析中
; _8 z' e8 y$ f' A5 M
: |0 K0 ~2 }. N# a1 G) N% l+ a) b B. Z, V
8 B6 O$ `" o+ h& v分析完成会显示是否可以部署到设备上,以及资源使用情况。
) t- U$ X5 S3 a% h% s% h6 L: ?3 l
0 h- g# d- Z5 r( ~4 j' z# n/ W! p
" d+ v# e. z0 U+ F, k5 @/ h
回到工程,有个小bug(使用的STM32CubeMX版本为6.6.1,X-CUBE-AI版本为7.2.0),下图的几个文件路径老是生成错9 \0 u$ u5 y2 J" e2 {3 C/ w
3 _! P6 {4 F& _4 i2 C C2 C( W' M" r0 D1 ~, x
" X6 b- H% O1 N* W. Q! g! }
% f, N' J4 C- M( P2 [右键文件打开设置,修改一下路径就行2 R8 t6 o+ Y2 w4 q
8 u- M; W& J6 F4 p' C5 N V
3 q v! y, \& f1 S* H+ P) P R& A8 I" w# |" g: x
头文件路径也有一样的问题
$ N4 `7 F1 y, @9 h6 y
7 e/ Q( [" S u
" H B2 a2 ^/ I1 s$ |% s
初始化模型- ai_handle ai_init(void)+ K5 z$ d4 h2 r. a- |1 s6 r- I' e
- {
- e' {3 Q$ A& [% y: R6 }: P - network_handle = AI_HANDLE_NULL;
, @$ F( L5 k& J; W$ ]& ^ Z; Y
. w7 x5 f& k4 q. |: G' G9 u9 V- m- /* Creating the network */
- @* K+ i: G) m- G; P5 w - ai_network_create(&network_handle, AI_NETWORK_DATA_CONFIG);/ q2 C: G* g4 q* N. q0 }9 Z1 }
6 W" {* k- [# c% b* [, u3 ~- /* Initialize param structure for the activation and weight buffers */% ^( d4 i0 j8 q
- const ai_network_params params = AI_NETWORK_PARAMS_INIT(7 J% Q7 C% U c8 W; b& X
- AI_NETWORK_DATA_WEIGHTS(ai_network_data_weights_get()),! \" E' B% s" }$ e) ^6 j) V
- AI_NETWORK_DATA_ACTIVATIONS(activations)
& d( d1 ?/ J6 z @ C - );
4 s2 ?7 U3 C9 R - 7 a+ a* N! t" {# a4 \+ e* M
- /* Initializing the network */
% X" X; U. r3 e# _# q - ai_network_init(network_handle, ¶ms);
$ R+ ~% |* ]: W4 ?7 U( H }, a. O - ) w, T3 B" [. X* r/ q+ a3 T
- /*Retrieve network descriptor*/
0 M+ F1 H& U u o9 ? - ai_network_get_info(network_handle, &desc_report);- p5 K* K' B# v$ S9 C( @9 ]
- ; d: x5 Z1 D- j4 p7 g
- /*Copy descriptor info*/' O6 {, A9 r* C n7 l. B, j2 ]' }
- ai_input[0]= desc_report.inputs[0];( e5 u0 o, |. c
- ai_output[0]= desc_report.outputs[0];/ l, Y; L5 T% S& U' k
-
0 D0 a: b. @: c5 x - return desc_report.inputs->data;
3 l( q* M4 |8 ]) n7 z" R$ A7 C - }
复制代码
/ X) K* c' i6 l! n o6 j! w2 Z+ C% P1 A运行模型
6 C6 M. M8 w& j& a- void ai_run(void* input, void* output)
9 D* Q1 g; B o. s* o$ P - {
+ G* I; @2 I! ? g4 x. F - ai_i32 nbatch;3 D6 H" X# w, ]
- , P) r/ n0 ?$ i% v. ^' V' g
- ai_input[0].data = AI_HANDLE_PTR(input);
3 z8 O4 }6 E0 c4 h6 K - ai_output[0].data = AI_HANDLE_PTR(output); \9 n9 C1 l8 z" R; Y% B8 `% f
- 4 r) T2 Q. g. ^6 T( i
- nbatch = ai_network_run(network_handle, &ai_input[0], &ai_output[0]);
& ?8 v( D& O9 P4 L - 7 U1 T, A. }2 |3 Y+ y6 |4 L3 l6 I
- if (nbatch != 1) {7 `* O1 M: s, n
- while(1);
# R; h2 q+ D! V7 n" P2 |4 x4 a - }
2 g. v+ Z2 |7 l' y5 K- X. k - }
复制代码 - _! I8 C5 Q* [0 f
图像接收处理,这个模型要求输入224*224的RGB888的图像,把数据转换一下。1 t- C0 k/ P `" K; ^$ w, K7 u
- void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
- p* E( t z4 z R2 V - {
1 {3 j1 q& \: U - uint8_t person_flag;
9 r5 m. e+ o5 u5 D - int i,j;1 l2 v. f: m2 C! }! T; ]
- for(i=0; i<224; i++)0 o4 q: n4 z# n) F" V& h4 ?2 c3 u
- {" N( X3 G2 @( i3 U2 G: C0 s9 z P
- for(j=0; j<224; j++)# ?. j* k5 O; j) R# q% q
- {
) d) ], [( k8 P; x - uint16_t bg_color = ((uint16_t *)_OV2640->frame->buffer)[i*320 + j];4 @, d4 w: Z! Z
- network_input[3*i*224 + 3*j + 0] = ((bg_color>>11)&0xff)<<3;7 K3 H1 p3 Y2 y/ U9 x
- network_input[3*i*224 + 3*j + 1] = ((bg_color>>5)&0x3f)<<2;8 V& k; U. P6 u# g4 A" K. e) u
- network_input[3*i*224 + 3*j + 2] = (bg_color&0x1f)<<2;
2 p# M$ O; {/ v) u, C+ T3 q& h - }
" S2 h& |, _) D+ ~ - }! Y; k) t2 E& u
- ai_run(network_input, network_output);# n+ U) U7 N' C3 K
! y @3 {" O4 \* ^- LCD_Draw_Image(0, 0, 320, 240, (uint16_t *)_OV2640->frame->buffer);& Y* n8 K/ S+ Y1 z& T8 E
- LCD_Draw_String(0, 0, 320, 240, 32, output_labels[network_max()]);$ I% k3 L j6 x% h
-
0 y6 r- f! h A& N' y - OV2640_DMA_Config(_OV2640->frame->buffer, (_OV2640->frame->length)/4);
' X2 v7 |) E( b% x - 5 M& H0 q/ G" o( u+ D- r2 G' I
- }
复制代码
2 x* K h- b/ _
" w: N2 D& `2 G: p; Y9 G& a运行效果(一共能识别18种食物,这里选了几个看看)
) D6 g: I9 l* b* p. e' a( `! v6 z; R0 X% x- ?
空
9 M, x/ g, K8 _9 R
- ~+ W% ?9 E5 D+ c4 n% A. d( W可乐
# M) }( Q) l. j) d
; }- W6 r+ p7 L' \1 ?% Q
, G* w" C/ X6 Z甜甜圈
9 M: J5 E2 v7 W4 n0 L$ h
$ d5 ?3 C0 c |, h0 r2 D6 C/ v3 t
汉堡包+ q2 G3 Q' ?( M# v, j$ ^! m
5 M! ^4 ~) P, m4 U$ |" y4 S
, J, d1 h( q8 Y8 `8 O" e1 ~& a+ o薯条) g! M$ ]2 Q+ B
/ u9 O+ `* j S8 _" a8 q% t1 L8 e, r9 t: d8 e
& B/ j2 j8 o6 D4 i( v小结:STM32Cube.AI工具真的太香了,这里仅仅演示了模型的部署,其实可以快速验证AI模型在目标板上的运行情况,只用串口连接,直接把输入发送到单片机,然后运行完后把结果返回来,全部都集成到了一起,快速验证模型运行情况。很是方便(本文未涉及,有需要的可以在X-CUBE-AI行下勾选时,application里面选择validation,回到配置界面后设置通信接口即可)
& Z* h( I, u( W3 J5 P. w. dWio Lite AI视觉开发套件确实是开发AI的很好的选择之一,板子虽小五脏俱全,拿来做单片机视觉绰绰有余,但是不得不吐槽的一点是资料支持太差了,原理图,代码全都藏起来,前期调驱动花了很长的时间,后来管管给了一个例程后好转了一些(但是已经晚了。。。),Ai在单片机上应用已经有很多厂商都推出类似的解决方案了,ST这一个环境很优秀,就是如果相关的培训跟资料再多一点就好了。
3 z4 m; v7 S. V& t5 m |
up有没有原理图资料~
求求了
<br /> <br />
好久之前做的了,资料都忘了放哪里了。。。你可以在网上找找,或者找卖家要
<br /> <br />
up 有更详细一点的建文件工程的教程吗? 还有模型怎么弄上去, 求解
<br /> <br />
按这个文章操作就行