基于树莓派的安保巡逻机器人--(一、快速人脸录入与精准人脸识别)
目录
零、前言
一、人脸检测
二、人脸识别
1、采集人脸
2、训练人脸识别模型
3、人脸识别应用
零、前言
随着智能安防需求的增长,基于人工智能和物联网的安保系统逐渐成为趋势。树莓派因其低成本、高扩展性等特点,成为很多AI项目的理想平台。本文将为大家介绍如何使用树莓派打造一款智能安保巡逻机器人。本篇是系列的第一部分,将聚焦于“快速人脸录入与精准人脸识别”的实现步骤。
本篇文章旨在通过搭建基于树莓派的安保巡逻机器人,实现人脸录入和识别功能。巡逻机器人将通过摄像头捕捉人脸信息,进行实时识别和数据存储,以实现自动化安保监控
树莓派5B作为一款小巧、功能强大的计算机设备,为快速人脸录入和精准识别提供了一个理想的硬件平台。本文将通过详细的代码示例,讲解如何利用树莓派5B与Python实现一个高效的人脸检测和识别系统。该系统可以实时捕捉人脸信息,进行边缘检测与处理,适用于智能安防、出入控制等多种场景。
一、人脸检测
由于不同需求,首先我们先进行一下人脸检测功能
我们将利用Python的Mediapipe和OpenCV库来完成图像处理,Picamera2库驱动树莓派的摄像头。(Mediapipe库是Google开源的多媒体处理框架,适用于多种机器学习任务;而OpenCV则是一个强大的计算机视觉库,广泛应用于图像处理、模式识别等领域。)以下是主要代码片段及其实现细节。
#!/usr/bin/env python3
# encoding: utf-8import mediapipe as mp
import cv2 as cv
from picamera2 import Picamera2
为了简化人脸检测的实现,我们定义了一个FaceDetector
类。该类使用Mediapipe的人脸检测模块,并在初始化时设置最小检测置信度参数minDetectionCon
,以控制检测的灵敏度。
class FaceDetector:def __init__(self, minDetectionCon=0.5):# 初始化人脸检测模块,并设置最小检测置信度self.mpFaceDetection = mp.solutions.face_detectionself.facedetection = self.mpFaceDetection.FaceDetection(min_detection_confidence=minDetectionCon)
-
在
findFaces
方法中,首先将捕获的图像从BGR格式转换为RGB格式。这样做是因为Mediapipe库使用的是RGB格式的图像输入。随后,调用self.facedetection.process(img_RGB)
来检测人脸。def findFaces(self, frame):# 将图像从BGR转换为RGB,因为MediaPipe使用的是RGB格式img_RGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)# 处理图像,检测人脸results = self.facedetection.process(img_RGB)# 如果检测到人脸,则在图像上绘制矩形框if results.detections:for detection in results.detections:# 获取人脸的边界框相对坐标bboxC = detection.location_data.relative_bounding_boxih, iw, _ = frame.shape # 获取图像的高度和宽度# 将相对坐标转换为绝对坐标bbox = int(bboxC.xmin * iw), int(bboxC.ymin * ih), \int(bboxC.width * iw), int(bboxC.height * ih)# 在图像上绘制人脸矩形框cv.rectangle(frame, (bbox[0], bbox[1]), (bbox[0] + bbox[2], bbox[1] + bbox[3]), (255, 0, 255), 2)return frame
在主程序中,我们通过Picamera2捕获视频流,将YUYV格式的图像转换为BGR格式,使用
findFaces
方法来检测人脸,并将检测到的人脸信息实时显示在窗口中if __name__ == '__main__':picam2 = Picamera2()config = picam2.create_preview_configuration(main={"format": 'YUYV', "size": (320, 240)})picam2.configure(config)picam2.start()face_detector = FaceDetector(0.75)while True:frame = picam2.capture_array()# 将YUYV格式的图像转换为BGRframe = cv.cvtColor(frame, cv.COLOR_YUV2BGR_YUYV)# 检测人脸并水平翻转图像frame = face_detector.findFaces(cv.flip(frame, 1))cv.imshow('frame', frame) if cv.waitKey(1) & 0xFF == ord('q'): breakcv.destroyAllWindows()
完整代码如下:
#!/usr/bin/env python3
# encoding: utf-8
import mediapipe as mp
import cv2 as cv
from picamera2 import Picamera2class FaceDetector:def __init__(self, minDetectionCon=0.5):# 初始化人脸检测模块,并设置最小检测置信度self.mpFaceDetection = mp.solutions.face_detectionself.facedetection = self.mpFaceDetection.FaceDetection(min_detection_confidence=minDetectionCon)def findFaces(self, frame):# 将图像从BGR转换为RGB,因为MediaPipe使用的是RGB格式img_RGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)# 处理图像,检测人脸results = self.facedetection.process(img_RGB)# 如果检测到人脸,则在图像上绘制矩形框if results.detections:for detection in results.detections:# 获取人脸的边界框相对坐标bboxC = detection.location_data.relative_bounding_boxih, iw, _ = frame.shape # 获取图像的高度和宽度# 将相对坐标转换为绝对坐标bbox = int(bboxC.xmin * iw), int(bboxC.ymin * ih), \int(bboxC.width * iw), int(bboxC.height * ih)# 在图像上绘制人脸矩形框cv.rectangle(frame, (bbox[0], bbox[1]), (bbox[0] + bbox[2], bbox[1] + bbox[3]), (255, 0, 255), 2)return frameif __name__ == '__main__':picam2 = Picamera2()config = picam2.create_preview_configuration(main={"format": 'YUYV', "size": (320, 240)})picam2.configure(config)picam2.start()face_detector = FaceDetector(0.75)while True:frame = picam2.capture_array()# 将YUYV格式的图像转换为BGRframe = cv.cvtColor(frame, cv.COLOR_YUV2BGR_YUYV)# 检测人脸并水平翻转图像frame = face_detector.findFaces(cv.flip(frame, 1))cv.imshow('frame', frame) if cv.waitKey(1) & 0xFF == ord('q'): breakcv.destroyAllWindows()
二、人脸识别
1、采集人脸
在实现人脸识别前,我们需要采集用户的人脸图像样本,建立一个基本的人脸数据库。为确保系统的高效和准确性,需采集多张人脸图像以便后续的人脸识别模型可以更好地学习每个用户的特征。
在本部分中,我们将利用OpenCV库采集人脸样本,并将这些图像存储在本地文件夹中。代码如下:
#利用opencv采集人脸(拍照)
import cv2
import os
import time
# 初始化摄像头
cam = cv2.VideoCapture(0)
cam.set(3, 640) # 设置视频宽度为640像素
cam.set(4, 480) # 设置视频高度为480像素# 加载人脸检测的分类器
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')# 输入用户ID,用于标识不同的用户
face_id = input('\n 输入用户ID并按回车 ==> ')print("\n [信息] 初始化人脸采集。看向摄像头等待...")
# 初始化单独采样人脸计数
count = 0while(True):# 读取摄像头的一帧图像ret, img = cam.read()# 将图像上下翻转img = cv2.flip(img, 1) # 垂直翻转视频图像# 将图像转换为灰度图,以提高处理速度gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 检测图像中的人脸faces = face_detector.detectMultiScale(gray, 1.3, 5)# 对于检测到的每一个人脸for (x,y,w,h) in faces:# 在图像上绘制矩形框cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2) # 增加人脸计数count += 1# 将捕捉到的人脸保存到datasets文件夹中cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])# 显示处理后的图像cv2.imshow('image', img)print("ok")time.sleep(0.2)# 按ESC退出视频k = cv2.waitKey(100) & 0xff if k == 27:break# 如果采集了30个样本,则停止视频elif count >= 30: break# 清理工作
print("\n [信息] 退出程序并清理资源")
cam.release() # 释放摄像头
cv2.destroyAllWindows() # 关闭所有OpenCV窗口
运行代码,输入用户ID:
按下回车进行人脸信息采集:
保存数据如下:
2、训练人脸识别模型
在完成了人脸图像的采集之后,接下来我们需要对这些图像进行训练,以便系统能够识别不同的用户。我们将使用OpenCV的LBPH(局部二值模式直方图)人脸识别算法进行训练。
LBPH (Local Binary Patterns Histogram) 是一种常用于人脸识别的特征提取方法,主要基于局部纹理信息来描述图像特征。它通过分析图像局部区域内像素的灰度关系,提取出具有高度差异性的特征,从而能够在光照、表情变化等方面取得较为鲁棒的识别效果。LBPH 是一种经典且有效的人脸识别方法。
以下是训练模型的代码实现:
import cv2
import numpy as np
from PIL import Image
import os# 人脸图像数据库的路径
path = 'dataset'# 创建LBPH人脸识别器
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 使用Haar特征分类器进行人脸检测
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");# 函数:获取图像和标签数据
def getImagesAndLabels(path):# 获取数据库中所有图像的路径imagePaths = [os.path.join(path, f) for f in os.listdir(path)] faceSamples = [] # 存储人脸样本ids = [] # 存储每张人脸的IDfor imagePath in imagePaths:# 打开图像并将其转换为灰度图PIL_img = Image.open(imagePath).convert('L')# 将灰度图转换为numpy数组img_numpy = np.array(PIL_img, 'uint8')# 获取图像文件名中的ID,假设文件名格式为:User.ID.xxx.jpgid = int(os.path.split(imagePath)[-1].split(".")[1])# 检测人脸位置faces = detector.detectMultiScale(img_numpy)# 遍历检测到的人脸区域,将每个区域保存到样本和标签列表中for (x, y, w, h) in faces:faceSamples.append(img_numpy[y:y+h, x:x+w])ids.append(id)return faceSamples, idsprint ("\n [信息] 训练人脸中,请稍候...")
# 获取所有人脸样本和对应的ID
faces, ids = getImagesAndLabels(path)
# 训练LBPH人脸识别器
recognizer.train(faces, np.array(ids))# 将训练好的模型保存到trainer/trainer.yml
recognizer.write('trainer/trainer.yml') # recognizer.save()在Mac上可用,但在Pi上不可用# 输出训练的人脸数量并结束程序
print("\n [信息] 训练了 {0} 张人脸。程序结束".format(len(np.unique(ids))))
运行代码进行训练,结果将得到一个trainer.yml文件,此文件保存着用户对应的LBPH相关数值
3、人脸识别应用
在成功训练完人脸识别模型后,我们将进入实际的识别环节。接下来,我们会使用摄像头实时捕捉视频流,并通过模型识别出画面中的人脸。
以下是实时人脸识别的代码实现:
import cv2
import numpy as np
import os
import time# 创建LBPH人脸识别器并加载训练好的模型
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')# 加载Haar特征分类器用于人脸检测
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath)font = cv2.FONT_HERSHEY_SIMPLEX# 初始化ID计数器
id = 0# ID与姓名的对应关系
names = ['None', 'ID=1', 'ID=2', 'ID=3', 'Z', 'W']# 初始化并开始实时视频捕捉
cam = cv2.VideoCapture(0)
cam.set(3, 640) # 设置视频宽度
cam.set(4, 480) # 设置视频高度# 定义识别为人脸的最小窗口大小
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
frame_count, pTime, cTime = 0, 0, 0 while True:ret, img = cam.read() # 从摄像头读取图像img = cv2.flip(img, 1) # 垂直翻转图像gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图# 检测人脸faces = faceCascade.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=5,minSize=(int(minW), int(minH)),)# 遍历检测到的人脸for (x, y, w, h) in faces:cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) # 绘制人脸框id, confidence = recognizer.predict(gray[y:y + h, x:x + w]) # 识别人脸if confidence < 70: # 置信度小于70id = names[id] # 获取对应的姓名confidence = " {0}%".format(round(100 - confidence)) # 计算置信度else:id = "unknown" # 识别为未知confidence = " {0}%".format(round(100 - confidence))# 显示姓名和置信度cv2.putText(img, str(id), (x + 5, y - 5), font, 1, (255, 255, 255), 2)cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (255, 255, 0), 1)frame_count += 1 # 帧计数cTime = time.time() # 当前时间fps = 1 / (cTime - pTime) # 计算FPSpTime = cTime # 更新上一帧时间text = "FPS : " + str(int(fps)) # 显示FPScv2.putText(img, text, (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)cv2.imshow('camera', img) # 显示摄像头画面k = cv2.waitKey(10) & 0xff # 按'ESC'键退出视频if k == 27:break# 清理工作
print("\n [信息] 退出程序并清理资源")
cam.release() # 释放摄像头
cv2.destroyAllWindows() # 关闭所有OpenCV窗口
此方法可以快速人脸录入(30秒)与模型训练最后依旧可以精准人脸识别。
本文介绍了如何在树莓派5B上实现快速的人脸录入与精准的人脸识别。从采集人脸图像、训练人脸数据库,再到使用LBPH进行实时识别,我们完成了一套简单但有效的人脸识别系统。LBPH特征提取方法在资源有限的设备上表现出色,能够在保证准确率的同时实现实时检测。
完整资料与代码下载:【免费】基于树莓派的安保巡逻机器人-(一、快速人脸录入与精准人脸识别)资源-CSDN文库
参考资料:基于Anirban Kar的代码https://github.com/thecodacus/Face-Recognition
相关文章:

基于树莓派的安保巡逻机器人--(一、快速人脸录入与精准人脸识别)
目录 零、前言 一、人脸检测 二、人脸识别 1、采集人脸 2、训练人脸识别模型 3、人脸识别应用 零、前言 随着智能安防需求的增长,基于人工智能和物联网的安保系统逐渐成为趋势。树莓派因其低成本、高扩展性等特点,成为很多AI项目的理想平台。本文将为大…...

中间件的应用
控制器 <?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;class AgeController extends Controller {//public function index(){return "年龄测试";} }路由 // 年龄控制器路由 Route::get("d2/{age}",[AgeController::class,&quo…...
真题与解析 202206二级 青少年软件编程(Python)考级
青少年软件编程(Python)等级考试试卷(二级) 202206真题与解析 分数:100 题数:37 测试时长:60分钟</...

ChatGPT新体验:AI搜索功能与订阅支付指南
就在凌晨,在ChatGPT迎来两周岁生日之际,OpenAI重磅发布了ChatGPT的全新人工智能搜索体验。 期待已久的时刻终于到来, ChatGPT正式转型成为一款革命性的AI搜索引擎! 先来看看ChatGPT搜索:这次不是简单的加个搜索框,而…...

【植物识别】Python+深度学习+人工智能+CNN卷积神经网络+算法模型训练+TensorFlow
一、介绍 植物识别系统,使用Python作为主要编程语言开发,通过收集常见的6中植物树叶(‘广玉兰’, ‘杜鹃’, ‘梧桐’, ‘樟叶’, ‘芭蕉’, ‘银杏’)图片作为数据集,然后使用TensorFlow搭建ResNet50算法网络模型&am…...

快讯,Flutter PC 多窗口新进展,已在 Ubuntu/Canonical 展示
相信 Flutter 开发者对于 Flutter PC 多窗口的支持一直是「望眼欲穿」,而根据 #142845 相关内容展示, 在上月 27 号的 Ubuntu 峰会,Flutter 展示了多窗口相关进展。 事实上 Ubuntu 和 Flutter 的进一步合作关系应该是在 2021 年就开始了&…...

BigDecimal 详解
阿里巴巴 Java 开发手册》中提到:“为了避免精度丢失,可以使用 BigDecimal 来进行浮点数的运算”。 浮点数的运算竟然还会有精度丢失的风险吗?确实会! 示例代码: float a 2.0f - 1.9f; float b 1.8f - 1.7f; Syst…...

ESP-HaloPanel:用 ESP32-C2 打造超低成本智能家居面板
项目简介 在生活品质日益提升的今天,智能家居系统已经走进了千家万户,并逐渐成为现代生活的一部份。与此同时,一款设计精致、体积轻盈、操作简便的全屋智能家居控制面板,已经成为众多家庭的新宠。这种高效、直观的智能化的解决方…...
CSS3新增盒子属性(三)
1、CSS3新增盒子属性 1.1 box-sizing 设置盒子的大小。 content-box:设置内容区的大小;border-box:设置盒子的总大小。 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><t…...

Manus在虚拟现实仿真模拟中的应用案例分享
Manus虚拟现实手套作为一种高精度的人机交互设备,在仿真模拟领域展现出了巨大的应用潜力。通过提供实时、准确的手指动作捕捉数据,Manus手套为多个行业带来了前所未有的仿真体验,推动了技术发展和应用创新。 技术特点 1. 高精度手指跟踪 Ma…...

大数据-201 数据挖掘 机器学习理论 - 决策树 局部最优 剪枝 分裂 二叉分裂
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...
Scala 的trait
在Scala中,trait是一种特殊概念。trait可以作为接口,同时也可以定义抽象方法。类使用extends继承trait,在Scala中,无论继承类还是继承trait都用extends关键字。在Scala中, 类继承trait后必须实现其中的抽象方法&#x…...

vue3官方示例-简单的 markdown 编辑器。
官方示例不能直接粘贴使用,故自己补了些代码。方便初学者学习,节省时间,提高学习效率。 1、html代码: <!doctype html> <html lang"en"> <head><meta charset"UTF-8"><meta nam…...

Linux标准I/O库汇总整理
Linux标准I/O库(Standard I/O Library)是C标准库的一部分,提供了一系列用于文件输入输出的高级接口。这些接口通常比低级别的系统调用更易于使用,但也可能带来额外的性能开销。下面是Linux标准I/O库的汇总整理,包括常见…...

BGP路由优选+EVPN
BGP 的路由优选规则是一套多步决策链,用来确定在多个可行路由中选择最优的路由。BGP 是一种路径向量协议,通过这些优选规则,网络管理员可以控制数据流量的流向,确保网络的稳定性和效率。下面以一个实例来详细说明 BGP 的优选规则及…...
牛客练习赛131(未补)
A-小H学语文 题意:木板数量为m,想让mmh(min)最大,找出这几块木板 分析:让木板从大到小排序,找到最大的体积,将之前的木板按序列输出 代码: #include<bits/stdc.h> using n…...

功能更新丨AI黑科技助燃VR全景新势能
随着VR全景市场需求不断扩大, 为更好地赋能合作商业务发展, 酷雷曼积极推进产品技术迭代, 融合VR虚拟现实和AI人工智能, 重磅推出6大AI黑科技, 让VR全景内容更丰富、创作更加高效! 新功能怎么用&#…...
JavaCV学习第一课
1、 JavaCV [1] 是一款基于JavaCPP [2]调用方式(JNI的一层封装),由多种开源计算机视觉库组成的包装库,封装了包含FFmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在内的计算…...

Java第二阶段---16字符串---第一节 String
1.特性介绍 String 类位于 java.lang 包中,无需引入,直接使用即可。 String 类是由 final 修饰的,表示String 类是一个最终类,不能够被继承。 String 类构建的对象不可再被更改 示例 package com.cyx.string;public class Ex…...

<十六>Ceph mon 运维
Ceph 集群有故障了,你执行的第一个运维命令是什么? 我猜测是ceph -s 。无论执行的第一个命令是什么,都肯定是先检查Mon。 在开始之前我们有必要介绍下Paxos协议,毕竟Mon就是靠它来实现数据唯一性。 一: Paxos 协议 1…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...