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

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

[复制链接]
北方. 发布时间:2022-10-17 10:57
Wio Lite AI视觉开发套件——人脸识别快速实现# Q: T+ R8 F- u0 K) X5 C( U
1、在完成基本硬件评测和软件开发环境配置之后,可以快速实现人脸识别的任务
! t; p. i! Y, }5 z& A3 ^2、首先按照新的ST-link连接,把Nucleo的st-link调试如下图连接,1 D3 X% S7 N! @! G
nucleo_stlink.png . m; M' g/ Q* r) I" Z
采用如下接口对应联络到WIO Lite AI开发板,
8 T+ ~6 a, _9 u) Z
$ T* v4 ]1 H$ B Nu_WIO.png . l4 z5 z+ V+ h8 f8 R9 i. P
使用调试夹子快速连接,就可以,如下图,  i0 O% [- }$ C% {8 Y2 T
353481694.jpg
( I6 ]% }8 M. L1 X在项目的接口可以发现ST-LInk在Port Com8,另一个是COM5,连接WIO Lite AI
9 c/ P3 y7 U2 o% m& B  Z7 d5 r4 S0 `. T0 y
Nu_WIO_03.PNG 6 k- _# e) v+ \! r, p
2、创建模板项目,启动CubeIDE
0 B, l3 ]4 ~0 }) A- C Nu_WIO_02.PNG
2 W5 p, f) _/ x可以找到人脸识别的模型,Person_detect.tflite,这个是用于人脸识别的tensorflow 模型。这个是压缩后的整数型数据,人脸识别在标准情况下,现在已经可以做到90%以上,那么压缩之后,精度下降,识别精度明显下降,但是仍然可以完美实现该功能。$ Z, k4 y2 r5 [/ B  @0 @, P
完成编译,执行下载,显示成功完成。/ x8 ^3 i& D: C+ S

- q0 e, m6 q4 d# h4 d2 I: m# U Nu_WIO_01.PNG
7 R) \8 t4 l- D- H: W% R+ @$ E" ?7 t3、运行模拟
, `' T, H1 j. Y1 D' C上电后,摄像头捕捉图像,并显示在LCD屏上,当图片是空白,或者没有发现人的时候,显示No-person,
" `, \. b# p* M0 x7 h这里用手机摄像头遮挡面部,就显示没发现人脸,显示准确度可以达到80%,
, x* j# C( }; u/ u' v' }# G% f, @
Nu_WIO_05.jpg 6 A2 S# ^. h7 T0 v! Y: }% ~
移开手机,露出人脸,就迅速监测到人脸,显示Person,同时计算出准确率61%。
" P  V7 k/ I8 k) b
$ S8 A0 T; j  [3 A+ a Nu_WIO_06.jpg 9 J: b0 `$ M7 a! n! i
这样快速监测成功。
% Q7 D" S+ [3 B/ ~4、人工智能实现的分析3 I3 ]$ S; l. K$ w' Q1 u6 C
4.1 硬件平台的能力2 _! N$ ]. Y$ f" y7 e2 r  D
WIO LiteAI采用的是STM32H725工作频率高达550 MHz的Arm® Cortex®-M7内核(具有双精度浮点单元),可选扩展室温范围最高为125 °C (*),只有一个内核,仍然展现强大的计算能力,可以无延迟实现图像处理和人脸识别。在图形上采用的高性能的支持,具有以下两个图形实现和加速功能,
& ]; I& V  `( h2 \9 S, q5 r
  • LCD-TFT控制器接口支持双层图形
  • Chrom-ART Accelerator™提高了图形内容创建速度,并为其它应用节省了MCU内核处理带宽
    " J0 M# K8 P, I8 q( c: E9 Y5 {

/ X; u* l9 `, n) I6 ^0 _. O7 @" X: K, \! C1 e& D
4.2 人脸识别的流程和库的支持0 d, c" m: A) o7 M' n
CubeAI的人脸识别是用如下层次实现! Q$ H: ~- r- c# n9 T
Nu_WIO_07.png
1 B( y$ T& f/ Q  U3 l在底层硬件上,实现板级支持,更上一层是STM32的人脸识别模型,实现具体的应用,实现过程的数据流程如下
* `$ Y% F# `  u% c0 r FaceReco_Dataflow.png
$ p+ v) t" V5 e. e7 ?* z数据依次在上述流程中逐级计算,根据人工智能模型实现人脸的识别精度计算,当大于计算值以后就迅速提出结果并显示出来
: W! [1 ^0 x0 D2 ^3 X4.3 程序代码分析# V8 B* s- G7 @' D# m$ c
首先定义图形数据的交换空间,是一个320x240的采样空间
. M9 s8 c% Q0 `6 [) m
  1. static Frame_TypeDef frame ={ .buffer = buffer,
    6 Q% w8 d" E9 w8 e' x+ }
  2.                                                           .length = 320 * 240 * 2,$ C: s4 Z$ [% C' H" j
  3.                                                           .width  = 320,
    ; o2 Z0 _! G  m0 @5 |
  4.                                                           .height = 2401 e* \, l. ?# {1 j$ W' f6 _1 ~% y
  5.                                                         };
复制代码
主程序代码非常精简
8 }" j. M. {% g

  1. - h" I! v4 a2 k2 O
  2. int main(void). ?- L. \5 H" o
  3. {9 c$ I5 Y8 R4 U) r% {4 a) v
  4.   MPU_Config();/ }  ~4 O: y8 P
  5.   SCB_EnableICache();
    2 H; e: ?! T+ Y. o( A
  6.   SCB_EnableDCache();/ q6 o$ l# [& d  I
  7.   HAL_Init();; L+ k' ?% I( R6 o0 P8 w
  8.   SystemClock_Config();
    1 H8 Y  s1 u5 X/ T

  9. ; `6 K( `7 k& B. T  P: W/ ^% v% |
  10.   /* Initialize all configured peripherals */- a6 B7 R/ ]# ]* [
  11.   MX_GPIO_Init();
    5 }) g7 {  M' E, f% c: ^* `2 Q
  12.   MX_USART3_UART_Init();
    9 O7 |4 I; Z) L) T) _
  13.   MX_LTDC_Init();) Z5 e1 l4 X+ q! v
  14.   MX_I2C4_Init();6 J& P" v3 Y" F, f9 o3 Z* k' b
  15.   MX_DMA_Init();) ]4 I& s. J0 b! ^, F& D
  16.   MX_DCMI_Init();/ C- \1 |' ]3 b) n- \: ~5 ^* R
  17.   MX_TIM2_Init();
    " S7 W, _, U; W4 v  K
  18.   MX_OCTOSPI1_Init();
    9 r" T8 y8 ^5 x, z0 [' T
  19.   MX_CRC_Init();
    $ b! `" b$ J" r5 l! E
  20.         LOG("here");0 p5 S4 `4 X* s3 W. h/ v
  21.         Psram_Init();: x% C: {% T) R" M; y  d
  22. 9 P; ?8 a% I; C8 x
  23.         /*OV2640 Init*/# X+ s, @+ i9 s& s' S6 ]
  24.         HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); //XCLK2 I3 Y; p  C- S0 x% _
  25.         OV2640_Init(&OV2640);0 |& X: C4 L/ r0 w
  26.         OV2640_ReadID(&(OV2640.ID));
    ' }  h) m8 I; m1 s+ ~
  27.         LOG("ID: %02X %02X \r\n", OV2640.ID.PIDH, OV2640.ID.PIDL);
    : n( M) n2 |% z; }# t# D
  28.         OV2640_UXGAConfig();        //flip after all the camera setting ,or camera setting  will change REG04 value.- C  Z* b1 o4 U7 X6 u; j' t
  29.         OV2640_Flip();' h0 g+ o0 o- R' F: g6 v  J3 o; ?6 V
  30.         OV2640_Start();        //initial IPL and AI; U8 L, i# R: X  y% C- O# h9 C  A
  31.         STM32Ipl_InitLib(buffer_ipl, IPL_BUFFER_SIZE);5 f' w- ?( n5 [1 p$ D2 c
  32.         /* The STM32 CRC IP clock should be enabled to use the network runtime library */- V* x* {# V! F( |: W& w
  33.         __HAL_RCC_CRC_CLK_ENABLE();
    * D# g8 L! _8 j% m9 H7 U  P
  34.         aiInit();) d% G- f+ G$ P8 Y. ^( v) s; q1 f
  35.         frame_rgb565.data = frame.buffer;3 l8 ?) j# V6 C4 \! j

  36. + C& B& |/ y7 C
  37.         while (1)
    9 ?, f- X6 H4 A# q* J- B
  38.         {
    5 W- y" t6 q6 E- U5 s3 T" o
  39.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);- [" u0 d  a. O$ p3 w& `8 w$ B
  40.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET);
    ' ^: ^2 j) p# ?/ `. ?

  41. ' T2 D" S' e$ y0 o
  42.                   // rgb565 320*240*2 to grayscale 320*240# ?9 R4 U" J) {: I1 h+ ]
  43.                   if (STM32Ipl_Convert(&frame_rgb565, &frame_rgb565_grayscale) != stm32ipl_err_Ok) {
    / G3 k, S$ D* h. ^; h1 M# G
  44.                           while(1);
    : {7 g- `  b6 {8 }: y' {( e8 U
  45.                   }7 Y. e2 `" p9 B# f  ], i
  46.                   // grayscale 320*240 to grayscale 96x96x25 r7 R, Y' M+ |: J% C
  47.                   if (STM32Ipl_Resize(&frame_rgb565_grayscale, &frame_grayscale_resized, &roi) != stm32ipl_err_Ok) {
    " N2 B1 t" k* n6 z& H* Q( m6 m
  48.                           while(1);
    5 h2 ~8 R$ B- U
  49.                   }' M, z" o% `! l. o
  50. . A3 X; P5 W  I$ e0 S7 P7 i
  51.                   //AI( g1 S5 {# W5 S4 _! ^
  52.                   aiRun(buffer_grayscale_resized, network_output);7 y( \: ]" p* j! b6 O
  53.                   postprocess(network_output);  j( N  `! [+ K
  54. * Q$ a2 P0 f/ L! ^4 b
  55.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);9 D5 E$ C! w& y/ F( F9 A0 _9 a: {
  56.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET);9 ?4 q3 i- I. N* p! r

  57. 0 x% Q8 d  F, O1 Y' F  x
  58.         }0 U% Y0 A+ G) E% ]
  59. }
    1 B. r2 D" Q( M! [( ?
复制代码
在启动硬件初始化之后,就进入识别循环,当识别出人脸就直接把对应的LED点亮,* Q5 y: ?) x5 A% ~% N! F
实现人脸识别的函数是aiRun,对图形交换空间的数据分析,并直接输出神经网络计算的结果
- t6 q( B/ J) B) A# o  O/ x' z. K8 B
  1. aiRun(buffer_grayscale_resized, network_output);- H% Z. E/ p0 o4 ^& _6 `
  2. postprocess(network_output);
复制代码
这个函数是在"ai_inference.h"文件中实现的,, k/ e7 n  Y' P2 n1 G
  1. void aiRun(ai_u8 *pIn, ai_u8 *pOut)0 f9 a2 _: e$ C* r" q9 F
  2. {8 p! M7 A* D9 ~  _# d( b/ O& ?
  3.   ai_i32 batch;
    ; C  F5 e8 B! G; s2 ^; S
  4.   ai_error err;( @' d( K" C2 c7 `/ u

  5. 9 N- h0 \: [% E% }5 F1 x* `1 z
  6.   /* 1 - Create the AI buffer IO handlers with the default definition */
    0 L8 P+ m! i. L. Y- `! k2 U' Q% D
  7.   ai_buffer ai_input[AI_NETWORK_IN_NUM] = AI_NETWORK_IN;
    5 e8 j! S  X, X7 Z) J4 S
  8.   ai_buffer ai_output[AI_NETWORK_OUT_NUM] = AI_NETWORK_OUT;$ T9 D, o1 L* p" ]! P6 {% J2 u+ h" n9 ^
  9. 1 E0 I4 W) S# g2 Q, A
  10.   /* 2 - Update IO handlers with the data payload */1 M4 b* K3 Q1 l) z) _
  11.   ai_input[0].n_batches = 1;# h9 u" F2 v  f1 U: g
  12.   ai_input[0].data = AI_HANDLE_PTR(pIn);
    : {- G0 c" g3 Y- l  U1 u" f5 O
  13.   ai_output[0].n_batches = 1;
    . e- t2 w$ O6 G$ R* q/ Z
  14.   ai_output[0].data = AI_HANDLE_PTR(pOut);( G* E; C5 t3 j. y4 P/ D3 f6 u0 d

  15. ; @+ ^* R1 U* ?
  16.   batch = ai_network_run(network, ai_input, ai_output);
    8 [& y3 L  \( ]1 Z7 _" O
  17.   if (batch != 1) {
    # C! A; Q8 p9 A2 Z
  18.     err = ai_network_get_error(network);& n- y' h6 b/ A7 z. _" k& j
  19.     printf("AI ai_network_run error - type=%d code=%d\r\n", err.type, err.code);
    ' W- l6 d! c+ }, A, u
  20.     Error_Handler();' Z/ t8 b. F. e& a: V0 [- b
  21.   }
    ; b( ]) m" O/ s4 y2 @4 x+ ^
  22. }& z& `; ^& x/ v7 k# e" K
复制代码
上述过程就是流程图数据流实现的过程,读取经过预处理的图像数据,然后再ai网络中计算,输出计算结果,
  E5 L% o# d% u, E  ]
  1. ai_i32 ai_network_run(
    0 _+ `6 M' ?1 c1 p4 [  r
  2.   ai_handle network, const ai_buffer* input, ai_buffer* output)
    1 S" c( j# O+ Z. N$ H
  3. {
    0 F6 ~) w; Q0 }: f
  4.   return ai_platform_network_process(network, input, output);
    . ^0 t9 g; m) P! j! K
  5. }
