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

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

[复制链接]
北方. 发布时间:2022-10-17 10:57
Wio Lite AI视觉开发套件——人脸识别快速实现* L, }& H6 u9 C+ W
1、在完成基本硬件评测和软件开发环境配置之后,可以快速实现人脸识别的任务
6 Z' ?) t( B4 v, s# T9 U! i2、首先按照新的ST-link连接,把Nucleo的st-link调试如下图连接,8 h# x6 T5 H+ E6 t
nucleo_stlink.png
) i3 F' w5 i, w& x. |4 r采用如下接口对应联络到WIO Lite AI开发板,( a6 V: ]" n) w+ M& i" B

; h! j/ ?: ?3 t: l% ~& G) u Nu_WIO.png 2 {. K  C" W; ~8 w
使用调试夹子快速连接,就可以,如下图,  m$ \- K  D8 p* \: {9 k' ]' s8 `
353481694.jpg   Z% _* J/ R, e: n
在项目的接口可以发现ST-LInk在Port Com8,另一个是COM5,连接WIO Lite AI* e- `; O4 K, O& |2 T" i% p( }9 a

  y# w9 y( Z& n  D2 g Nu_WIO_03.PNG
9 v/ v; @3 w+ @9 E$ R9 ]: U- p$ i2、创建模板项目,启动CubeIDE
3 ^/ x7 b* u; H. j4 u Nu_WIO_02.PNG
& l* a5 Q/ \/ a. ?0 v3 s% t  C可以找到人脸识别的模型,Person_detect.tflite,这个是用于人脸识别的tensorflow 模型。这个是压缩后的整数型数据,人脸识别在标准情况下,现在已经可以做到90%以上,那么压缩之后,精度下降,识别精度明显下降,但是仍然可以完美实现该功能。0 A! a9 O& L5 b, `, Q2 y
完成编译,执行下载,显示成功完成。
7 g( u( V* {0 c$ h" n
9 t) l- N" F2 i Nu_WIO_01.PNG " j, \6 G+ g. R9 M
3、运行模拟$ ^1 [9 q# k7 h6 l5 O5 o% O
上电后,摄像头捕捉图像,并显示在LCD屏上,当图片是空白,或者没有发现人的时候,显示No-person,
2 @% d& F1 y. y+ b. H这里用手机摄像头遮挡面部,就显示没发现人脸,显示准确度可以达到80%,
6 \) H# _- d7 ?: I# J# |7 i+ R2 u' g8 Y/ l
Nu_WIO_05.jpg
" u- ]. ]3 S" o+ Y移开手机,露出人脸,就迅速监测到人脸,显示Person,同时计算出准确率61%。
& l7 }  i: m; N' W' M' q9 [& _; X( w" ^/ ]
Nu_WIO_06.jpg
1 F& a+ r+ p% D6 `这样快速监测成功。
1 o4 ^1 n4 [& V8 d, k4、人工智能实现的分析/ h5 Q2 s+ [1 ^4 S0 O! C
4.1 硬件平台的能力) j9 ?% \1 s+ \. k4 ~4 x* U
WIO LiteAI采用的是STM32H725工作频率高达550 MHz的Arm® Cortex®-M7内核(具有双精度浮点单元),可选扩展室温范围最高为125 °C (*),只有一个内核,仍然展现强大的计算能力,可以无延迟实现图像处理和人脸识别。在图形上采用的高性能的支持,具有以下两个图形实现和加速功能,
/ ^: q% C; {* W, U$ P
  • LCD-TFT控制器接口支持双层图形
  • Chrom-ART Accelerator™提高了图形内容创建速度,并为其它应用节省了MCU内核处理带宽
    / A& }: j' \7 h5 w: ~! y* J

# A- i- \3 j, N: Q0 ]8 x; E% B% V! T; m- v
4.2 人脸识别的流程和库的支持7 K: c5 h1 E6 m* k
CubeAI的人脸识别是用如下层次实现
7 o) T. i5 ^4 P& Q Nu_WIO_07.png , @2 e# d1 M+ Z4 t; y
在底层硬件上,实现板级支持,更上一层是STM32的人脸识别模型,实现具体的应用,实现过程的数据流程如下
  h' ~; a: [  }5 k6 a FaceReco_Dataflow.png
/ i- G! {) D+ }% z' L$ y, X9 n. `数据依次在上述流程中逐级计算,根据人工智能模型实现人脸的识别精度计算,当大于计算值以后就迅速提出结果并显示出来
  d8 q0 H4 w- u9 d- u# N4.3 程序代码分析2 i/ t3 {6 [4 V8 a) H
