0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎样用树莓派构建基于面部识别的门锁

454398 来源:工程师吴畏 2019-07-30 09:16 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

该项目将包括三个阶段:

人脸检测和数据收集

训练识别器

面部识别

在深入研究代码之前,让我们将电磁锁与Raspberry Pi连接。

电路图和说明

Raspberry Pi的GPIO引脚可以提供3.3V的输出,但电磁锁需要7-12V才能工作。因此,我们需要使用外部电源和继电器来操作锁定。

将继电器模块的VCC和GND连接到Raspberry Pi的5V和GND。然后将继电器模块的信号引脚连接到Raspberry Pi的GPIO 26.

在继电器模块的另一侧,将负极直流电源连接到电磁门锁的负极。将来自直流电源的正极连接到继电器模块的公共端,然后将常开模块从继电器模块连接到电磁门锁的正极。

面部识别电路图。

人脸检测的数据收集

第一个任务是收集我们要训练分类器的数据。我们将使用OpenCV预训练分类器编写一个python代码,每个人需要30个面。

OpenCV已经包含许多面部,眼睛,微笑等预先训练的分类器。我们要去的分类器使用将检测面部,并在GitHub上提供级联文件。

将此文件保存在工作目录中“haarcascade_frontalface_default.xml”。

代码演练

现在让我们编写代码。 首先,我们导入所需的包。

import cv2

from picamera.array import PiRGBArray

from picamera import PiCamera

import numpy as np

import os

import sys

然后我们初始化相机对象,这将允许我们使用Raspberry Pi相机。我们将分辨率设置为(640,480),帧速率设置为30 fps。

camera = PiCamera()

camera.resolution = (640, 480)

camera.framerate = 30

PiRGBArray() 为我们提供了一个来自未编码RGB捕获的三维RGB数组(行,列,颜色)。 PiRGBArray的优势在于它能够将Raspberry Pi相机中的帧读取为NumPy阵列,使其与OpenCV兼容。它避免了从JPEG格式到OpenCV格式的转换,这会减慢我们的过程。

它需要两个参数:

相机对象

分辨率

rawCapture = PiRGBArray(camera, size=(640, 480))

加载用于检测面的级联文件。

face_cascade = cv2.CascadeClassifier(“haarcascade_frontalface_default.xml”);

接下来,我们要求用户输入名称。如果已存在具有该名称的目录,则它将以“名称已存在”进行响应并退出代码。如果没有此名称的目录,它将创建目录,图像将以此名称保存。

name = input(“What‘s his/her Name? ”)

dirName = “。/images/” + name

print(dirName)

if not os.path.exists(dirName):

os.makedirs(dirName)

print(“Directory Created”)

else:

print(“Name already exists”)

sys.exit()

为图像创建目录。

之后,我们使用 capture_continuous 从Raspberry Pi相机模块开始读取帧的功能。

c apture_continuous函数有三个参数:

rawCapture

我们想要读取每个帧的格式,因为OpenCV期望图像采用BGR格式而不是RGB格式,因此我们将格式指定为BGR。

use_video_port布尔值,使其为true意味着我们将流视为视频。

for frame in camera.capture_continuous(rawCapture, format=“bgr”, use_video_port=True):

一旦我们有了f rame,我们可以通过.array属性访问原始的NumPy数组。访问后,我们将此帧转换为灰度。

frame = frame.array

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

然后我们调用分类器函数来检测帧中的面。我们传递的第一个参数是灰度图像。第二个参数是指定在每个图像比例下图像尺寸减少多少的参数。第三个参数是一个参数,指定每个候选矩形应保留多少个邻居。数字越大,误报率越低。

faces = faceCascade.detectMultiScale(gray, scaleFactor = 1.5, minNeighbors = 5)

上面的函数给出了面部区域的矩形坐标。我们使用这些坐标从图像中提取面部并将其保存在我们在开始时创建的目录中。之后,我们展示了裁剪的面部并在原始框架上创建了一个矩形。

代码将收集30张图像。

for (x, y, w, h) in faces:

roiGray = gray[y:y+h, x:x+w]

fileName = dirName + “/” + name + str(count) + “.jpg”

