整体概述

本项目采用两个舵机构成的二自由度的电动云台作为执行机构,控制摄像头在水平和垂直方向的运动。舵机带动摄像头进行二维平面的运动的同时,摄像头进行实时人脸检测,一旦检测到人脸,则进行人脸跟踪。

摄像头采用星瞳openMV H7,主控采用的是正点原子探索者F407开发板。

本文通过openMV和STM32两方面来讲解。

openMV部分

OpenMV摄像头是一款小巧,低功耗,低成本的电路板,它帮助你很轻松的完成机器视觉(machine vision)应用。其使用的是STM32F765VI ARM Cortex M7 处理器,所以其实我们编写openMV的代码从某种程度上来说其实还是往STM32里写代码,唯一不同的是,openMV这部分代码我们要用microPython来写。

在openMV上我们要做的很简单,如果摄像头识别到人脸,用矩形框将人脸框起来,通过串口把矩形框的中心坐标返回到开发板,开发读取坐标后控制舵机执行相应的运动。

所以首先,人脸追踪的基础是摄像头能够进行人脸检测。而openMV已经集成封装好了很多能够调用的库,其中正好就包含人脸检测相关的库和方法,只管调用就是了。(同时,openMV内置了n多个example,我们可以在example的基础上对代码进行修改。本例就是在face_detection的基础上修改实现的。)

模板例程这里就不赘述了,注释都写得很清楚,不了解的可以去看看官方的教程。这里主要讲一下人脸追踪的部分。

其中,我们要知道find_features方法返回一个关于这些特征的边界框矩形元组(x,y,w,h)的列表,若未发现任何特征,则返回一个空白列表。x,y是矩形框左上角的坐标值,w,h分别为矩形框的宽度和高度。那么很容易得到中心坐标(cx = x + w / 2, cy = y + h / 2)

接下来的任务就是将这两个数据通过串口传输到开发板。我们在串口上写了个简单的协议,规定发送数据的格式为:‘X’ + cx + ‘Y’ + cy + ‘OK’(后面讲STM32部分的时候会提到),于是我们这里向串口发送的数据为(‘X%dY%dOK\r\n’ % (cx,cy)),到了STM32部分我们会对接收到的数据进行分析然后把有效数据cx和cy从中提取出来。

具体代码如下:

import sensor, time, image
from pyb import UART# Reset sensor
sensor.reset()# Sensor settings
sensor.set_contrast(1)
sensor.set_gainceiling(16)
# HQVGA and GRAYSCALE are the best for face tracking.
sensor.set_framesize(sensor.HQVGA)
sensor.set_pixformat(sensor.GRAYSCALE)# Load Haar Cascade
face_cascade = image.HaarCascade("frontalface", stages=25)# OpenMV上P4,P5对应的串口3
uart = UART(3, 115200, timeout_char=1000)# FPS clock
clock = time.clock()while (True):clock.tick()# Capture snapshotimg = sensor.snapshot()# Find objects.objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25)#find_features函数返回一个关于要找的这些feature的边界框矩形元组(x,y,w,h)的列表。#若未发现任何要找的feature,则返回一个空白列表,即objects是一个元组列表,包含(x,y,w,h)这个元组作为唯一一个元素# Draw objectsfor r in objects:if(r):img.draw_rectangle(r,color = (255,0,0))cx = r[0]+r[2]/2                                            #计算得到人脸矩形框的中心x坐标cy = r[1]+r[3]/2                                            #计算得到人脸矩形框的中心y坐标print('x:%d, y:%d, w:%d, h:%d' % (r[0],r[1],r[2],r[3]) )    #打印矩形框的x,y,w,hprint('cx = %d, cy = %d' % (cx,cy))uart.write('X%dY%dOK\r\n' % (cx,cy))breakelse:#print('cannot find any face!')uart.write('X-1Y-1OK\r\n')

STM32部分

舵机部分

扫描函数:用两层循环分别控制x方向和y方向的舵机运动,即可实现摄像头的二维运动。一旦识别到人脸,退出扫描函数,进入跟随函数,让摄像头跟随人脸运动,使人脸一直处于画面正中心。