首先定义图形数据的交换空间,是一个320x240的采样空间4 K! Y2 P' }; m# X' @8 D4 `6 |
  1. static Frame_TypeDef frame ={ .buffer = buffer,! U6 }( a- ~' I
  2.                                                           .length = 320 * 240 * 2,; P# ^" I- W, {6 `
  3.                                                           .width  = 320,
    # O) v# \9 e: m) Q# B+ b
  4.                                                           .height = 240
    $ _! B2 A( b& r3 Z$ v/ a
  5.                                                         };
复制代码
主程序代码非常精简' }0 T$ f" W$ @$ Q2 ~6 e& j9 V
  1. & L  b% W( h( E2 ]2 |7 Z
  2. int main(void)
    / S+ n8 U6 [; U: X2 z
  3. {8 e( R+ S/ x3 K# }/ d4 i% d
  4.   MPU_Config();4 }6 ?( O9 l, s. B4 `( G- ~
  5.   SCB_EnableICache();3 U. w# ?( i' u9 X# ?+ b' ]
  6.   SCB_EnableDCache();$ c/ V9 N6 v' O9 B. [3 t8 J) [
  7.   HAL_Init();
    ) b3 s% U* E' ~: D4 I
  8.   SystemClock_Config();  P. ^5 e% d/ M/ [2 z9 j4 w; C( V: I
  9. " I: ?% K" {; |# P/ g( O
  10.   /* Initialize all configured peripherals */
    1 v& `; e) Y8 y! C3 X& d
  11.   MX_GPIO_Init();
    , v' `0 r1 V0 z. D5 Z2 J% N
  12.   MX_USART3_UART_Init();$ z! K" J% e8 G- {; ]+ P% ?
  13.   MX_LTDC_Init();
    ) J% }% x1 x8 r* `0 S& k5 q
  14.   MX_I2C4_Init();" ^3 ]- ]6 }5 O6 s' R
  15.   MX_DMA_Init();0 }$ t$ F/ H: x8 B4 T  ^
  16.   MX_DCMI_Init();
    ' d( b. H- i( I- S4 N: W0 O( @6 C
  17.   MX_TIM2_Init();
    ) W! X! l5 c: I5 q2 x
  18.   MX_OCTOSPI1_Init();
    9 Q- X$ w2 Z) p2 b
  19.   MX_CRC_Init();
    + }" Y& U' [5 w. S" S& b) g0 \
  20.         LOG("here");
    3 `# n( E& T/ b" M5 R
  21.         Psram_Init();+ ?) u  a. |6 w

  22. 5 n* r. D( X7 ~% y
  23.         /*OV2640 Init*/
    9 }! O/ l7 I8 ]$ ]0 y
  24.         HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); //XCLK, O9 T- m) q4 s8 x8 k* y
  25.         OV2640_Init(&OV2640);
    1 \* ~# f# }. H8 Q0 j! {
  26.         OV2640_ReadID(&(OV2640.ID));
    + M- x' A  d' G* t, B
  27.         LOG("ID: %02X %02X \r\n", OV2640.ID.PIDH, OV2640.ID.PIDL);; |% ?8 q8 [8 N$ U4 l2 b
  28.         OV2640_UXGAConfig();        //flip after all the camera setting ,or camera setting  will change REG04 value.
    # |$ G, }; a% h9 |6 L& ~
  29.         OV2640_Flip();
    , [* n! Y1 l. a' x" v! q
  30.         OV2640_Start();        //initial IPL and AI
    - \! K; P' ?% a1 y% ^
  31.         STM32Ipl_InitLib(buffer_ipl, IPL_BUFFER_SIZE);+ |, }# C% t1 U
  32.         /* The STM32 CRC IP clock should be enabled to use the network runtime library */
    ' p2 v6 z$ {9 U( S& q! Y- F
  33.         __HAL_RCC_CRC_CLK_ENABLE();
    & Y# m; ]6 `) \+ q7 x! d
  34.         aiInit();
    * }! R& p. ~2 D5 U
  35.         frame_rgb565.data = frame.buffer;  k8 b$ U; [8 ], ^
  36. 1 `5 O4 g7 ]0 L- r1 y  @) _
  37.         while (1)
      b. `# ]9 m& l% E
  38.         {
    # h# y) [8 ]0 y) a; @* v
  39.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    5 V1 q' f1 M9 |% |- L
  40.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET);0 C- r" r8 f) c6 E
  41. 9 }" H+ y9 p! ?1 k8 {7 ^
  42.                   // rgb565 320*240*2 to grayscale 320*240
    % B2 Y# j( A+ {, t+ e
  43.                   if (STM32Ipl_Convert(&frame_rgb565, &frame_rgb565_grayscale) != stm32ipl_err_Ok) {* w# F( [) T2 |$ m0 S7 F& a
  44.                           while(1);
      ], x' I$ D$ x6 \9 n; M$ [
  45.                   }4 p5 c) u3 j% Q% z% R) l8 e$ S. I0 u
  46.                   // grayscale 320*240 to grayscale 96x96x23 J% T# K/ M: b! e. N
  47.                   if (STM32Ipl_Resize(&frame_rgb565_grayscale, &frame_grayscale_resized, &roi) != stm32ipl_err_Ok) {/ r  Q8 G: S+ i, f6 g. x/ G$ K& n% @
  48.                           while(1);+ Y9 ~4 L7 y9 X8 L; A/ J9 }2 U
  49.                   }: j4 D* K) i. A% I" v  X/ J9 D
  50. 6 j$ r4 p8 t  N$ l3 D" A
  51.                   //AI
    6 M0 w5 v0 ~) Y/ S; U; d) u
  52.                   aiRun(buffer_grayscale_resized, network_output);% H2 M; j. Z" @3 r
  53.                   postprocess(network_output);& |% o# i) [/ G. {2 j5 }

  54. & d- S. |. }6 W5 }" a  z0 e/ L
  55.                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    2 w* E0 U3 i) {/ a3 p
  56.                   HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET);
    , z8 J- o0 ]4 L, v% ~" c
  57. & K0 e$ h- h' t# s* o: Y5 E
  58.         }
    - u: L# N! |; v9 d1 I
  59. }
    ' B  ^) ?  [) K8 X% f3 w
