树莓派双目人脸识别门禁(在线+离线模式)+刷卡进出

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在这里插入图片描述
在这里插入图片描述

我做好的成品运行视频见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);
  
}

如有侵权,请联系!

  • 7
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值