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

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

[复制链接]
北方. 发布时间:2022-10-17 10:57
Wio Lite AI视觉开发套件——人脸识别快速实现
  q% \% E  e, Q2 n; p* Z" Q  s1、在完成基本硬件评测和软件开发环境配置之后,可以快速实现人脸识别的任务
* ~9 n+ g- X8 b( l3 ]  q2、首先按照新的ST-link连接,把Nucleo的st-link调试如下图连接,8 V7 S1 u2 g( U" {- c' n
nucleo_stlink.png % B" `1 O* A6 @
采用如下接口对应联络到WIO Lite AI开发板,
# J( a  f! e; [1 y+ ?: f1 A  D+ R( |: L3 l; }1 x* e
Nu_WIO.png
% o5 L$ z. ~: i使用调试夹子快速连接,就可以,如下图,
* L0 R1 y6 f  K- U 353481694.jpg 4 s7 a5 ]5 [' R) V$ x- R9 W# u
在项目的接口可以发现ST-LInk在Port Com8,另一个是COM5,连接WIO Lite AI
4 v6 {: a* r! B  Y; @' G9 ?! ^8 b& E! ]1 @( K
Nu_WIO_03.PNG
/ J6 t1 A. O; j- Z1 r/ k2、创建模板项目,启动CubeIDE9 ^" J. s$ {" k3 F
Nu_WIO_02.PNG
2 e' {3 l- f4 Y$ o. A% ]: O可以找到人脸识别的模型,Person_detect.tflite,这个是用于人脸识别的tensorflow 模型。这个是压缩后的整数型数据,人脸识别在标准情况下,现在已经可以做到90%以上,那么压缩之后,精度下降,识别精度明显下降,但是仍然可以完美实现该功能。1 W3 }- r$ f4 ^, o3 T) m: q
完成编译,执行下载,显示成功完成。
- E% T  f5 p  N; ^" n3 C7 j: p; ~% I' m( k7 Y7 V# }! @  r. U
Nu_WIO_01.PNG
4 ^. O& u# z3 r2 f" J8 }3 f  B3、运行模拟2 m8 {& w4 |" b
上电后,摄像头捕捉图像,并显示在LCD屏上,当图片是空白,或者没有发现人的时候,显示No-person,5 z3 J) W: b0 G& q9 s9 y
这里用手机摄像头遮挡面部,就显示没发现人脸,显示准确度可以达到80%,) C/ |8 ?* r  q& A; A6 H/ y

