OpenMV(五)--STM32实现人脸识别_stm32人脸识别-程序员宅基地

技术标签: •OpenMV  stm32  •嵌入式AI  嵌入式硬件  单片机  

OpenMV(一)–基础介绍与硬件架构
OpenMV(二)–IDE安装与固件下载
OpenMV(三)–实时获取摄像头图片
OpenMV(四)–STM32实现特征检测

前言

本专栏基于以STM32H743为MCU的OpenMV-H7基板,结合OV7725卷帘快门摄像头进行相关机器视觉应用的开发。人脸识别的前提是人脸检测,本篇博文基于OpenMV官方的Face-Detection例程,来解析一下怎么实现人脸识别。

1. 人脸检测

人脸检测就是通过摄像头实时获取的图片,来标记出人脸的位置。本节代码的目的就是将摄像头拍摄的画面中的人脸用矩形框表示出来。人脸检测的本质是特征识别,OpenMV中已经集成了非常多的特征库和算法库,比如image模块下的find_features()特征寻找函数。

1.1 构造函数
  • image.find_features(cascade, threshold=0.5, scale=1.5, roi)
    搜索和Haar Cascade匹配的所有区域的图像,并返回一个关于这些特征的边界框矩形元祖(x, ,y, w, h)的列表,若没有发现任何特征,则返回一个空白列表。基于Haar特征的cascade分类器一种有效的物品检测(object detect)方法。它是一种机器学习方法,通过许多正负样例中训练得到cascade方程,然后将其应用于其他图片。详细内容可以参考博客:使用Haar Cascade 进行人脸识别
    • cascade:Haar Cascade 对象
    • threshold: 是浮点数(0.0-1.0),其中较小的值在提高检测速率同时增加误报率。相反,较高的值会降低检测速率,同时降低误报率。
    • scale: 是一个必须大于1.0的浮点数。较高的比例因子运行更快,但是其图像匹配相应较差。理想值介于1.35到1.5之间。
    • roi:指定识别区域的矩形元组(x, y, w, h)。如果没有指定,roi即整个图像的图像矩形。
1.2 源码分析
"""
人脸检测例程
利用Haar Cascade特征检测器来实现:一个Haar Cascade是一系列简单区域的对比检查,人脸识别有25个阶段,每个阶段有几百次检测。Haar Cascade运行很快是因为它是逐个阶段进行检测的。
OpenMV使用一种称为积分图像的数据结构来在恒定时间内快速执行每个区域的对比度检查
"""
# 导入相应的库
import sensor, image, time

# 初始化摄像头
sensor.reset()

# 设置相机图像的对比度为1
sensor.set_contrast(1)

# 设置相机的增益上限为16
sensor.set_gainceiling(16)

# 设置采集到照片的大小
sensor.set_framesize(sensor.HQVGA)

# 设置采集到照片的格式:灰色图像
sensor.set_pixformat(sensor.GRAYSCALE)

# 加载Haar Cascade 模型
# 默认使用25个步骤,减少步骤会加快速度但会影响识别成功率
face_cascade = image.HaarCascade("frontalface", stage = 25)
print(face_cascade)

# 创建一个时钟来计算摄像头每秒采集的帧数FPS
clock = time.clock()

while(True):
	# 更新FPS时钟
	clock.tick()
	
	# 拍摄图片并返回img
	img = sensor.snapshot()

	# 寻找人脸对象
	# threshold和scale_factor两个参数控制着识别的速度和准确性
	objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25)

	# 用矩形将人脸画出来
	for r in objects:
		img.draw_rectangle(r)
	
	# 串口打印FPS参数
	print(clock.fps())

我们将板子连接到OpenMV IDE, 新建文件,并将上述代码copy进去,点击左下角的绿色按钮,我们就可以看到IDE右边的窗口在实时显示提取到的人脸特征图片:
在这里插入图片描述

2. 人脸识别

人脸识别是通过短时间的人脸特征学习,再重新识别的过程,这节内容是基于第一小节的人脸检测的基础上完成的。

2.1 构造函数

本节是人脸检测和特征点识别的结合,实验用到的函数和对象在之前都有介绍过,分别是

  • image.find_features(cascade, threshold=0.5, scale=1.5, roi)
    收获和Haar Cascade 匹配的所有区域的对象,并返回关于这个特征的边界框矩形元组
  • image.find_keypoints(roi, threshold=20, normalize=False, scale_factor=1.5, max_keypoints=100, corner_detector=image.CORNER_AGAST)
    特征点识别函数,返回一个image.rect矩形对象列表
  • image.match_descriptor(descriptor0, descriptor1, threshold=70, filter_outliers=False)
    特征点对比函数。
