用python在树莓派上实现人脸识别 代码

摄像头测试代码

import cv2

capCamera = cv2.VideoCapture(0)
if(not capCamera.isOpened()):
    print("can't open this camera")
    exit(0)

capCamera.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
capCamera.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

while(True):
    # handle for the camera
    ret, frame = capCamera.read()
    if ret == True:
        cv2.imshow('camera',frame)
    else:
        break

    # handle for the video

    # handle for exit
    if (cv2.waitKey(1)) == ord('q'):
        break

capCamera.release()
cv2.destroyAllWindows()
	

 

GPIO示例

import RPi.GPIO as GPIO

import time

GPIO.setmode(GPIO.BCM)

GPIO.setmode(18,GPIO.OUT)
//BCM 编号GPIO18 ;wPI 编号 1;物理引脚 12

while True:

        GPIO.output(18,GPIO.HIGH)

        time.sleep(1)

        GPIO.output(18,GPIO.LOW)

        time.sleep(1)

        GPIO.cleanup()

信息录入

#import cv2.cv2 as cv2
import cv2
import os

#config
add_name = 'xiaoming'#要录入的人名

#cv2.imread()
target_dir = './pic_dir/{}/'.format(add_name)
if os.path.exists(target_dir) is False:
    os.makedirs(target_dir)