3 j. m: l" G) t" _# ^! a5 Y- E, [ Nu_WIO_05.jpg + `9 D0 v2 O2 P$ Z& y& ^! R% M
移开手机,露出人脸,就迅速监测到人脸,显示Person,同时计算出准确率61%。2 J: g. B" a% n) x
/ l5 P4 W7 S# q' p
Nu_WIO_06.jpg - n# k0 D1 \2 [1 G. \% }
这样快速监测成功。
1 C& r6 |. T; `6 p+ |4 F4、人工智能实现的分析. b; Z) }( [: r, U9 L' G- R
4.1 硬件平台的能力
; K3 g  a2 I6 L2 i; o6 JWIO LiteAI采用的是STM32H725工作频率高达550 MHz的Arm® Cortex®-M7内核(具有双精度浮点单元),可选扩展室温范围最高为125 °C (*),只有一个内核,仍然展现强大的计算能力,可以无延迟实现图像处理和人脸识别。在图形上采用的高性能的支持,具有以下两个图形实现和加速功能,
$ _' N& S3 o1 L) E; ^$ h- D2 @$ ?
  • LCD-TFT控制器接口支持双层图形
  • Chrom-ART Accelerator™提高了图形内容创建速度,并为其它应用节省了MCU内核处理带宽! M: s7 f) o  J6 \# |5 d
" A- `5 j: c: K
$ y7 O$ I5 R6 N1 B
4.2 人脸识别的流程和库的支持
% Q* M, i; M, g, B1 r& i% qCubeAI的人脸识别是用如下层次实现' C# F) u- \* u" ?- ^
Nu_WIO_07.png
4 z. P/ _# @2 a! K4 i在底层硬件上,实现板级支持,更上一层是STM32的人脸识别模型,实现具体的应用,实现过程的数据流程如下( a! L' G5 g0 `( t
FaceReco_Dataflow.png % Q0 c* Q6 y: p2 b2 y" F, O% d
数据依次在上述流程中逐级计算,根据人工智能模型实现人脸的识别精度计算,当大于计算值以后就迅速提出结果并显示出来
7 p/ T% B. G4 W0 c' G4.3 程序代码分析
  ?9 I4 i% c( y4 r首先定义图形数据的交换空间,是一个320x240的采样空间9 v& {# G1 V  k) ^  l
  1. static Frame_TypeDef frame ={ .buffer = buffer,
    3 l7 @6 O' y9 x. @6 `  |
  2.                                                           .length = 320 * 240 * 2,
    ! y/ m% t, p7 `* ~) m8 ~! G; j( m' A
  3.                                                           .width  = 320,' k* U/ p8 S5 m9 \9 Q3 A
  4.                                                           .height = 240
    4 k, M" U, @  g; m7 K. Q
  5.                                                         };
复制代码
主程序代码非常精简
; @. M6 F% J2 ^4 E& }2 J$ a* o

  1. # I6 t$ ?0 f- p- r9 w; w4 Y: s
  2. int main(void)8 e5 T1 g/ A5 p) p" h* D
  3. {: H8 n0 ?: V* w* A7 u
  4.   MPU_Config();
    # w9 b5 r$ I/ o( `) a
  5.   SCB_EnableICache();" k1 J5 |( |+ h" d* S) j
  6.   SCB_EnableDCache();7 ^2 Z. f! A9 z: I% ?2 Q) ?) ?
  7.   HAL_Init();
    0 h  [8 u  m7 S3 h0 i: |
  8.   SystemClock_Config();
    ! Y, V1 P" X/ W$ B! w0 I7 [- v

  9. ' x- M' |* s6 k5 G, W6 x" n' t- Y
  10.   /* Initialize all configured peripherals */
    ' ~% ?* K/ d: [8 O4 Y' U6 r% N7 [" p
  11.   MX_GPIO_Init();9 j2 A9 {1 A, }: F7 P
  12.   MX_USART3_UART_Init();# S; ^1 F# ^' z5 v6 ~
  13.   MX_LTDC_Init();
    ; h7 H- S" v1 Q6 ^' o, m* O3 e0 |
  14.   MX_I2C4_Init();
    ) L) S8 d: w; f% i# T+ n
  15.   MX_DMA_Init();3 p7 c% e1 g; C
  16.   MX_DCMI_Init();
    # q0 {& k2 @3 Z3 {& }/ |$ n1 N
  17.   MX_TIM2_Init();
    # D0 X/ f+ ?: N, _5 e
  18.   MX_OCTOSPI1_Init();0 s) P& H' ?0 M& b" @' c% }/ {7 `9 o
  19.   MX_CRC_Init();
    ( \) |! a! J2 H" k4 ]7 X. y: m
  20.         LOG("here");: H& ^" E3 M& V
  21.         Psram_Init();  F/ U, u, g" X% O5 U
  22. 1 q% v8 F: P% v% W6 R! d
  23.         /*OV2640 Init*/# l: A+ A  k; j* y5 x. P
  24.         HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); //XCLK' k2 s- X4 F  `) f! W
  25.         OV2640_Init(&OV2640);3 I* \; V$ `- A' ^6 l
  26.         OV2640_ReadID(&(OV2640.ID));
    ( y9 s' D+ F* a- C; r' c  Q" R# T
  27.         LOG("ID: %02X %02X \r\n", OV2640.ID.PIDH, OV2640.ID.PIDL);* a0 [7 T7 a0 i8 l$ Q" r
  28.         OV2640_UXGAConfig();        //flip after all the camera setting ,or camera setting  will change REG04 value.
    * X4 X1 _; }) W& z2 ]1 o& A  n
  29.         OV2640_Flip();
    9 M8 J8 o. V. u# O5 Z! \$ I. _0 B
  30.         OV2640_Start();        //initial IPL and AI: f" c. z2 b# s% A2 J! s
  31.         STM32Ipl_InitLib(buffer_ipl, IPL_BUFFER_SIZE);
    & D  a- M5 h' }* }
  32.         /* The STM32 CRC IP clock should be enabled to use the network runtime library */; t6 R& [) ?" f0 {4 |% Z0 @2 V' h
  33.         __HAL_RCC_CRC_CLK_ENABLE();& {7 p: v; R0 y7 K8 c) V4 _
  34.         aiInit();
    7 |' R( F/ _0 t" w% {) G9 g, n
  35.         frame_rgb565.data = frame.buffer;
    - J7 n1 o# a+ X- p' D4 V  S

  36. : C' [/ q1 n, F) o
  37.         while (1)# h/ ]! W# w& N2 m5 @
  38.         {
    ' d& F7 {4 S+ y7 a, K! Y' i2 A) h! T
  39.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);) C6 r; I0 V' \
  40.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET);
    $ ?& ~0 v  q" \) S; x
  41. 9 C( W: s) L5 y
  42.                   // rgb565 320*240*2 to grayscale 320*240
    0 @0 U) {) v6 @- b6 E7 v
  43.                   if (STM32Ipl_Convert(&frame_rgb565, &frame_rgb565_grayscale) != stm32ipl_err_Ok) {' Z3 d0 K: C5 t; a! G( J+ q1 t# b
  44.                           while(1);
    & m4 e; o4 }) u+ O+ o) M
  45.                   }) N- y$ ^' J8 Q" p4 c8 R' y7 {
  46.                   // grayscale 320*240 to grayscale 96x96x2
    : R) H8 m/ c0 C4 G
  47.                   if (STM32Ipl_Resize(&frame_rgb565_grayscale, &frame_grayscale_resized, &roi) != stm32ipl_err_Ok) {
    : q. t" `( u$ A: |* [  O3 O
  48.                           while(1);
    9 V' X+ @" f9 Z) A6 ]1 f3 }# w2 ]8 T% N* G
  49.                   }
    & t' m3 z' y/ M, `- X% H
  50. 9 _+ b2 P. s! H, G  A1 `
  51.                   //AI( w2 r  x; Z, B- W
  52.                   aiRun(buffer_grayscale_resized, network_output);. |. r  O6 K/ J+ D
  53.                   postprocess(network_output);
    0 L- M- s9 j' n& x1 z; N

  54. $ y( X8 Z/ f# |3 J; x5 d: A
  55.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    & g4 N9 e7 f6 K% d+ n9 ^
  56.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET);
    , N% ?, j8 k2 Q! V" f% L5 \* r

  57. ( F( w/ o3 U) H# \; c; s
  58.         }
    7 a- L0 u! t. e5 v
  59. }
    + G9 \! c* @- E! p3 z4 K