复制代码
上述处理,需要计算网络,这个是再ai_model中定义的,然后读取输入数据,形成输出数据。0 ~/ c/ s4 `& l, Y3 U" H2 C4 W
, H7 q! ^, t2 p' n2 [8 |
5 小结
4 G! p# G% H% x  Q" S- [    基于STM的cubeAI,通常已经提供了一个快速部署的流程框架。对于开发者,只需要自定义人工智能模型,然后导入到新建的工程中,按照提供的API逐步实现数据流程,就能够在项目中嵌入人工智能的功能。: P& d& ?- H; g5 O
  在上一个文件中提高的,对应模型的生产,采用CubeAI中的命令行指令,stm32ai就可以完整实现。这个CubeAI极其配套工具,就是一个完整实现人工智能嵌入的工具,虽然安装和使用流程比较多,但是能够实现这样的效果还是非常理想的,在硬件性能和软件功能,达到完美的结合。
1 e% _3 F8 }/ H2 Z9 A( f- q5 L$ S. e4 Y/ X1 h5 g

2 G" l6 f, ~+ Z9 C3 E3 L: V% R2 O: E8 v9 P* b! T
" ^- r9 L4 J* @  }( ~6 x
& t( R( \3 @/ j# ?

  e. `% `& c) A, F4 C  @6 b7 I. O- `. i$ K

