基于树莓派的安保巡逻机器人--(一、快速人脸录入与精准人脸识别)

news2024/11/26 6:23:50

目录

零、前言

一、人脸检测

 二、人脸识别

1、采集人脸

 2、训练人脸识别模型

 3、人脸识别应用

零、前言

        随着智能安防需求的增长,基于人工智能和物联网的安保系统逐渐成为趋势。树莓派因其低成本、高扩展性等特点,成为很多AI项目的理想平台。本文将为大家介绍如何使用树莓派打造一款智能安保巡逻机器人。本篇是系列的第一部分,将聚焦于“快速人脸录入与精准人脸识别”的实现步骤。

        本篇文章旨在通过搭建基于树莓派的安保巡逻机器人,实现人脸录入和识别功能。巡逻机器人将通过摄像头捕捉人脸信息,进行实时识别和数据存储,以实现自动化安保监控

树莓派5B作为一款小巧、功能强大的计算机设备,为快速人脸录入和精准识别提供了一个理想的硬件平台。本文将通过详细的代码示例,讲解如何利用树莓派5B与Python实现一个高效的人脸检测和识别系统。该系统可以实时捕捉人脸信息,进行边缘检测与处理,适用于智能安防、出入控制等多种场景。

一、人脸检测

由于不同需求,首先我们先进行一下人脸检测功能

我们将利用Python的Mediapipe和OpenCV库来完成图像处理,Picamera2库驱动树莓派的摄像头。(Mediapipe库是Google开源的多媒体处理框架,适用于多种机器学习任务;而OpenCV则是一个强大的计算机视觉库,广泛应用于图像处理、模式识别等领域。)以下是主要代码片段及其实现细节。

#!/usr/bin/env python3
# encoding: utf-8

import 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_detection
        self.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_box
                ih, 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格式的图像转换为BGR
            frame = 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'): 
                break
    
        cv.destroyAllWindows()
    

完整代码如下:

#!/usr/bin/env python3
# encoding: utf-8
import mediapipe as mp
import cv2 as cv
from picamera2 import Picamera2

class FaceDetector:
    def __init__(self, minDetectionCon=0.5):
        # 初始化人脸检测模块,并设置最小检测置信度
        self.mpFaceDetection = mp.solutions.face_detection
        self.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_box
                ih, 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

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格式的图像转换为BGR
        frame = 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'): 
            break

    cv.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 = 0