#path='\home\pi\opencv-4.2.0\modules\objdetect\src\cascadedetect'
def generate():
    face_cascade = cv2.CascadeClassifier('/home/pi/opencv-4.2.0/data/haarcascades_cuda/haarcascade_frontalface_default.xml')
   # face_cascade.load(path+'\haarcascade_frontalface_default.xml')
    #打开摄像头
    camera = cv2.VideoCapture(0)
    forword_count = 0
    #正脸采集,一共20张图片
    while (forword_count <= 20):
        ret, frame = camera.read()
        #转化为灰度图像,用来检测人脸
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        faces = face_cascade.detectMultiScale(gray, 1.3, 5)

        for (x, y, w, h) in faces:
            #画出预测框
            cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

            f = cv2.resize(gray[y:y + h, x:x + w], (200, 200))
            #保存录入的图片
            cv2.imwrite('./pic_dir/{0}/{1}.png'.format(add_name, forword_count), f)
            print(forword_count)
            forword_count += 1
        #展示图片
        cv2.imshow("camera", frame)
        #一秒钟24帧
        if cv2.waitKey(1000 // 24) & 0xff == ord("q"):
            break

    camera.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    generate()

 

人脸识别

import os
import sys
import cv2
import numpy as np
import time
from picamera import PiCamera
import RPi.GPIO as GPIO

RelayPin = 16

def setup():
     GPIO.setmode(GPIO.BOARD)
     GPIO.setup(RelayPin,GPIO.OUT)
     GPIO.output(RelayPin,GPIO.LOW)

#def destroy():
    #GPIO.output(RelayPin,GPIO.LOW)
   # GPIO.cleanup()

def change_door(open_later_time,isOpen,new_face_position):
    
    if len(new_face_position) > 0 and isOpen == False:
        print('打开1')
        isOpen = True
    if len(new_face_position) == 0 and isOpen == True:
        open_later_time += 1
    else:
        open_later_time = 0
    if open_later_time == 100:
        open_later_time = 0
        print('关闭1')
        isOpen = False
    return open_later_time,isOpen,new_face_position

def read_images(path, sz=None):#给一个地址,返回训练集
    c = 0
    X, Y = [], []
    names = []
    for dirname, dirnames, filenames in os.walk(path):#目录,子目录,子文件(只限一层目录)
        for subdirname in dirnames:
            names.append(subdirname)
            subject_path = os.path.join(dirname, subdirname)
            for filename in os.listdir(subject_path):#遍历每个名字
                try:
                    if (filename == ".directory"):
                        continue
                    filepath = os.path.join(subject_path, filename)
                    im = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
                    if (im is None):
                        print("image " + filepath + " is none")
                    else:
                        print(filepath)
                    if (sz is not None):
                        im = cv2.resize(im, (200, 200))

                    X.append(np.asarray(im, dtype=np.uint8))
                    Y.append(c)
                except IOError:
                    print("I/O error({0}): {1}".format(IOError.errno, IOError.strerror))

                except:
                    print("Unexpected error:", sys.exc_info()[0])

                    raise
            print(c)
            c = c + 1

    print(Y)
    print(names)

    return [X, Y], names


def face_rec():
    image_dir = './pic_dir'
    isOpen = False
    open_later_time = 0
    time_start = 0
    time_end = 0
    cost = 0

    [X, Y] , names = read_images(image_dir)
    Y = np.asarray(Y, dtype=np.int32)
    
    #python3
    model = cv2.face.LBPHFaceRecognizer_create()
    #python2
    #model = cv2.createLBPHFaceRecognizer()
    
    model.train(np.asarray(X), np.asarray(Y))
    camera = cv2.VideoCapture(0)
    #camera.set(cv2.CAP_PROP_FRAME_WIDTH, 400)
    #camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 350)
    face_cascade = cv2.CascadeClassifier('/home/pi/opencv-4.2.0/data/haarcascades/haarcascade_frontalface_default.xml')
    re_count = 0
    old_face_position = {}#用来绘制预测框
    new_face_position = {}#用来收集新数据
    while (True):
        #print(old_face_position)
        #print(new_face_position)
        re_count += 1
        read, img = camera.read()
        faces = face_cascade.detectMultiScale(img,1.3,5)
        #print('{}的类型{}'.format(faces, type(faces)))
        for (x, y, w, h) in faces:
            img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            roi = gray[x:x + w, y:y + h]
            try:
                roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
                #print(roi.shape)
                [label,confidence]=params = model.predict(roi)
                
                #print("Label: %s, Confidence: %.2f" % (params[0], params[1]))
                #cv2.putText(img,names[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2)
                #print(params)
                new_face_position[names[params[0]]] = (x, y, w, h)
                #print(len(new_face_position))
            except:
                continue

        #优化用户体验
        #采集三帧的人脸识别信息,将预测框画出,预测框三帧一刷新,防止预测框频繁抖动的现象
        if re_count == 3:
            re_count = 0
            #print(new_face_position)
            if len(new_face_position) > 0:
                for key in new_face_position.keys():
                    (x, y, w, h) = new_face_position[key]
                    if old_face_position.__contains__(key) is False:
                        img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
                        cv2.putText(img, key, (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
                        #print('did1')
                        old_face_position[key] = (x, y, w, h)
                    else:
                        (o_x, o_y, o_w, o_h) = new_face_position[key]
                        if abs((o_x-x)) <= 5 and abs((o_y-y)) <= 5:
                            img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
                            cv2.putText(img, key, (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
                            #print('no')
                            old_face_position[key] = (x, y, w, h)
            else:
                old_face_position = {}
                new_face_position = {}
        else:
            for key in old_face_position.keys():
                (o_x, o_y, o_w, o_h) = old_face_position[key]
                img = cv2.rectangle(img, (o_x, o_y), (o_x + o_w, o_y + o_h), (255, 0, 0), 2)
                cv2.putText(img, key, (o_x, o_y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)

        #开关门模拟和保存打卡信息
        #如果检测到人,并且门没有开,则打开门,并且录入信息
        if len(new_face_position) > 0 and isOpen == False :
            if(confidence < 65):
                setup()
                print('开门')
                GPIO.output(RelayPin,GPIO.LOW)
                time.sleep(1)
                GPIO.output(RelayPin,GPIO.HIGH)
                time.sleep(1)
                #GPIO.output(RelayPin,GPIO.LOW)
                #time.sleep(1)
                time_start=time.time()
                #time_end = time.time()
                #保存打卡信息
                t = time.strftime('%Y.%m.%d %H:%M:%S', time.localtime(time.time()))
                with open('jilu.txt', 'a') as file:
                    file.writelines('{},{}\n'.format(new_face_position.keys(),t))
                isOpen = True
        
        #如果没有检测到人,并且门开了,计数器+1,否则计数器为0
        if len(new_face_position) == 0 and isOpen == True:
            open_later_time += 1
        elif time.time()-time_start > 2:
            open_later_time = 10
        else :
            open_later_time = 0
         
        #当计数器为10的时候关门
        if open_later_time == 10 : #or time_end-time_start == 2:
            setup()
            #GPIO.output(RelayPin,GPIO.HIGH)
            #time.sleep(1)
            print('关门')
            GPIO.output(RelayPin,GPIO.LOW)
            time.sleep(1) 
            GPIO.cleanup()
            isOpen = False
            open_later_time = 0

        cv2.imshow("camera", img)
        #树莓派最好将帧数设为最大,不然看起来不舒服
        if cv2.waitKey(1000 // 25) & 0xff == ord("q"):
        #if cv2.waitKey(1000 // 25) & 0xff == ord("q"):
            break
    camera.release()
    cv2.destroyAllWindows()



if __name__ == "__main__":
    
    setup()
    face_rec()
    
    

 

GPIO 控制参考代码

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time

RelayPin = 11    # pin11

def setup():
	GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
	GPIO.setup(RelayPin, GPIO.OUT)
	GPIO.output(RelayPin, GPIO.HIGH)

def loop():
	while True:
		print '...relayd on
		GPIO.output(RelayPin, GPIO.LOW)
		time.sleep(0.5)
		print 'relay off...'
		GPIO.output(RelayPin, GPIO.HIGH)
		time.sleep(0.5)

def destroy():
	GPIO.output(RelayPin, GPIO.HIGH)
	GPIO.cleanup()                     # Release resource

if __name__ == '__main__':     # Program start from here
	setup()
	try:
		loop()
	except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child program destroy() will be  executed.
		destroy()

信息录入错误

 faces = face_cascade.detectMultiScale(gray, 1.3, 5,cv2.CASCADE_SCALE_IMAGE)
cv2.error: OpenCV(4.2.0) /home/pi/opencv-4.2.0/modules/objdetect/src/cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'detectMultiScale'

属于路径问题,仔细查看后更正即可

人脸识别代码问题

module 'cv2' has no attribute 'face'

https://www.piwheels.org/simple/openvn-contrib-python/

版本问题,在当前版本该函数名可能不同,还有很多类似都是属于版本不同,可以查阅后更改函数名

你可能感兴趣的:(面部识别,人脸识别)