cv2.imwrite(fileName, roiGray)

cv2.imshow(“face”, roiGray)

cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

count += 1

然后我们在上面显示原始帧输出窗口。 cv2.waitkey()是一个键盘绑定函数。它等待任何键盘事件的指定毫秒。它需要一个参数,这个参数是以毫秒为单位的时间。如果在该时间内按下该键,则程序将继续。传递0表示它将无限期地等待一个键。

cv2.imshow(’frame‘, frame)

key = cv2.waitKey(1)

然后我们通过在捕获之间调用truncate(0)来清除流以准备下一帧。

rawCapture.truncate(0)

人脸检测和数据收集工作现已完成。我们应该在新创建的目录中有30个图像。

我们的30张图片保存在新创建的目录中。

人脸检测完整代码

import cv2

from picamera.array import PiRGBArray

from picamera import PiCamera

import numpy as np

import os

import sys

camera = PiCamera()

camera.resolution = (640, 480)

camera.framerate = 30

rawCapture = PiRGBArray(camera, size=(640, 480))

faceCascade = cv2.CascadeClassifier(“haarcascade_frontalface_default.xml”)

name = input(“What’s his/her Name? ”)

dirName = “。/images/” + name

print(dirName)

if not os.path.exists(dirName):

os.makedirs(dirName)

print(“Directory Created”)

else:

print(“Name already exists”)

sys.exit()

count = 1

for frame in camera.capture_continuous(rawCapture, format=“bgr”, use_video_port=True):

if count 》 30:

break

frame = frame.array

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(gray, scaleFactor = 1.5, minNeighbors = 5)

for (x, y, w, h) in faces:

roiGray = gray[y:y+h, x:x+w]

fileName = dirName + “/” + name + str(count) + “.jpg”

cv2.imwrite(fileName, roiGray)

cv2.imshow(“face”, roiGray)

cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

count += 1

cv2.imshow(‘frame’, frame)

key = cv2.waitKey(1)

rawCapture.truncate(0)

if key == 27:

break

cv2.destroyAllWindows()

训练识别器

现在我们可以根据上一步收集的数据训练识别器。

我们将使用LBPH (LOCAL BINARY PATTERNS HISTOGRAMS)面部识别器,包含在OpenCV包中。我们将它加载到以下行:

recognizer = cv2.face.LBPHFaceRecognizer_create()

我们获取当前工作目录的路径,然后移动到图像目录所在的目录。

baseDir = os.path.dirname(os.path.abspath(__file__))

imageDir = os.path.join(baseDir, “images”)

《然后我们进入每个图像目录并查找图像。如果图像存在,我们将其转换为NumPy数组。

for root, dirs, files in os.walk(imageDir):

print(root, dirs, files)

for file in files:

print(file)

if file.endswith(“png”) or file.endswith(“jpg”):

path = os.path.join(root, file)

label = os.path.basename(root)

print(label)

if not label in labelIds:

labelIds[label] = currentId

print(labelIds)

currentId += 1

id_ = labelIds[label]

pilImage = Image.open(path).convert(“L”)

imageArray = np.array(pilImage, “uint8”)

之后,我们再次进行面部检测,以确保我们有正确的图像,然后我们准备训练数据。

faces = faceCascade.detectMultiScale(imageArray, scaleFactor=1.1, minNeighbors=5)

for (x, y, w, h) in faces:

roi = imageArray[y:y+h, x:x+w]

xTrain.append(roi)

yLabels.append(id_)

存储包含目录名称和标签ID的字典。

with open(“labels”, “wb”) as f:

pickle.dump(labelIds, f)

f.close()

现在训练数据并保存文件。

recognizer.train(xTrain, np.array(yLabels))

recognizer.save(“trainer.yml”)

此代码创建一个trainer.yml并标记我们在识别代码中使用的文件。

我们在识别代码中使用的trainer.yml文件。

培训识别器的完整代码

import os

import numpy as np

from PIL import Image

import cv2

import pickle

faceCascade = cv2.CascadeClassifier(“haarcascade_frontalface_default.xml”)