复制代码
在启动硬件初始化之后,就进入识别循环,当识别出人脸就直接把对应的LED点亮,
7 `1 S* S! ~0 ~4 _) _实现人脸识别的函数是aiRun,对图形交换空间的数据分析,并直接输出神经网络计算的结果  {( e* J; m" v# h" ]5 w9 A
; C! `4 j* {7 {( M
  1. aiRun(buffer_grayscale_resized, network_output);5 _' L* E* ~! ]( w8 b  \' C6 s+ Q7 `
  2. postprocess(network_output);
复制代码
这个函数是在"ai_inference.h"文件中实现的,( k* t/ [1 @5 O. z
  1. void aiRun(ai_u8 *pIn, ai_u8 *pOut)! t' Z& }1 y( {4 p
  2. {8 t8 y: P" R' s5 M7 e" n3 b
  3.   ai_i32 batch;
    5 S" k5 \% F4 F1 k* K, A1 N3 j
  4.   ai_error err;$ N, t' ~4 c8 f$ ^
  5. & {+ `+ h2 M. I# ?
  6.   /* 1 - Create the AI buffer IO handlers with the default definition *// \6 m4 U3 X5 m# Z1 s3 f, h
  7.   ai_buffer ai_input[AI_NETWORK_IN_NUM] = AI_NETWORK_IN;, V0 g5 a! O4 W) t- x4 n
  8.   ai_buffer ai_output[AI_NETWORK_OUT_NUM] = AI_NETWORK_OUT;
    $ Z- @, o/ T* V
  9. & [9 |# X! y8 w0 K  J* Z
  10.   /* 2 - Update IO handlers with the data payload */! E1 S3 r! |  [3 o4 _
  11.   ai_input[0].n_batches = 1;& j% t% q# [- u$ v) a( ?% w1 @
  12.   ai_input[0].data = AI_HANDLE_PTR(pIn);5 w# `7 [$ r. ?! y) @* N
  13.   ai_output[0].n_batches = 1;& q! }+ p( g5 F% C  k" q7 C! u4 a
  14.   ai_output[0].data = AI_HANDLE_PTR(pOut);2 p  f6 X. Z( D, r7 w  j

  15. ' ^+ M5 z7 w6 l6 B$ |/ k
  16.   batch = ai_network_run(network, ai_input, ai_output);; C8 @1 F/ S  H6 ^  ^
  17.   if (batch != 1) {
    4 V( a$ B. o: P7 G
  18.     err = ai_network_get_error(network);
    " J& U# {! A$ V. N. P( R, \' d. d
  19.     printf("AI ai_network_run error - type=%d code=%d\r\n", err.type, err.code);. q2 G3 v4 O8 `$ C# K
  20.     Error_Handler();" O: q, E. k0 |2 z+ v
  21.   }, [5 B0 U, g/ E7 y9 h- c2 j
  22. }
    + h3 c# I" H6 r) l/ j* c
复制代码
上述过程就是流程图数据流实现的过程,读取经过预处理的图像数据,然后再ai网络中计算,输出计算结果,
8 @: e! @) v. O$ w% h) K
  1. ai_i32 ai_network_run(
    # S. j* v) H* f3 Z$ C
  2.   ai_handle network, const ai_buffer* input, ai_buffer* output)
    4 G0 s1 j( B3 S( [% K% j
  3. {+ C, g# E& f3 L8 `, o
  4.   return ai_platform_network_process(network, input, output);- h" o; c( [( p  R# @+ }
  5. }
复制代码
上述处理,需要计算网络,这个是再ai_model中定义的,然后读取输入数据,形成输出数据。( x* T6 K$ B" `2 s
# B+ b+ f8 a- N; V
5 小结
: K3 _, G" ^3 `7 ?, S8 q9 ^3 Z    基于STM的cubeAI,通常已经提供了一个快速部署的流程框架。对于开发者,只需要自定义人工智能模型,然后导入到新建的工程中,按照提供的API逐步实现数据流程,就能够在项目中嵌入人工智能的功能。9 l7 F: ~6 g- o! U9 v7 P
  在上一个文件中提高的,对应模型的生产,采用CubeAI中的命令行指令,stm32ai就可以完整实现。这个CubeAI极其配套工具,就是一个完整实现人工智能嵌入的工具,虽然安装和使用流程比较多,但是能够实现这样的效果还是非常理想的,在硬件性能和软件功能,达到完美的结合。
  c$ N+ G6 B& {& M) f
5 k& v) A* n/ q: y7 A3 P
3 h4 \% \( X/ p5 M& r2 I1 ]
2 _1 `, ^4 N9 H: j
3 T! v  ?% i1 {$ f5 |, @' ~( y! ~( J, m) S+ N; X* e  T

) ?7 ?  Z' d2 l1 Y$ \# R
/ t. v5 r; \2 r: G. L+ D4 X& }9 ~9 w) q+ n

0 b% J3 P% V/ o6 u: }& A
% A$ Y$ d, ^0 e& U. t, |
收藏 评论7 发布时间:2022-10-17 10:57

举报

7个回答
小样爱捣鼓 回答时间:2022-10-17 19:17:31
这么好的板子不自己训练个模型尝试部署上去就有点浪费了
/ Y* m7 w6 c" o8 _7 _
晒太阳的懒猫 回答时间:2022-11-11 09:35:57
照着评测内容,一步一步学习,让自己更快地获取AI视觉开发的知识,谢谢楼主!8 W% [1 r" \3 q+ h& U( N
LN 回答时间:2022-11-16 15:26:25
人脸识别算法,可以直接搞个现成的吗?重新训练是不是很复杂
LN 回答时间:2022-11-16 15:29:29
签到
# w1 F) B+ V. P' ]3 y
+ g. f! q! C5 r8 O8 K7 k
stm32_AI2.jpg
stm32_AI.jpg
党国特派员 回答时间:2022-12-22 16:45:47
这个网络模型是什么模型?
- h1 d# i/ ]# |# b. H' h* ^) q# Y8 ?0 p
萨法 回答时间: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 手机版