跟随函数:如果识别到人脸,获取人脸在屏幕中的位置,当其距离屏幕正中心超过一定的阈值时,调节相应的舵机,使之向屏幕中心靠拢。如果未识别到人脸,则继续从当前位置开始执行扫描函数。

串口部分

上文提到,openMV捕获到人脸后,不断通过串口向STM32发送数据,所以我们串口函数的目的就是把接收到的数据中的cx和cy提取出来(其余数据丢弃不用),然后把cx和cy和舵机的运动函数联系起来,进而控制摄像头云台执行相应运动实现人脸追踪。

串口的配置过于简单,这里就略过不讲了,主要还是讲解一下如何解析从openMV接收到的格式为’X’ + cx + ‘Y’ + cy + 'OK’的数据并从中提取有效信息cx和xy。

我们提取数据的代码将在正点原子的串口中断函数的基础上进行更改,可以先在我的上一篇博文了解到正点原子串口中断函数的思路:基于STM32F407的串口通信


通过正点原子的例子,我们知道如果我们的数据如果是以‘OK’结尾,会被串口认为有效数据接收,且‘OK’不会作为数据内容存入buffer数组中。

于是,‘X’ + cx + ‘Y’ + cy + 'OK’格式的数据(e.g. X17Y41OK)被STM32的串口有效接收后存放到buffer数组里的数据是X17Y41,那么我们只要通过遍历把XY之间的cx提取出来,把Y之后的cy提取出来,分别存放在两个数组里,就实现了cx和cy的提取。

(如果STM32部分的代码(如舵机控制)也干脆在openMV上写,那么提取数据用Python的正则表达式之类的应该很轻松能做到。不过当然,如果舵机控制部分在openMV上写,那也不会有串口通信和这些带格式的数据了,毕竟数据不需要通过串口从两个设备之间传输了。当然这是后话了,以后尝试只用openMV实现)

显然,我们是在数据接收完成后(即USART_RX_STA&0x8000==1)进行的进一步操作,于是我们在if((USART_RX_STA&0x8000)==0)后紧跟else if语句,条件为(USART_RX_STA&0x8000),表明接收完成,开始分析数据。

思路前面已经大致提到了,我们先建立两个buffer数组分别用于存放cx和cy的数据。然后按字节遍历整个接收数据,当识别到当前字节的数据为‘X’时,将之后出现的数据存放到cx数组中,当识别到当前字节的数据为‘Y’时,将之后出现的数据存放到cy数组中。最后,由于串口接收到的是char型数据,我们再通过atoi()函数将char型转化成int型的数据即可。

以上就是人脸追踪的大致思路了,写得有点复杂,其实代码还可以较大程度的优化,以后有时间再改了。

具体代码见:完整代码