recognizer = cv2.face.LBPHFaceRecognizer_create()

baseDir = os.path.dirname(os.path.abspath(__file__))

imageDir = os.path.join(baseDir, “images”)

currentId = 1

labelIds = {}

yLabels = []

xTrain = []

for root, dirs, files in os.walk(imageDir):

print(root, dirs, files)

for file in files:

print(file)

if file.endswith(“png”) or file.endswith(“jpg”):

path = os.path.join(root, file)

label = os.path.basename(root)

print(label)

if not label in labelIds:

labelIds[label] = currentId

print(labelIds)

currentId += 1

id_ = labelIds[label]

pilImage = Image.open(path).convert(“L”)

imageArray = np.array(pilImage, “uint8”)

faces = faceCascade.detectMultiScale(imageArray, scaleFactor=1.1, minNeighbors=5)

for (x, y, w, h) in faces:

roi = imageArray[y:y+h, x:x+w]

xTrain.append(roi)

yLabels.append(id_)

with open(“labels”, “wb”) as f:

pickle.dump(labelIds, f)

f.close()

recognizer.train(xTrain, np.array(yLabels))

recognizer.save(“trainer.yml”)

print(labelIds)

使用识别器进行面部识别

我们在上一节中设置的识别器现在可用于识别面部。它会给我们信心和标签ID(识别器对这场比赛的信心程度)。如果面部匹配,继电器将打开。

首先我们加载包含字典的pickle文件。

with open(‘labels’, ‘rb’) as f:

dicti = pickle.load(f)

f.close()

然后我们加载将检测面部的分类器以及预测面部和训练数据的识别器。

faceCascade = cv2.CascadeClassifier(“haarcascade_frontalface_default.xml”)

recognizer = cv2.face.LBPHFaceRecognizer_create()

recognizer.read(“trainer.yml”)

我们读取帧,将其转换为灰度,并在图像中查找面。如果有任何面部,我们将提取面部区域并使用识别器识别图像。

识别器将为我们提供标签ID和置信度。

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(gray, scaleFactor = 1.5, minNeighbors = 5)

for (x, y, w, h) in faces:

roiGray = gray[y:y+h, x:x+w]

roiColor = frame[y:y+h, x:x+w]

id_, conf = recognizer.predict(roiGray)

我们在字典中查找分配给此标签ID的名称。

for name, value in dict.items():

if value == id_:

print(name)

然后检查我们是否有足够的信心打开门锁。如果信心小于70,门将打开。否则,它将保持关闭状态。

if conf 《= 70:

GPIO.output(relay_pin, 1)

cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

cv2.putText(frame, name + str(conf), (x, y), font, 2, (0, 0 ,255), 2,cv2.LINE_AA)

else:

GPIO.output(relay_pin, 0)

在原始图像中创建一个矩形,并将该名称写在矩形的顶部。

cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

cv2.putText(frame, name, (x, y), font, 2, (0, 0 ,255), 2,cv2.LINE_AA)

随着代码的完成,设置已准备好进行面部识别!

训练识别器的完整代码

import cv2

from picamera.array import PiRGBArray

from picamera import PiCamera

import numpy as np

import pickle

import RPi.GPIO as GPIO

from time import sleep

relay_pin = [26]

GPIO.setmode(GPIO.BCM)

GPIO.setup(relay_pin, GPIO.OUT)

GPIO.output(relay_pin, 0)

with open(‘labels’, ‘rb’) as f:

dicti = pickle.load(f)

f.close()

camera = PiCamera()

camera.resolution = (640, 480)

camera.framerate = 30

rawCapture = PiRGBArray(camera, size=(640, 480))

faceCascade = cv2.CascadeClassifier(“haarcascade_frontalface_default.xml”)

recognizer = cv2.face.LBPHFaceRecognizer_create()

recognizer.read(“trainer.yml”)

font = cv2.FONT_HERSHEY_SIMPLEX

for frame in camera.capture_continuous(rawCapture, format=“bgr”, use_video_port=True):

frame = frame.array

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(gray, scaleFactor = 1.5, minNeighbors = 5)

for (x, y, w, h) in faces:

