Tensorflow Lite Micro是tensorflow框架针对微控制器应用场景所专门设计的深度学习推理框架,它占用的资源少,运行时内存最低只需要16KB,同时其兼容tensorflow框架,依托于Tensorflow平台强大的生态背景,使得更多开发者可以方便的集成、使用AI算法,为端侧带来人工智能的新活力。其中Tensorflow Lite模型也被ST的AI工具所支持,但是我们这次是不通过STM32提供的AI工具,而是移植Tensorflow Lite代码去运行其模型。* y% \# y7 l I& O, j7 E) \, |% n
0 `- @- t7 U4 U O5 y9 F: Q4 q( S
首先获取Tensorflow LiteMCU版的源代码:https://github.com/tensorflow/tflite-micro
7 }' S, J4 i" [* \# o# J+ p. V* T! C1 F* p3 K7 M6 I
根据教程获取工程代码:TFLITE-micro/new_platform_support.md at Main ·张量流/TFLITE-micro ·吉特哈布 (github.com)
2 x7 l: L/ U" C) T9 a, C1 r- m8 v" ~; `* l- @/ m/ a% X$ Y* y
文件都扔工程里面,太多了,截图只是一部分。把CMSIS-NN库(算子加速)也扔进去,加速运算
}8 W6 o6 a0 u5 W
. ^$ I$ K7 h9 k
% U& { L, v, j+ ]7 H- Z
添加相关路径
: k/ @+ _4 T9 q! K, T
3 w5 \% \ z# l P; _* Q8 z
5 J# u* P O: y* A8 H% o, F
设置工程,使用AC6编译,关闭Keil的Microlib库
1 O) e+ `' U- y% {; v
, _- O# \- p9 h: L# A6 E& f0 N
编译选项使用-Os,这样代码体积小点
6 `$ g6 `8 t8 v$ o
* S" y& u' U2 b
, ?1 Z0 P5 m( D
图像预处理函数。模型要求输入神经网络的图像为灰度图,为完成摄像头获取的RGB彩图到模型输入需要的灰度图转换,需从输入的RGB565像素格式中解析出R、G、B三通道的值,再根据心理学公式计算出单个像素点的灰度,具体代码如下:- uint8_t rgb565_to_gray(uint16_t bg_color)4 \. W. s A# G9 u* v0 \7 p0 ?
- {
) s0 {; w6 _2 i) H - uint8_t bg_r = 0;7 T# e: W* ^' E* h9 n5 `7 n
- uint8_t bg_g = 0;
6 ?5 O$ ?# j9 r, i, P/ D# o - uint8_t bg_b = 0;
/ _2 `1 R# S7 I0 q( |, ?% j - bg_r = ((bg_color>>11)&0xff)<<3;! y5 w" T! N9 R6 R2 y( ?- [# G3 j; ]
- bg_g = ((bg_color>>5)&0x3f)<<2;, ?1 W: q8 L: x) Z* K
- bg_b = (bg_color&0x1f)<<2;; }' b' F; ~" P& A' `
- uint8_t gray = (bg_r*299 + bg_g*587 + bg_b*114 + 500) / 1000;) J: `$ V5 U2 N& U( g5 _" u; G5 Z" o `
- return gray;
0 z* k2 _2 N! P% ?+ u& n - }
1 w6 u \4 W3 L) b+ @
6 g' H" ]* Q) E& I+ r. i8 |- void input_convert(uint16_t* camera_buffer , uint8_t* model_buffer)) B: ]) n- D2 Z/ _- D
- {7 e0 H4 X3 d/ y. V. P% W, B
- int i,j;
" D+ R9 _' v+ e2 q) A - for(i=0; i<96; i++)! k# q' n9 U. f. Q! e- L& C
- {
0 |) F( O! Z% h0 R1 J% Q6 O - for(j=0; j<96; j++)
8 Z G7 n2 @0 f& r% W5 U, b$ P - {# N n+ S7 H7 O! V
- model_buffer[i*96+j] = rgb565_to_gray(camera_buffer[i*2*320 + j*2 + 64 + 320*24]); Z. b, K" N% _; g. \1 w( Q) M
- }* l, L$ X3 x( H3 U! B, _
- }
1 ~; d7 T. f1 H* l8 n/ ?. S - }
复制代码
; h- l5 K* J6 }' W* _" e在图像接收中断里面处理识别过程- void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)8 \0 n" y8 @& e
- {1 K+ X" r2 X& A2 ~8 `4 e$ Q! r
- uint8_t person_flag;
$ D9 K* w5 X8 y/ w' j) L' @! O
* z: F% ~1 F' w3 A* x g+ `) a- //转换图像为模型可处理的大小
* f3 J, W4 m$ X8 i8 a' B: w - input_convert((uint16_t*)_OV2640->frame->buffer, model_buffer);# _; z; b, F7 H- c- B: }* Z4 ^. l# \/ d
- person_flag = person_detect(model_buffer); //运行模型) I b5 \2 h& |/ I# ` W
- . D, s( H" R( w' H9 K1 l
- LCD_Draw_Image(0, 0, 320, 240, (uint16_t *)_OV2640->frame->buffer); H; Y0 s. y9 v2 T7 y4 y3 m$ W. |; v
- for(int i=0;i<192;i++)
9 i" s; k: P% Q - {
- e: ~# S* S. _0 r - LCD_Draw_Point(i+64, 192+24,0xf100);) s% f( d5 A. j- R
- LCD_Draw_Point(192+64,i+24, 0xf100);
5 t# I) w; Z: [/ o4 W - LCD_Draw_Point(i+64, 0+24, 0xf100);
" U6 M* s% X* J! I) w+ t - LCD_Draw_Point(64, i+24, 0xf100);- |; |9 C2 q& m% }
- }
3 B# j- I; b, s* w5 g - if(person_flag!=0)LCD_Draw_String(0, 0, 320, 240, 32, "people");% Z# p/ b9 Y& L$ x' u
- 5 t' \' p: ]5 V
- OV2640_DMA_Config(_OV2640->frame->buffer, (_OV2640->frame->length)/4);
& W2 B8 D* T& Z. \/ \7 z; s - }
复制代码 $ f4 S3 V2 _, |
& O( u% b5 A5 @. X
6 f3 H1 w3 `9 p6 v. |- h" W- l运行效果:
" E, u5 V" }) @" G) u8 p识别充电器(无反应)
9 ~9 k% J& U$ b6 h6 N
3 u. B0 ~9 q$ J5 O7 D% z
$ x- {8 j* L$ R9 d( ]+ R8 W' A7 J/ f& ]& f% e6 }+ V, @
识别打火机(无反应)
8 a" j. o6 M. k% H
7 T& t9 \7 P1 B3 j3 a5 E/ z" b ~3 a) G1 s. k
识别人体(显示people)7 z" `- L5 }8 t
; r+ P1 r* G% w/ J( ?6 m
+ e' p* }0 E4 Y" @& ^. y0 f4 f5 o
- k+ Q$ Y7 o- ?. v
6 G3 f) f. Y8 ^ A- \3 \
|
你好,请问有些源文件是重名的,该怎么才能解决冲突
一些是需要删掉的,二选一