复制代码
在启动硬件初始化之后,就进入识别循环,当识别出人脸就直接把对应的LED点亮,
$ t' Y) s4 I9 }" H实现人脸识别的函数是aiRun,对图形交换空间的数据分析,并直接输出神经网络计算的结果1 O# H$ ~( Q- b

! c" H1 S% J- P- R" G% `/ z  O
  1. aiRun(buffer_grayscale_resized, network_output);: N. ~3 M$ O0 }
  2. postprocess(network_output);
复制代码
这个函数是在"ai_inference.h"文件中实现的,$ e& z2 Y9 U# `  ^
  1. void aiRun(ai_u8 *pIn, ai_u8 *pOut)6 V% B% v9 N9 A/ O7 Z+ C! J+ Y4 C
  2. {, b. O2 ]$ t0 g1 s" u
  3.   ai_i32 batch;
    ' g* K( y! G9 G) G2 k
  4.   ai_error err;- o6 B& Q$ f) ]1 B. o2 @( ]

  5. 2 N& p' f# x& E
  6.   /* 1 - Create the AI buffer IO handlers with the default definition */1 S. P$ B2 m, B; z3 q
  7.   ai_buffer ai_input[AI_NETWORK_IN_NUM] = AI_NETWORK_IN;
    ! Q% H7 I3 W' w: U$ M8 L4 ^; d
  8.   ai_buffer ai_output[AI_NETWORK_OUT_NUM] = AI_NETWORK_OUT;4 |; a6 P8 J3 G

  9.   B( k+ Z( V5 T0 t, o6 v
  10.   /* 2 - Update IO handlers with the data payload */* S. G% b: g% t8 r9 \: R/ M# I
  11.   ai_input[0].n_batches = 1;. y# T+ V  w; T4 H
  12.   ai_input[0].data = AI_HANDLE_PTR(pIn);/ Q* Z# ?- O$ V7 q
  13.   ai_output[0].n_batches = 1;
    7 }8 y: f0 _2 A% V7 g- ?
  14.   ai_output[0].data = AI_HANDLE_PTR(pOut);
      U! j  ~4 {6 n7 m- s/ L
  15. 6 @( v! o! P- h: o- h
  16.   batch = ai_network_run(network, ai_input, ai_output);) }; G( h# e9 N  t5 |* S
  17.   if (batch != 1) {
    : K8 r# J9 \5 K: o9 \8 n! F( x. w
  18.     err = ai_network_get_error(network);
    " f$ P+ D% O4 ^0 @1 E* u0 z
  19.     printf("AI ai_network_run error - type=%d code=%d\r\n", err.type, err.code);
    & U6 C1 H7 ?1 E; {% t; I; F
  20.     Error_Handler();: I6 u: a" k2 \+ {! I8 Q/ G( F
  21.   }
    0 V5 W3 T$ I8 ~4 D$ ]" v9 n
  22. }
    6 R# q- ?" Z$ X0 U8 E
复制代码
上述过程就是流程图数据流实现的过程,读取经过预处理的图像数据,然后再ai网络中计算,输出计算结果,# ?% h! _* r% J: g( p1 e  O
  1. ai_i32 ai_network_run(5 _4 Q4 r7 t- B- p" m! `
  2.   ai_handle network, const ai_buffer* input, ai_buffer* output)2 k0 \) T# C4 L  X6 `5 ^
  3. {& ~. {/ E* o1 S. v$ }4 u
  4.   return ai_platform_network_process(network, input, output);
    ) r) A! C; Y* G# }. k: q
  5. }