2.2 源码分析

对于人脸识别,具体的实现步骤如下:
初始化和配置相应模块–>加载人脸检测Haar Cascade模型–>对当前的人脸学习并记录特征点K1–>在采集的图像中提取特征点K2–>对比K1和K2是否一致–>如果一致就在图中用矩形画出相应位置

"""
人脸识别例程
第一步先使用Haar Cascade找出人脸并记录该关键点
第二步就是不停的检测当前获取图片的关键点是否匹配
"""
# 导入相应的库
import sensor, image, time

# 初始化摄像头
sensor.reset()

# 设置相机图像的对比度为3
sensor.set_contrast(3)

# 设置相机的增益上限为16
sensor.set_gainceiling(16)

# 设置采集到照片的大小
sensor.set_framesize(sensor.VGA)

# 在VGA(640*480)下开个小窗口,相当于数码缩放
sensor.set_windowing((320, 240))

# 设置采集到照片的格式:灰色图像
sensor.set_pixformat(sensor.GRAYSCALE)

# 加载Haar Cascade 模型
# 默认使用25个步骤,减少步骤会加快速度但会影响识别成功率
face_cascade = image.HaarCascade("frontalface", stage = 25)
print(face_cascade)

# 初始化特征kpts1
kpts1 = None

# 找到人脸
while(kpts1 == None):
	# 拍摄图片并返回img
	img = sensor.snapshot()
	img.draw_string(0, 0, "Looking for a face...")

	# 寻找人脸对象
	# threshold和scale_factor两个参数控制着识别的速度和准确性
	objects = img.find_features(face_cascade, threshold=0.5, scale_factor=1.25)
	
	if objects:
		# 将 ROI(x, y, w, h)往各个方向扩展31像素
		face = (objects[0][0]-31,
				objects[0][1]-31,
				objects[0][2]+31*2,
				objects[0][3]+31*2)
		# 使用扩展后的ROI区域(人脸)学习关键点
		kpts1 = img.find_keypoints(threshold = 10,
								   scale_factor = 1.1,
								   max_keypoints = 100,
								   roi = face)
		img.draw_keypoints(kpts1, size=24)
		img = sensor.snapshot()
		time.sleep(2000)

while(True):
	img = sensor.snapshot()
	# 从图像中提取关键点
	kpts2 = img.find_keypoints(threshold = 10,
							   scale_factor = 1.1,
							   max_keypoints = 100,
							   normalized = True)
	if(kpts2):
		# 跟kpts1匹配
		c = image.match_descriptor(kpts1, kpts2, threshold = 85)
		# c[6]为match值,值越大表示匹配程度越高
		match = c[6]
		if(match > 5):
			img.draw_rectangle(c[2:6])
			img.draw_cross(c[0], c[1], size = 10)

我们将板子连接到OpenMV IDE, 新建文件,并将上述代码copy进去,点击左下角的绿色按钮,我们就可以看到IDE右边的窗口在首先学习了人脸特征:
在这里插入图片描述
然后我们换一张还是吴彦祖的人脸看看是否能够进行识别:
在这里插入图片描述
从图中可以发现,已经成功识别了这张人脸特征。

3.通过本地特征文件进行人脸识别

第2节的例程是在线学习特征然后进行人脸识别,但是绝大多数的应用场景需要我们对比本地的人脸特征库和目标图像。我们要做的步骤有两部,首先要将人脸特征保存到本地,其次是调用本地的特征来进行人脸识别,下面我们将通过实例来分析如果实现这两个步骤。

3.1 将人脸特征保存到本地

将人脸特征保存到本地只需要一句语句即可:

 image.save_descriptor(kpts, "path")

其中kpts为要保存的特征点,path为保存路径。
源码如下:

"""
保存人脸特征例程
第一步先使用Haar Cascade识别出人脸,并获取人脸的特征
第二步就是将特征保存在本地文件中
"""
# 导入相应的库
import sensor, image, time

# 初始化摄像头
sensor.reset()

# 设置相机图像的对比度为3
sensor.set_contrast(3)