roiGray = gray[y:y+h, x:x+w]

id_, conf = recognizer.predict(roiGray)

for name, value in dict.items():

if value == id_:

print(name)

if conf 《= 70:

GPIO.output(relay_pin, 1)

cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

cv2.putText(frame, name + str(conf), (x, y), font, 2, (0, 0 ,255), 2,cv2.LINE_AA)

else:

GPIO.output(relay_pin, 0)

cv2.imshow(‘frame’, frame)

key = cv2.waitKey(1)

rawCapture.truncate(0)

if key == 27:

break

cv2.destroyAllWindows()

最后的想法

这种人脸识别系统不是100%准确,但在良好的光线下效果很好条件。问题是它还可以检测图片中的面孔 - 例如,有人可以通过手机显示您的图片来解锁它。我们可以通过训练自己的级联分类器来改进这一点。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 面部识别
    +关注

    关注

    1

    文章

    376

    浏览量

    27781
  • 树莓派
    +关注

    关注

    122

    文章

    2082

    浏览量

    110769
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于树莓(RaspberryPi)构建高效实时监控系统

    由于树莓体积小、可开发性强等特性,常被用于视频监控场景中,结合 ZeroNews,可实现用户在任意位置都能实时安全得访问视频监控系统。 先决条件:树莓正常连接网络,可访问互联网 第
    的头像 发表于 09-22 15:14 1628次阅读
    基于<b class='flag-5'>树莓</b><b class='flag-5'>派</b>(RaspberryPi)<b class='flag-5'>构建</b>高效实时监控系统

    零成本钢铁侠手套!树莓+OpenCV 秒变手势遥控器!

    大家好,这是一个树莓和OpenCV的连载专题。使用树莓与OpenCV实现姿态估计和面部特征点追踪使用
    的头像 发表于 08-16 16:16 1569次阅读
    零成本钢铁侠手套!<b class='flag-5'>树莓</b><b class='flag-5'>派</b>+OpenCV 秒变手势遥控器!

    如何使用树莓与OpenCV实现面部和运动追踪的云台系统?

    大家好,这是一个树莓和OpenCV的连载专题。使用树莓与OpenCV实现姿态估计和面部特征点追踪使用
    的头像 发表于 08-14 17:45 2415次阅读
    如何使用<b class='flag-5'>树莓</b><b class='flag-5'>派</b>与OpenCV实现<b class='flag-5'>面部</b>和运动追踪的云台系统?

    如何使用树莓+OpenCV实现姿态估计和面部特征点追踪?

    大家好,这是一个树莓和OpenCV的连载专题。使用树莓与OpenCV实现姿态估计和面部特征点追踪使用
    的头像 发表于 08-13 17:44 1469次阅读
    如何使用<b class='flag-5'>树莓</b><b class='flag-5'>派</b>+OpenCV实现姿态估计和<b class='flag-5'>面部</b>特征点追踪?

    树莓做一个指纹识别方案,难不难?

    让我们在树莓单板计算机上解锁生物识别控制功能吧!生物识别技术利用每个人独有的、不易复制的生理或行为特征进行身份验证。地球上每个人的指纹都是独一无二的,让我们一起来探索指纹的奇妙用途吧
    的头像 发表于 08-09 13:14 1059次阅读
    <b class='flag-5'>用</b><b class='flag-5'>树莓</b><b class='flag-5'>派</b>做一个指纹<b class='flag-5'>识别</b>方案,难不难?

    树莓屏幕怎么选?

    树莓很多人都用过,但屏幕的倒不是很多。不少都是直接远程操作,或者直接接身边的显示设备了。但我觉得给开发板配一个屏幕还是很能提升使用体验的。这次我就介绍一下树莓
    的头像 发表于 08-08 14:59 1736次阅读
    <b class='flag-5'>树莓</b><b class='flag-5'>派</b>屏幕怎么选?

    树莓 + OpenCV 打造人脸识别技术!

    在本指南中,我们将教您如何使用OpenCV和面部识别库(两个出色的开源项目)设置树莓派来检测和识别面部。在这个设置中,所有的数据和处理都将在
    的头像 发表于 07-29 17:27 1562次阅读
    <b class='flag-5'>用</b><b class='flag-5'>树莓</b><b class='flag-5'>派</b> + OpenCV 打造人脸<b class='flag-5'>识别</b>技术!

    如何在树莓 AI HAT+上进行YOLO姿态估计?

    大家好,接下来会为大家开一个树莓5和YOLO的连载专题。内容包括四个部分:在树莓5上使用YOLO进行物体和动物识别-入门指南在
    的头像 发表于 07-20 20:34 1196次阅读
    如何在<b class='flag-5'>树莓</b><b class='flag-5'>派</b> AI HAT+上进行YOLO姿态估计?

    如何在树莓 AI HAT+上进行YOLO目标检测?

    大家好,接下来会为大家开一个树莓5和YOLO的连载专题。内容包括四个部分:在树莓5上使用YOLO进行物体和动物识别-入门指南在
    的头像 发表于 07-19 08:34 1972次阅读
    如何在<b class='flag-5'>树莓</b><b class='flag-5'>派</b> AI HAT+上进行YOLO目标检测?

    树莓5上开启YOLO姿态估计识别之旅!

    大家好,接下来会为大家开一个树莓5和YOLO的连载文章。内容包括四个部分:在树莓5上使用YOLO进行物体和动物识别-入门指南在
    的头像 发表于 07-18 15:31 2760次阅读
    在<b class='flag-5'>树莓</b><b class='flag-5'>派</b>5上开启YOLO姿态估计<b class='flag-5'>识别</b>之旅!

    树莓5上使用YOLO进行物体和动物识别-入门指南

    大家好,接下来会为大家开一个树莓5和YOLO的专题。内容包括四个部分:在树莓5上使用YOLO进行物体和动物识别-入门指南在
    的头像 发表于 07-17 17:16 2326次阅读
    在<b class='flag-5'>树莓</b><b class='flag-5'>派</b>5上使用YOLO进行物体和动物<b class='flag-5'>识别</b>-入门指南

    树莓分类器:树莓识别不同型号的树莓

    在本教程系列的第一部分中,您将学习如何使用树莓AI摄像头来检测不同的树莓型号。本系列由DavidPlowman创建,他是树莓
    的头像 发表于 06-13 16:39 1547次阅读
    <b class='flag-5'>树莓</b><b class='flag-5'>派</b>分类器:<b class='flag-5'>用</b><b class='flag-5'>树莓</b><b class='flag-5'>派</b><b class='flag-5'>识别</b>不同型号的<b class='flag-5'>树莓</b><b class='flag-5'>派</b>!

    树莓“揪出”家里的耗电怪兽!

    在本应用中,我们将使用树莓设置一个CE电流监测器,并通过网页界面显示电路的电流读数。本项目使用的组件硬件组件树莓2ModelBx112通道20安培电流监测控制器x1项目背景介绍在本
    的头像 发表于 06-04 15:33 2065次阅读
    <b class='flag-5'>用</b><b class='flag-5'>树莓</b><b class='flag-5'>派</b>“揪出”家里的耗电怪兽!

    树莓“吉尼斯世界记录”:将树莓的性能发挥到极致的项目!

    树莓是一款功能强大、体积小巧且高度可定制的设备,多年来,我们见证了它被应用于众多领域。无论是将其装入3D打印的经典游戏机外壳,还是简单地将它隐藏起来作为家庭文件服务器,我们都报道过在社区里
    的头像 发表于 05-22 16:53 1722次阅读
    <b class='flag-5'>树莓</b><b class='flag-5'>派</b>“吉尼斯世界记录”:将<b class='flag-5'>树莓</b><b class='flag-5'>派</b>的性能发挥到极致的项目!

    树莓 Zero 打造的智能漫游车!

    使用PXFMini和树莓Zero打造您自己的自主漫游车。本项目所用组件硬件组件ErleRoboticsPXFmini×1树莓Zero×1树莓
    的头像 发表于 05-13 16:39 1309次阅读
    <b class='flag-5'>用</b> <b class='flag-5'>树莓</b><b class='flag-5'>派</b> Zero 打造的智能漫游车!