你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【Wio Lite AI视觉开发套件】人脸识别快速实现

[复制链接]
北方. 发布时间:2022-10-17 10:57
Wio Lite AI视觉开发套件——人脸识别快速实现5 q9 [: j* F& ]. Y) r* d( f( K
1、在完成基本硬件评测和软件开发环境配置之后,可以快速实现人脸识别的任务
# w" y% q! y- i0 ^2、首先按照新的ST-link连接,把Nucleo的st-link调试如下图连接,
) e5 c; e# l! N nucleo_stlink.png
1 ^/ v9 u8 g/ F; s采用如下接口对应联络到WIO Lite AI开发板,
1 D4 r8 R. r9 }
6 c& l5 n' S7 k$ R Nu_WIO.png 7 ^( D; ?1 l9 H1 }3 u
使用调试夹子快速连接,就可以,如下图,* ?5 h0 i7 X7 q' A) x
353481694.jpg
, ^0 J' O# O. M$ N  G) h% C& ], C8 J在项目的接口可以发现ST-LInk在Port Com8,另一个是COM5,连接WIO Lite AI
" e- w% E3 m4 A- ?. w
9 U) {- [3 c; t  H Nu_WIO_03.PNG $ r& H* g- ~1 f: g: q1 g$ b
2、创建模板项目,启动CubeIDE, P( i+ f9 X  A4 H9 e8 |. M
Nu_WIO_02.PNG
1 e  M2 t+ O+ c  W; G2 A! }. V可以找到人脸识别的模型,Person_detect.tflite,这个是用于人脸识别的tensorflow 模型。这个是压缩后的整数型数据,人脸识别在标准情况下,现在已经可以做到90%以上,那么压缩之后,精度下降,识别精度明显下降,但是仍然可以完美实现该功能。7 G* @) g# M: ?9 D- `
完成编译,执行下载,显示成功完成。" u0 a* R1 b& x" I5 m$ J2 @

$ I1 x8 g  A9 v Nu_WIO_01.PNG
: p0 j8 |0 Q- G0 G6 g3、运行模拟
( z4 Q" K* T# g( c. |3 _上电后,摄像头捕捉图像,并显示在LCD屏上,当图片是空白,或者没有发现人的时候,显示No-person,* Y3 S9 y( D5 F( |- D
这里用手机摄像头遮挡面部,就显示没发现人脸,显示准确度可以达到80%,
4 ^: |4 A) i6 E
, v) b9 j* j. g Nu_WIO_05.jpg
( C8 A5 t$ @+ ^  E. D7 b; K( Z) Y移开手机,露出人脸,就迅速监测到人脸,显示Person,同时计算出准确率61%。7 B9 R) G9 v, o
" Q% B5 G$ C' n  @  z& ]
Nu_WIO_06.jpg " ~$ t; A6 H8 i# b2 K
这样快速监测成功。
8 z& m6 {, g& i& f; \: d8 X4、人工智能实现的分析
( ^3 f" B* D7 i7 a1 o" ?, Z3 Y7 K4.1 硬件平台的能力2 Q6 ?- S1 [: s/ I5 N  \  o! I% K
WIO LiteAI采用的是STM32H725工作频率高达550 MHz的Arm® Cortex®-M7内核(具有双精度浮点单元),可选扩展室温范围最高为125 °C (*),只有一个内核,仍然展现强大的计算能力,可以无延迟实现图像处理和人脸识别。在图形上采用的高性能的支持,具有以下两个图形实现和加速功能,
+ W3 A; |, {( l  z  W
  • LCD-TFT控制器接口支持双层图形
  • Chrom-ART Accelerator™提高了图形内容创建速度,并为其它应用节省了MCU内核处理带宽5 X: l. u8 s4 [. H. K6 g$ Z3 P
, y# {% q' P- K3 D9 r3 d
3 _$ g/ F5 @, l
4.2 人脸识别的流程和库的支持
8 B+ {9 {+ q2 a9 T7 p8 ^& i9 [CubeAI的人脸识别是用如下层次实现
3 `1 E0 m7 O& E3 u& v Nu_WIO_07.png 2 u6 z. Y  H# b  }( A/ R
在底层硬件上,实现板级支持,更上一层是STM32的人脸识别模型,实现具体的应用,实现过程的数据流程如下- N# q+ I; [2 `1 `  e% F  W# n& n0 Y
FaceReco_Dataflow.png
1 P/ t: v6 {, S数据依次在上述流程中逐级计算,根据人工智能模型实现人脸的识别精度计算,当大于计算值以后就迅速提出结果并显示出来" y$ l. q$ L9 _0 p1 W9 A$ K! ~$ k
4.3 程序代码分析
( i+ M) D' a) l: W7 {. l" r5 T首先定义图形数据的交换空间,是一个320x240的采样空间* f( ^4 w- z6 k) L: u' S; O: q: F) ?
  1. static Frame_TypeDef frame ={ .buffer = buffer,
    ( x+ r% Z; |0 r5 ^- I
  2.                                                           .length = 320 * 240 * 2,
    & `; k7 I% m; }3 G9 @
  3.                                                           .width  = 320,6 D$ R9 D  \6 W4 Q' ?8 S* D8 l; F
  4.                                                           .height = 240
    / @4 L7 p+ ^, g; b6 X; J7 Q$ P8 w
  5.                                                         };
复制代码
主程序代码非常精简" E5 j- Y, c1 b
  1. , B/ C- T4 @# \& b$ W
  2. int main(void)
    ; h0 r' M  a8 L* l7 u9 e5 z+ A2 i$ ?9 d
  3. {
    2 ~8 F% O" \+ l2 w
  4.   MPU_Config();; g& r0 e; n1 B; K6 y
  5.   SCB_EnableICache();
      ?  i. m% d' d) w: I
  6.   SCB_EnableDCache();/ s5 M& q5 f% _
  7.   HAL_Init();
    , i' I6 W8 w, X9 N' x& @# y
  8.   SystemClock_Config();0 c  v7 y* h5 e, C

  9. * @, C$ z0 d1 @1 n
  10.   /* Initialize all configured peripherals */4 `! F. y; S$ T5 ]- E
  11.   MX_GPIO_Init();" @! F' a% C. z: {0 {9 p
  12.   MX_USART3_UART_Init();
    3 f" ?" u, [: i' f. X
  13.   MX_LTDC_Init();
    0 |8 H; _; |! M# s. G
  14.   MX_I2C4_Init();
    . w1 L) W$ c$ ?7 O* {
  15.   MX_DMA_Init();2 q. _) A) j2 q) h1 v
  16.   MX_DCMI_Init();
    7 k$ }7 D0 R% b9 R( e+ P
  17.   MX_TIM2_Init();
    2 w8 R6 k& X2 _$ }
  18.   MX_OCTOSPI1_Init();, M9 i% B! g# j
  19.   MX_CRC_Init();
    4 X7 E9 c  r9 ^. @
  20.         LOG("here");
    / |$ F4 q2 |3 {0 u
  21.         Psram_Init();
    # y- n! _" U7 z5 _+ M

  22. 4 O3 q! D) i, R, C) L
  23.         /*OV2640 Init*/
    8 t9 ~: g& n$ V+ ~) o
  24.         HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); //XCLK' d1 g: R: ~; Z; |* F1 K
  25.         OV2640_Init(&OV2640);
    2 }  R+ f% I+ i' M; l$ E& w
  26.         OV2640_ReadID(&(OV2640.ID));1 O8 f" n5 ^0 k. T/ x6 a( M' F
  27.         LOG("ID: %02X %02X \r\n", OV2640.ID.PIDH, OV2640.ID.PIDL);
    7 B, b' w4 [% M6 P  \1 l0 i
  28.         OV2640_UXGAConfig();        //flip after all the camera setting ,or camera setting  will change REG04 value.+ H6 K0 r/ |' v2 _- _! |. {
  29.         OV2640_Flip();
    $ K2 w  e# ]3 F7 \; t- ^
  30.         OV2640_Start();        //initial IPL and AI
    , K# Y5 @5 C! y- S: r$ n# V
  31.         STM32Ipl_InitLib(buffer_ipl, IPL_BUFFER_SIZE);, F/ a: E, k# u  G. G& J
  32.         /* The STM32 CRC IP clock should be enabled to use the network runtime library *// [/ W" v0 ]+ f* ^6 G1 c
  33.         __HAL_RCC_CRC_CLK_ENABLE();* C6 ~* ?$ w6 q+ C2 e
  34.         aiInit();; o+ U3 @. F9 v0 S: V1 a. p' s
  35.         frame_rgb565.data = frame.buffer;
    4 ~# ?* a( C/ D' ?# f, B( @

  36. & ~/ m) X0 ?( M0 f
  37.         while (1)2 u9 s6 ]' Q8 c
  38.         {
    ! k5 F! D0 X; ^& i# N6 D  g0 U% o( L
  39.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    % X, V# m9 k0 |, O- O
  40.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET);$ o* s% f4 g" x9 @7 T7 j, g9 G, Y- m  k

  41. 7 o6 b, t- g$ P* T2 ~: N+ ~
  42.                   // rgb565 320*240*2 to grayscale 320*240: F! T, X0 g# @/ p1 n1 Q# @
  43.                   if (STM32Ipl_Convert(&frame_rgb565, &frame_rgb565_grayscale) != stm32ipl_err_Ok) {- y7 P  Q2 f0 ]: g" ~5 L  [# T
  44.                           while(1);
    2 Y$ A/ w8 f( m, {) Y0 D
  45.                   }
    ; b& c( p( `/ `0 b3 J% |/ w
  46.                   // grayscale 320*240 to grayscale 96x96x2. B/ Q# n) O+ |
  47.                   if (STM32Ipl_Resize(&frame_rgb565_grayscale, &frame_grayscale_resized, &roi) != stm32ipl_err_Ok) {' y7 M  i; }; K6 y4 L2 h0 m/ [$ ~
  48.                           while(1);
    , P) x4 ^% M0 S8 v9 }( @
  49.                   }
    " X$ f" O+ J+ ]- e% L7 v7 r, d
  50. 7 k# L" A8 F& U; H. o9 P2 U4 y
  51.                   //AI
    / ~* Y, I" F9 x! ~; S
  52.                   aiRun(buffer_grayscale_resized, network_output);  t3 k, l) ?, a6 U5 a7 }
  53.                   postprocess(network_output);& G' }4 K  T: K# C: q* A8 e$ F4 \
  54. 7 _% s) t2 d4 T4 g; s
  55.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);/ s# q2 u) ~4 d) Q
  56.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET);: W4 a+ V+ ~* p9 d& K* ]% i3 ~3 L

  57. 0 g% `: h1 h' o) C) b
  58.         }
    $ p9 X9 D6 i3 Y7 ?; k
  59. }" S+ N8 W/ \$ ~& A
复制代码
在启动硬件初始化之后,就进入识别循环,当识别出人脸就直接把对应的LED点亮,( d4 u7 L( H; ^% i- I6 X# W
实现人脸识别的函数是aiRun,对图形交换空间的数据分析,并直接输出神经网络计算的结果
4 V7 n( W/ g: {; {. J, H5 G# x1 N
* R! I9 b8 M) N7 r
  1. aiRun(buffer_grayscale_resized, network_output);8 V( Y/ M* Y# v
  2. postprocess(network_output);
复制代码
这个函数是在"ai_inference.h"文件中实现的,' e! B0 H( K: _  T" }' b& p% G
  1. void aiRun(ai_u8 *pIn, ai_u8 *pOut), O" d4 {9 A2 C& s# W8 ?; f
  2. {
    8 c7 }0 N" Y, f
  3.   ai_i32 batch;) R7 i- J9 J2 @: J- H1 h5 c
  4.   ai_error err;
    " `) }* v0 d- O& i

  5. 9 y/ V5 j* O; b
  6.   /* 1 - Create the AI buffer IO handlers with the default definition */
    , b! C# G  Q5 p4 {5 l
  7.   ai_buffer ai_input[AI_NETWORK_IN_NUM] = AI_NETWORK_IN;
    0 ~4 v) t6 G" ~. D8 S- z9 P- P2 k( M
  8.   ai_buffer ai_output[AI_NETWORK_OUT_NUM] = AI_NETWORK_OUT;
    3 X5 C" `1 o6 b" X! g

  9. ' K) x; W4 F) Q9 g' m( p  |1 ?
  10.   /* 2 - Update IO handlers with the data payload */$ u# G# |# O& C
  11.   ai_input[0].n_batches = 1;
    & r3 X4 P9 u" a9 ^: v
  12.   ai_input[0].data = AI_HANDLE_PTR(pIn);
    5 Z) }: y, H3 f0 [( c- f
  13.   ai_output[0].n_batches = 1;
    % [7 T/ [" J4 n/ O$ P6 N- J
  14.   ai_output[0].data = AI_HANDLE_PTR(pOut);" B# h, |# k0 H0 u4 W
  15. 9 |/ ?8 x9 m  l8 W' b9 ?
  16.   batch = ai_network_run(network, ai_input, ai_output);& t4 ^6 p3 h6 U) c
  17.   if (batch != 1) {
    . L9 {+ ~5 n6 a! ^
  18.     err = ai_network_get_error(network);! j/ V% T1 M) p. P
  19.     printf("AI ai_network_run error - type=%d code=%d\r\n", err.type, err.code);
      N4 b8 U! K3 o0 O! U
  20.     Error_Handler();1 V/ r$ N4 d3 \' i' n/ c' Z/ c! m
  21.   }
    2 W* W4 a, @3 h* S$ E
  22. }7 D$ ?! n% e% b/ L$ I
复制代码
上述过程就是流程图数据流实现的过程,读取经过预处理的图像数据,然后再ai网络中计算,输出计算结果,
. q( f5 j9 m/ J7 c0 N
  1. ai_i32 ai_network_run(
    7 i' u4 [7 _6 `+ |3 ~2 o
  2.   ai_handle network, const ai_buffer* input, ai_buffer* output)" L# n8 `* a  W- y
  3. {
    ; _4 k3 J# S3 ~. S4 i! m" P" O
  4.   return ai_platform_network_process(network, input, output);
    & ?  b. a0 q* p. h( X
  5. }
复制代码
上述处理,需要计算网络,这个是再ai_model中定义的,然后读取输入数据,形成输出数据。2 F( K' @; X2 N0 X' Q

; C0 o  A0 |; A# j. p5 小结
/ W- R( W* Y1 E, h8 c    基于STM的cubeAI,通常已经提供了一个快速部署的流程框架。对于开发者,只需要自定义人工智能模型,然后导入到新建的工程中,按照提供的API逐步实现数据流程,就能够在项目中嵌入人工智能的功能。
' R, ^8 _* Q* e7 V$ \) B% a( E* V  在上一个文件中提高的,对应模型的生产,采用CubeAI中的命令行指令,stm32ai就可以完整实现。这个CubeAI极其配套工具,就是一个完整实现人工智能嵌入的工具,虽然安装和使用流程比较多,但是能够实现这样的效果还是非常理想的,在硬件性能和软件功能,达到完美的结合。5 Y3 U! z3 R0 ?8 g% i: G, `

% U; l; `2 ^' H; A4 p, @8 o, h4 ]3 }" D" q

+ P  U, K. Q$ I8 K* f- z: s7 \; K

' b& q; \  n5 w" s" j( E) s% [2 w9 t& d2 a9 ?5 l
+ @* v$ _3 L/ k# }! S; h3 M4 n8 D

: M$ ?6 }: b3 L) W$ _' N+ x% j7 m4 S: g: }: z+ r

% @7 x+ D% d0 l. k% u1 j4 q6 F
收藏 评论5 发布时间:2022-10-17 10:57

举报

5个回答
小样爱捣鼓 回答时间:2022-10-17 19:17:31
这么好的板子不自己训练个模型尝试部署上去就有点浪费了
" g' [: b: u% o+ y
晒太阳的懒猫 回答时间:2022-11-11 09:35:57
照着评测内容,一步一步学习,让自己更快地获取AI视觉开发的知识,谢谢楼主!% ?! P4 B( W' y* q; T$ \( M
LN 回答时间:2022-11-16 15:26:25
人脸识别算法,可以直接搞个现成的吗?重新训练是不是很复杂
LN 回答时间:2022-11-16 15:29:29
签到( C3 ?& T7 h+ M; `/ M
- E" s3 w4 @4 L( y: E
stm32_AI2.jpg
stm32_AI.jpg
党国特派员 回答时间:2022-12-22 16:45:47
这个网络模型是什么模型?
4 m0 k8 T( ]3 \& A" T3 W2 X* k. a
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版