基于STM32F407的人脸追踪相关推荐

  1. 基于 OpenCV 的人脸追踪

    作者 | 努比 来源 | 小白学视觉 在Raspberry上启动项目很简单,所以让我们开始吧. 01. 产品清单 Raspberry Pi 4 Model B - 4GB 适用于Raspberry P ...

  2. 一种基于人脸追踪和特征分析的疲劳驾驶预警平台

    目录 整体描述 1. 嵌入式端: 2.程序端: 3. 辅助功能: 4. 项目整体工作流程 5. 不足之处 效果演示 程序源码 算法篇 基于AdaBoost级联分类器的人脸/眼睛位置检测算法 基于特征脸 ...

  3. 【V1.0】基于树莓派的OpenCV-Python摄像头人脸追踪系统

    [V1.0]基于树莓派OpenCV的摄像头人脸追踪系统 该系统目前结合了树莓派+51单片机 树莓派主要用于运行Python程序 追踪人脸 同时用GPIO口给出信号 单片机用于控制42步进电机导轨左右移 ...

  4. perclos嘴巴_基于人脸追踪和特征分析的疲劳驾驶预警系统设计

    齐伟 张来刚 刘朝阳 摘 要:本文通过对人脸追踪和疲劳特征分析的研究设计了一个疲劳驾驶预警系统,通过特征人脸识别器来进行驾驶人身份的验证;通过坐标解算来获取驾驶人的头部姿态.电脑端将驾驶人的眨眼频率. ...

  5. 基于PID的树莓派控制二自由度舵机人脸追踪云台设计

    人脸追踪云台的设计 一.舵机控制概述 脉冲宽度与舵机转角: 在脉冲信号频率50Hz的条件下输入的脉冲信号宽度和舵机转角的对应关系图以如图1.所示,该转角的计算公式如下.树莓派端通过占空比信号对舵机进行 ...

  6. 【计算机视觉】基于OpenCV的人脸识别

    一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenCV 已被广泛运用在各种项目上,从 ...

  7. OpenCV-Python实战(16)——人脸追踪详解

    OpenCV-Python实战(16)--人脸追踪详解 0. 前言 1. 人脸追踪技术简介 2. 使用基于 dlib DCF 的跟踪器进行人脸跟踪 2.1 完整代码 3. 使用基于 dlib DCF ...

  8. Python人工智能实例 │ 使用Haar级联进行人脸检测、使用CAMShift算法、光流法进行人脸追踪

    使用Haar级联进行人脸检测 使用CAMShift算法进行人脸追踪 使用光流法进行人脸追踪 01.背景知识 1.1●Haar级联简介 Haar级联是基于Haar特征的级联分类器.那么级联分类器是什么? ...

  9. 基于 PCA 的人脸识别系统及人脸姿态分析

    文章目录 1 PCA 1.1 原理 1.2 算法流程 1.2.1 零均值化 1.2.2 计算协方差矩阵 1.2.3 特征值和特征向量 1.2.4 降维得到 K 维特征 1.2.5 PCA 的优缺点 2 ...

最新文章

  1. 打发无聊的办法(2005-5-31)
  2. mysql 7.4_CentOS 7.4 64位/ mysql
  3. redis 一主二从
  4. mysql 线上加索引_mysql手札,唯一索引引发的线上事故
  5. 三分钟掌握数据中心“容灾和备份的区别”
  6. 技术系统进化法则是_()是技术系统所有进化法则的基础。
  7. kalixfce不能启动_kali升级2019.4后切换xfce桌面
  8. 自定义SpringBoot start 被依赖时 程序包不存在的问题
  9. Buildroot构建指南--Overview
  10. E20171214-sl
  11. snapchat注册不到_从Snapchat获得开发人员职位中学到的经验教训
  12. LeetCode 1430. 判断给定的序列是否是二叉树从根到叶的路径(递归)
  13. python参考文献_[zotero/python]库中参考文献条目删除后,清除残留PDF的脚本
  14. 这两年亚马逊创业都是一个非常火热的话题
  15. 宋宝华Linux培训笔记-Linux系统开发与工具
  16. C语言if else语句详解
  17. 分享爬取链家地图找房房价数据的小爬虫
  18. 无需格式化 移动硬盘/U盘上装WinPE、Win7PE图解
  19. 肌肤食品揭秘淘宝骗子经典伎俩
  20. Unity GL画线的坑

热门文章

  1. 电脑增加机械硬盘计算机管理,电脑新增加一块硬盘安装并使用的教程
  2. 微信小程序加载并且编译显示富文本编辑器内容
  3. excel怎么启用宏_轻便免费的Excel合并工具,支持wps和office全系统
  4. 书单收藏 | 17本中信版畅销书从科普、商业到技术带你轻松理解区块链
  5. 超文本标记语言--Html
  6. HMACSHA1 加密算法
  7. 悲痛!长安福特AE工程师之死:985高校吉大毕业,入职8年,年仅30岁抑郁跳楼身亡...
  8. 让别人关机!(VB语言)
  9. 企业邮箱注册申请入口,公司邮箱申请哪个好?
  10. 21北邮计算机专硕与学硕科目,【21考研】研考必知!对考英语、数学、专硕、学硕、专科考研都有用!...