提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
我做好的成品运行视频见b站:树莓派人脸识别门禁
一、安装配置
新手入门,树莓派操作系统配置方法树莓派配置Ho老师讲的很细致!!
树莓派配置usb摄像头:树莓派配置usb摄像头
在线模式用的是树莓派调用百度云api人脸识别,具体教程树莓派人脸识别门禁,照着她的一步步的来,配置好了就能实现了。如果usb摄像头配置好了,就不需要用她说的官方csi摄像头了,直接插usb摄像头。
这里提一嘴!现在淘宝卖的树莓派4b硬件都是1.5版本的,只能安装bullseye的操作系统,比如官网上下载的2022-04-04-raspios-bullseye-armhf-full.img.xz,这个版本python一直打不开摄像头,捣鼓了好几天,又联系了tb换了个旧硬件版本的树莓派,安装了旧版本buster操作系统才好用的。如有大神知道这个怎么解决评论一下,感谢!
离线模式需配置python opencv环境
python配置在b站哒哒贝塔那里配置好了,opencv配置教程:
树莓派配置opencv教程
二、代码文件(离线模式的)
1.树莓派代码
上面的文件第一行的都需要自己创建,第二行haar那个要到网上下载,rizhi.txt的会自己生成。
01_face_dateset.py文件代码如下:
这是拍摄你人脸照片的代码,会拍30张,存到dataset这个文件夹里。
import cv2
import os
cam = cv2.VideoCapture(0)
cam.set(3, 640)
cam.set(4, 480)
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_id = input('\n enter user id end press <return> ==> ')
count = 0
while(True):
ret, img = cam.read()
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
cv2.imwrite("dataset/yourname." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])
cv2.imshow('image', img)
k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
if k == 27:
break
elif count >= 30:
break
cam.release()
cv2.destroyAllWindows()
02_face_recognition.py文件代码如下:
训练你的人脸数据,生成一个xml文件存到trainer文件夹里。
import numpy as np
from PIL import Image
import os
import cv2
path = 'dataset'
recognizer = cv2.face.createLBPHFaceRecognizer()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
def getImagesAndLabels(path):
imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
faceSamples=[]
ids = []
for imagePath in imagePaths:
PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
img_numpy = np.array(PIL_img,'uint8')
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
faces,ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
recognizer.save('trainer/trainer.yml')
03_face_training.py文件代码如下:
import cv2
import numpy as np
import os
import time
from bluetest import bt_open,servo_init,bt_close
isOpen = False
open_later_time = 0
recognizer = cv2.face.createLBPHFaceRecognizer()
recognizer.load('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
font = cv2.FONT_HERSHEY_SIMPLEX
id = 0
Bro = 0
c=0
names = ['I', 'yourname', 'M', 'N', 'V']
cam = cv2.VideoCapture(0)
cam.set(3, 1200) # set video widht 这里我用的双目摄像头,显示连个画面,单目的可以改成600
cam.set(4, 450) # set video height
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
while True:
ret, img =cam.read()
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])
c = confidence
n = names[id]
if (confidence < 20) and isOpen == False:
bt_open()
id = names[id]
print('欢迎%s'%id)
c = " {0}%".format(round(100 - confidence))
Bro = 'Welcome'
t = time.strftime('%Y.%m.%d %H:%M:%S', time.localtime(time.time()))
with open('rizhi.txt', 'a') as file:
file.writelines('{},{}\n'.format(id,t))
isOpen = True
if isOpen == True:
open_later_time += 1
else:
open_later_time = 0
#当计数器为100的时候准备下一次识别,这样两次识别之间就有一段间隔,否则会因为人脸框刷新太快导致死机。
if open_later_time == 100:
print('准备就绪')
isOpen = False
open_later_time = 0
elif (confidence < 20):
c = " {0}%".format(round(100 - confidence))
Bro = 'Welcome'
else:
n = "unknown"
c = " {0}%".format(round(100 - confidence))
Bro = 'Who are you'
cv2.putText(img, str(n), (x+5,y-5), font, 1, (255,255,255), 2)
cv2.putText(img, str(c), (x+5,y+h-5), font, 1, (255,255,0), 1)
cv2.putText(img, str(Bro), (x,y+h+20), font, 1, (0,0,255), 2)
cv2.imshow('camera',img)
k = cv2.waitKey(30) & 0xff
if k == 27: # press 'ESC' to quit
break
cap.release()
cv2.destroyAllWindows()
蓝牙文件bluetest.py代码
import bluetooth
def servo_init():#初始化指令
bd_addr ="00:21:10:1E:B5:8A"#arduino连接的蓝牙模块的地址
port =1
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))#创建连接
sock.send("1")#发送数据
sock.close()#关闭连接
def bt_open():#开门指令
bd_addr ="00:21:10:1E:B5:8A"#arduino连接的蓝牙模块的地址
port =1
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))#创建连接
sock.send("2")#发送数据
sock.close()#关闭连接
def bt_close():#关门指令
bd_addr ="00:21:10:1E:B5:8A"#arduino连接的蓝牙模块的地址
port =1
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))#创建连接
sock.send("3")#发送数据
sock.close()#关闭连接
2.arduino代码
舵机,刷卡模块怎么连看这篇文章:arduino连线
代码用我的:
#include<Servo.h>
#include <RFID.h>
#include <SPI.h>
Servo myservo;
int pos =0;
RFID rfid(10,9); //D10--读卡器MOSI引脚、D5--读卡器RST引脚
int temp=0;
void setup()
{
Serial.begin(9600);
SPI.begin();
rfid.init();
myservo.attach(8);
myservo.write(0);
delay(10000);
}
void loop()
{
if (rfid.isCard()) {
Serial.println("找到卡");
//读取卡序列号
if (rfid.readCardSerial()) {
Serial.print("卡号");
Serial.print(rfid.serNum[0],HEX);
Serial.print(" ");
Serial.print(rfid.serNum[1],HEX);
Serial.print(" ");
Serial.print(rfid.serNum[2],HEX);
Serial.print(" ");
Serial.print(rfid.serNum[3],HEX);
Serial.print(" ");
Serial.print(rfid.serNum[4],HEX);
Serial.print(" ");
Serial.println(" ");
if(rfid.serNum[0]==0x03&&rfid.serNum[1]==0x22&&rfid.serNum[2]==0xDB&&rfid.serNum[3]==0x1D&&rfid.serNum[4]==0xE7)
{
temp=1;//NFC
}
}
//选卡,可返回卡容量(锁定卡片,防止多数读取),去掉本行将连续读卡
rfid.selectTag(rfid.serNum);
}
if(temp==1)
{
myservo.write(85);
delay(2500);
myservo.write(0);
temp=0;
}
rfid.halt();
while(Serial.available())//读取HC-05接收到的字符串
{char c;
c=Serial.read();
Serial.println (c);
switch(c){
case'1':servo_init();
break;
case'2':open_the_door();
break;
case'3':close_the_door();
break;
default:servo_init();
}
}
}
void servo_init()//舵机初始化
{
myservo.write(0);
delay(1000);
}
void open_the_door()//舵机开门
{
// for(pos =0; pos <= 180; pos +=1){
// myservo.write(pos);
myservo.write(85);
delay(2500);
myservo.write(0);
delay(5);
}
void close_the_door() //舵机关门
{
//for(pos = 180; pos >= 0; pos -= 1)
// {
// myservo.write(pos);
myservo.write(10);
delay(2500);
myservo.write(0);
delay(5);
}
如有侵权,请联系!