# 设置相机的增益上限为16
sensor.set_gainceiling(16)

# 设置采集到照片的大小
sensor.set_framesize(sensor.VGA)

# 在VGA(640*480)下开个小窗口,相当于数码缩放
sensor.set_windowing((320, 240))

# 设置采集到照片的格式:灰色图像
sensor.set_pixformat(sensor.GRAYSCALE)

sensor.skip_frames(time = 3000)     # Wait for settings take effect.

# 加载Haar Cascade 模型
# 默认使用25个步骤,减少步骤会加快速度但会影响识别成功率
face_cascade = image.HaarCascade("frontalface", stage = 25)

# 初始化特征kpts1
kpts1 = None

# 文件名
FILE_NAME = "kpts1"
# 找到人脸
while(kpts1 == None):
    # 拍摄图片并返回img
    img = sensor.snapshot()
    img.draw_string(0, 0, "Looking for a face...")

    # 寻找人脸对象
    # threshold和scale_factor两个参数控制着识别的速度和准确性
    objects = img.find_features(face_cascade, threshold=0.5, scale_factor=1.25)

    if objects:
        # 将 ROI(x, y, w, h)往各个方向扩展31像素
        face = (objects[0][0]-31,
                objects[0][1]-31,
                objects[0][2]+31*2,
                objects[0][3]+31*2)
        # 使用扩展后的ROI区域(人脸)学习关键点
        kpts1 = img.find_keypoints(threshold = 10,
                                   scale_factor = 1.1,
                                   max_keypoints = 100,
                                   roi = face)
        img.draw_keypoints(kpts1, size=24)
        img = sensor.snapshot()
        #将人脸保存打本地文件
        image.save_descriptor(kpts1, "/face_feature/%s.orb"%(FILE_NAME))
3.2 通过本地特征文件进行人脸识别

提取本地特征文件只需要一句语句即可:

 kpts1 = image.load_descriptor("path")

其中kpts1为要本地文件中的特征,path为保存路径。
源码如下:

"""
加载本地特征文件进行人脸识别例程
第一步先从本地加载特征文件
第二步就是不停的检测当前获取图片的关键点判断是否和本地特征匹配
"""
# 导入相应的库
import sensor, image, time

# 初始化摄像头
sensor.reset()

# 设置相机图像的对比度为3
sensor.set_contrast(3)

# 设置相机的增益上限为16
sensor.set_gainceiling(16)

# 设置采集到照片的大小
sensor.set_framesize(sensor.VGA)

# 在VGA(640*480)下开个小窗口,相当于数码缩放
sensor.set_windowing((320, 240))

# 设置采集到照片的格式:灰色图像
sensor.set_pixformat(sensor.GRAYSCALE)

sensor.skip_frames(time = 10000)     # Wait for settings take effect.

# 加载Haar Cascade 模型
# 默认使用25个步骤,减少步骤会加快速度但会影响识别成功率
face_cascade = image.HaarCascade("frontalface", stage = 25)
print(face_cascade)

# 从本地提取特征
kpts1 = image.load_descriptor("/face_feature/kpts1.orb")

while(True):
    img = sensor.snapshot()
    # 从图像中提取关键点
    kpts2 = img.find_keypoints(threshold = 10,
                               scale_factor = 1.1,
                               max_keypoints = 100,
                               normalized = True)
    if(kpts2):
        # 跟kpts1匹配
        c = image.match_descriptor(kpts1, kpts2, threshold = 85)
        # c[6]为match值,值越大表示匹配程度越高
        match = c[6]
        if(match > 10):
            img.draw_rectangle(c[2:6])
            img.draw_cross(c[0], c[1], color = (255,0,0), size = 10)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42580947/article/details/105861162

智能推荐

leetcode 172. 阶乘后的零-程序员宅基地