while(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 = []  # 存储每张人脸的ID

    for imagePath in imagePaths:
        # 打开图像并将其转换为灰度图
        PIL_img = Image.open(imagePath).convert('L')
        # 将灰度图转换为numpy数组
        img_numpy = np.array(PIL_img, 'uint8')

        # 获取图像文件名中的ID,假设文件名格式为:User.ID.xxx.jpg
        id = 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, ids

print ("\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:  # 置信度小于70
            id = 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)  # 计算FPS
    pTime = cTime  # 更新上一帧时间
    text = "FPS : " + str(int(fps))  # 显示FPS
    cv2.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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2228389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTB:BoardLight[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many TCP ports are listening on BoardLight? 2.What is the domain name used by the box? 3.What is the name of the application running on a virtual host of board.htb? 4.What version of Dolibarr is running on Board…

react18中redux-saga实战系统登录功能及阻塞与非阻塞的性能优化

redux-saga中的effect常用的几个是有区分出阻塞与非阻塞的&#xff0c;这里主要看下call和fork两者的区别。 实现效果 非阻塞的task执行&#xff0c;不用等到登录成功后请求的list接口完成&#xff0c;点击退出按钮可以立即退出 阻塞task的执行&#xff0c;必须等到登录成功…

【JavaEE】【多线程】进阶知识

目录 一、常见的锁策略1.1 悲观锁 vs 乐观锁1.2 重量级锁 vs 轻量级锁1.3 挂起等待锁 vs 自旋锁1.4 普通互斥锁 vs 读写锁1.5 可重入锁 vs 不可重入锁1.6 不公平锁 vs 公平锁 二、synchronized特性2.1 synchronized的锁策略2.2 synchronized加锁过程2.3 其它优化措施 三、CAS3.…

炫酷的登录框!(附源码)

大家想看什么前端效果请留言 预览效果 源码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>登录页…

RK3568平台开发系列讲解(内存篇)ioremap进行物理内存的映射

🚀返回专栏总目录 文章目录 一、使用案例:二、ioremap 函数的使用三、volatile 的使用一、使用案例: ioremapdevm_ioremap (你不用担心资源的释放)二、ioremap 函数的使用

中小企业设备资源优化:Spring Boot系统实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

基于SSM(spring+springmvc+mybatis)+MySQL开发的新闻推荐系统

基于内容的新闻推荐系统 一、环境搭建 开发框架&#xff1a;SSM(springspringmvcmybatis)开发语言&#xff1a;Java、HTML5、JavaScript开发工具&#xff1a;MyEclipse软件依赖&#xff1a;tomcat8、MySQL 1.1 新建工程 打开 myeclispe&#xff0c;新建一个 maven 工程&…

STM32 HAL ADC FIR 窗函数实现低通滤波

FIR 窗函数实现低通滤波 文章目录 FIR 窗函数实现低通滤波1.窗的分类与选择2.matlab设计3.代码编写4.结果欣赏与群延迟5.其他可能报错5.1.adc采集的数据没问题&#xff0c;vofa打印成-nan5.2.vofa打印的滤波数据为初始化的0 6.代码备忘 1.窗的分类与选择 2.matlab设计 主页命令…

例程学习(学习笔记)

project括号里面表示工程的名称&#xff0c;决定了最后生成的bin文件的名称&#xff0c;比如我们现在编译后的bin文件名称就是hello_world.bin文件&#xff0c;如果改成了project(xxx)&#xff0c;编译后的名称就是xxx.bin 这个文件用来设置路径&#xff0c;咱们得例程案例里面…

uniapp:上拉加载更多、下拉刷新、页面滚动到指定位置

提醒 本文实例是使用uniapp进行开发演示的。 一、需求场景 在开发商品&#xff08;SKU&#xff09;列表页面时&#xff0c;通常有三个需求&#xff1a; 页面下拉刷新&#xff0c;第一页展示最新数据&#xff1b;上拉加载更多数据&#xff1b;列表页面可以滚动到指定位置&#x…

5G在汽车零部件行业的应用

5G技术在汽车零部件行业的应用正在不断深入&#xff0c;为行业的智能化、自动化和高效化转型提供了强大的技术支持。 1、5G技术特点与优势 5G技术具有高速度、低延迟、大连接和切片技术等特点与优势。这些特性为汽车零部件行业提供了稳定、可靠、高效的通信连接&#xff0c;使…

jmeter的基本使用

Jmeter基本使用 一、变量 1.用户定义变量 2.用户参数 二、函数 1.计数器${__counter(,)} 2.时间函数 3.加密函数${__digest(,,,,)} 4. 整数相加${__intSum(,,)} 5.属性函数&#xff0c;${__P(,)}、${__property(,,)}、${__setProperty(,,)} 6.V函数 三、获取响应数据…

算法的学习笔记—和为 S 的连续正数序列(牛客JZ74)

&#x1f600;前言 在牛客网的《剑指 Offer》系列题中&#xff0c;有一道关于输出和为给定值 S 的连续正数序列的问题。这是一道典型的双指针问题&#xff0c;考察我们对连续数列求和的理解和双指针的应用。本文将详细解析这道题的思路&#xff0c;并展示如何实现代码。 &#…

D53【python 接口自动化学习】- python基础之模块与标准库

day53 自定义模块 学习日期&#xff1a;20241030 学习目标&#xff1a;模块与标准库 -- 67 自定义模块&#xff1a;如何编写一个完整功能&#xff1f; 学习笔记&#xff1a; 创建自定义模块 自定义模块注意事项 自定义模块 def func1():return this is a functionclass Cl…

上市公司企业数字金融认知数据集(2001-2023年)

一、测算方式&#xff1a;参考C刊《经济学家》王诗卉&#xff08;2021&#xff09;老师的做法&#xff0c;数字金融认知使用每万字年报描述中包含的对数字金融相关关键词的提及次数&#xff0c;关键词为&#xff1a;互联网、数字化、智能、大数据、电子银行、金融科技、科技金融…

4.2-7 运行MR应用:词频统计

文章目录 1. 准备数据文件2. 文件上传到HDFS指定目录2.1 创建HDFS目录2.2 上传文件到HDFS2.3 查看上传的文件 3. 运行词频统计程序的jar包3.1 查看Hadoop自带示例jar包3.2 运行示例jar包里的词频统计 4. 查看词频统计结果5. 在HDFS集群UI界面查看结果文件6. 在YARN集群UI界面查…

How to Train Neural Networks for Flare Removal

Abstract 当相机指向强光源时&#xff0c;生成的照片可能包含镜头眩光伪影。 耀斑以多种形式出现&#xff08;光晕、条纹、渗色、雾霾等&#xff09;&#xff0c;这种外观的多样性使得去除耀斑变得具有挑战性。 现有的分析解决方案对伪影的几何形状或亮度做出了强有力的假设&a…

Kafka如何控制消费的位置?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka如何控制消费的位置?】面试题&#xff1f;希望对大家有帮助&#xff1b; Kafka如何控制消费的位置? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中&#xff0c;控制消费位置主要通过以下几个机制来实…

shell脚本实例(4)while实现1+...+100,linux新增用户

while实现1到100求和 #!/bin/bash/ s0 i1 #-le小于等于 while [ $i -le 100 ] dos$[ $s$i ]i$[ $i1 ] done echo $s echo $i 执行结果如下 修改用户名密码脚本 #!/bin/bash/ #提示用户输入用户名 read -p "请输入用户名&#xff1a;"username useradd $username #提…

Qt 实战(10)模型视图 | 10.5、代理

文章目录 一、代理1、简介2、自定义代理 前言&#xff1a; 在Qt的模型/视图&#xff08;Model/View&#xff09;框架中&#xff0c;代理&#xff08;Delegate&#xff09;是一个非常重要的概念。它充当了模型和视图之间的桥梁&#xff0c;负责数据的显示和编辑。代理可以自定义…