4 V1 C' n9 O/ @4 I$ |5 d
$ w" u% L5 a9 y" m
3 i9 O- W- `" F7 ~" x/ h8 n( r. A
收藏 评论7 发布时间:2022-10-17 10:57

举报

7个回答
小样爱捣鼓 回答时间:2022-10-17 19:17:31
这么好的板子不自己训练个模型尝试部署上去就有点浪费了
( X4 q4 t. ^4 Z8 |" G8 Y: O! c  {' G
晒太阳的懒猫 回答时间:2022-11-11 09:35:57
照着评测内容,一步一步学习,让自己更快地获取AI视觉开发的知识,谢谢楼主!
: {0 O& Z1 H; E3 G" m
LN 回答时间:2022-11-16 15:26:25
人脸识别算法,可以直接搞个现成的吗?重新训练是不是很复杂
LN 回答时间:2022-11-16 15:29:29
签到
* [! k: L' B" |7 b- i
. u# B5 I& I. ^) g' h  r
stm32_AI2.jpg
stm32_AI.jpg
党国特派员 回答时间:2022-12-22 16:45:47
这个网络模型是什么模型?
( L7 y3 W7 K4 u- R$ T: d  G5 C+ }; W3 K- G
萨法 回答时间:2025-1-5 14:38:37

大佬求源码

萨法 回答时间:2025-1-12 11:12:49

UP求驱动程序

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版