文章浏览阅读63次。题目给定一个整数 n,返回 n! 结果尾数中零的数量。解题思路每个0都是由2 * 5得来的,相当于要求n!分解成质因子后2 * 5的数目,由于n中2的数目肯定是要大于5的数目,所以我们只需要求出n!中5的数目。C++代码class Solution {public: int trailingZeroes(int n) { ...

Day15-【Java SE进阶】IO流(一):File、IO流概述、File文件对象的创建、字节输入输出流FileInputStream FileoutputStream、释放资源。_outputstream释放-程序员宅基地

文章浏览阅读992次,点赞27次,收藏15次。UTF-8是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节。文件字节输入流:每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1。注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码。定义一个与文件一样大的字节数组,一次性读取完文件的全部字节。UTF-8字符集:汉字占3个字节,英文、数字占1个字节。GBK字符集:汉字占2个字节,英文、数字占1个字节。GBK规定:汉字的第一个字节的第一位必须是1。_outputstream释放

jeecgboot重新登录_jeecg 登录自动退出-程序员宅基地

文章浏览阅读1.8k次,点赞3次,收藏3次。解决jeecgboot每次登录进去都会弹出请重新登录问题,在utils文件下找到request.js文件注释这段代码即可_jeecg 登录自动退出

数据中心供配电系统负荷计算实例分析-程序员宅基地

文章浏览阅读3.4k次。我国目前普遍采用需要系数法和二项式系数法确定用电设备的负荷,其中需要系数法是国际上普遍采用的确定计算负荷的方法,最为简便;而二项式系数法在确定设备台数较少且各台设备容量差..._数据中心用电负荷统计变压器

HTML5期末大作业:网页制作代码 网站设计——人电影网站(5页) HTML+CSS+JavaScript 学生DW网页设计作业成品 dreamweaver作业静态HTML网页设计模板_网页设计成品百度网盘-程序员宅基地

文章浏览阅读7k次,点赞4次,收藏46次。HTML5期末大作业:网页制作代码 网站设计——人电影网站(5页) HTML+CSS+JavaScript 学生DW网页设计作业成品 dreamweaver作业静态HTML网页设计模板常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 明星、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 军事、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他 等网页设计题目, A+水平作业_网页设计成品百度网盘

【Jailhouse 文章】Look Mum, no VM Exits_jailhouse sr-iov-程序员宅基地

文章浏览阅读392次。jailhouse 文章翻译,Look Mum, no VM Exits!_jailhouse sr-iov

随便推点

chatgpt赋能python:Python怎么删除文件中的某一行_python 删除文件特定几行-程序员宅基地

文章浏览阅读751次。本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。AI职场汇报智能办公文案写作效率提升教程 专注于AI+职场+办公方向。下图是课程的整体大纲下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具。_python 删除文件特定几行

Java过滤特殊字符的正则表达式_java正则表达式过滤特殊字符-程序员宅基地

文章浏览阅读2.1k次。【代码】Java过滤特殊字符的正则表达式。_java正则表达式过滤特殊字符

CSS中设置背景的7个属性及简写background注意点_background设置背景图片-程序员宅基地

文章浏览阅读5.7k次,点赞4次,收藏17次。css中背景的设置至关重要,也是一个难点,因为属性众多,对应的属性值也比较多,这里详细的列举了背景相关的7个属性及对应的属性值,并附上演示代码,后期要用的话,可以随时查看,那我们坐稳开车了······1: background-color 设置背景颜色2:background-image来设置背景图片- 语法:background-image:url(相对路径);-可以同时为一个元素指定背景颜色和背景图片,这样背景颜色将会作为背景图片的底色,一般情况下设置背景..._background设置背景图片

Win10 安装系统跳过创建用户,直接启用 Administrator_windows10msoobe进程-程序员宅基地

文章浏览阅读2.6k次,点赞2次,收藏8次。Win10 安装系统跳过创建用户,直接启用 Administrator_windows10msoobe进程

PyCharm2021安装教程-程序员宅基地

文章浏览阅读10w+次,点赞653次,收藏3k次。Windows安装pycharm教程新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入下载安装PyCharm1、进入官网PyCharm的下载地址:http://www.jetbrains.com/pycharm/downl_pycharm2021

《跨境电商——速卖通搜索排名规则解析与SEO技术》一一1.1 初识速卖通的搜索引擎...-程序员宅基地

文章浏览阅读835次。本节书摘来自异步社区出版社《跨境电商——速卖通搜索排名规则解析与SEO技术》一书中的第1章,第1.1节,作者: 冯晓宁,更多章节内容可以访问云栖社区“异步社区”公众号查看。1.1 初识速卖通的搜索引擎1.1.1 初识速卖通搜索作为速卖通卖家都应该知道,速卖通经常被视为“国际版的淘宝”。那么请想一下,普通消费者在淘宝网上购买商品的时候,他的行为应该..._跨境电商 速卖通搜索排名规则解析与seo技术 pdf

推荐文章

热门文章

相关标签