复制代码
上述处理,需要计算网络,这个是再ai_model中定义的,然后读取输入数据,形成输出数据。7 N$ t: [3 V: \4 u% K" ~

5 {6 i1 T4 q1 g% ?+ p+ F+ ^5 小结
8 G2 N! _$ m) B" |    基于STM的cubeAI,通常已经提供了一个快速部署的流程框架。对于开发者,只需要自定义人工智能模型,然后导入到新建的工程中,按照提供的API逐步实现数据流程,就能够在项目中嵌入人工智能的功能。; s- T' F# I* I# g
  在上一个文件中提高的,对应模型的生产,采用CubeAI中的命令行指令,stm32ai就可以完整实现。这个CubeAI极其配套工具,就是一个完整实现人工智能嵌入的工具,虽然安装和使用流程比较多,但是能够实现这样的效果还是非常理想的,在硬件性能和软件功能,达到完美的结合。- {: |# y/ r7 q8 q! O
% \. S' ^- T, G: g8 h. I8 s
7 Y8 s) m; b) q6 L* ^+ ?
1 M* ]4 ]3 V% B/ s' G! f$ t
4 ?: \, M6 S1 I& F
9 N2 |' \; T# C
( k$ U. H; ~, c- ]$ t6 f

3 T  D0 I. g& s! K: b+ U6 a' L
2 @/ B. d0 }1 ?( n* b  a' w- I/ k  f# |$ w" R
- j% A" C) `6 g0 D
收藏 评论7 发布时间:2022-10-17 10:57

举报

7个回答
小样爱捣鼓 回答时间:2022-10-17 19:17:31
这么好的板子不自己训练个模型尝试部署上去就有点浪费了
7 n% F4 i  T: P7 M/ U9 h$ ?
晒太阳的懒猫 回答时间:2022-11-11 09:35:57
照着评测内容,一步一步学习,让自己更快地获取AI视觉开发的知识,谢谢楼主!0 W% `( s5 }1 a
LN 回答时间:2022-11-16 15:26:25
人脸识别算法,可以直接搞个现成的吗?重新训练是不是很复杂
LN 回答时间:2022-11-16 15:29:29
签到
" q7 s* Z- Y6 T5 c+ K% F. L) s* `- Z9 |1 k7 ?
stm32_AI2.jpg
stm32_AI.jpg
党国特派员 回答时间:2022-12-22 16:45:47
这个网络模型是什么模型?0 j7 V1 _" m4 x' f1 G  F& k. [

$ C# h$ j# O& f* N1 q+ q
萨法 回答时间: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 手机版