基於python+opencv的簡易人臉識別打卡系統


import cv2
import os
import numpy as np
from PIL import Image
import datetime
import csv
from time import sleep
# 調用筆記本內置攝像頭,所以參數為0,如果有其他的攝像頭可以調整參數為1,2
Path = r"C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml"
face_detector = cv2.CascadeClassifier(Path)
names = []
zh_name = []
with open("maxmember.csv","r",encoding='UTF-8') as csv_file:
    reader = csv.reader(csv_file)
    for item in reader:
        # print(item)
        names.append(item[2])
        zh_name.append(item[1])
    # print (zh_name)

def data_collection():
    cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)#cv2.CAP_DSHOW是作為open調用的一部分傳遞標志,還有許多其它的參數,而這個CAP_DSHOW是微軟特有的。
    face_id = input('\n 請輸入你的ID:')
    print('\n 數據初始化中,請直視攝像機錄入數據....')
    count = 0
    while True:

        # 從攝像頭讀取圖片
        sucess, img = cap.read()

        # 轉為灰度圖片
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 檢測人臉
        faces = face_detector.detectMultiScale(gray, 1.3, 5)#1.image表示的是要檢測的輸入圖像# 2.objects表示檢測到的人臉目標序列# 3.scaleFactor表示每次圖像尺寸減小的比例
        for (x, y, w, h) in faces:
            #畫矩形
            cv2.rectangle(img, (x, y), (x + w, y + w), (255, 0, 0))
            count += 1
            # 保存圖像
            cv2.imwrite("facedata/Member." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])
            cv2.imshow('data collection', img)
        # 保持畫面的持續。
        k = cv2.waitKey(1)
        if k == 27:  # 通過esc鍵退出攝像
            break
        elif count >= 200:  # 得到n個樣本后退出攝像
            break
    cap.release()
    cv2.destroyAllWindows()
def face_training():
    # 人臉數據路徑
    path = './facedata'
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    #LBP是一種特征提取方式,能提取出圖像的局部的紋理特征
    def get_images_and_labels(path):
        imagePaths = [os.path.join(path, f) for f in os.listdir(path)]  # join函數將多個路徑組合后返回
        faceSamples = []
        ids = []
        # 遍歷圖片路徑,導入圖片和id,添加到list
        for imagePath in imagePaths:
            PIL_img = Image.open(imagePath).convert('L') #通過圖片路徑並將其轉換為灰度圖片。

            img_numpy = np.array(PIL_img, 'uint8')
            id = int(os.path.split(imagePath)[-1].split(".")[1])
            faces = face_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('數據訓練中')
    faces, ids = get_images_and_labels(path)
    recognizer.train(faces, np.array(ids))

    recognizer.write(r'.\trainer.yml')

def face_ientification():
    cap = cv2.VideoCapture(0)
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    
    recognizer.read('./trainer.yml')
    faceCascade = cv2.CascadeClassifier(Path)
    font = cv2.FONT_HERSHEY_SIMPLEX

    idnum = 0
    global namess
    cam = cv2.VideoCapture(0)
    #設置大小
    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)
        
        # 將人臉用vector保存各個人臉的坐標、大小(用矩形表示)
        faces = faceCascade.detectMultiScale(
            gray,
            scaleFactor=1.2,#表示在前后兩次相繼的掃描中,搜索窗口的比例系數
            minNeighbors=5,#表示構成檢測目標的相鄰矩形的最小個數(默認為3個)
            minSize=(int(minW), int(minH))#minSize和maxSize用來限制得到的目標區域的范圍
        )
    
        for (x, y, w, h) in faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
            # 返回偵測到的人臉的id和近似度conf(數字越大和訓練數據越不像)
            idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])

            if confidence < 100:
                namess = names[idnum]
                confidence = "{0}%".format(round(100 - confidence))
            else:
                namess = "unknown"
                confidence = "{0}%".format(round(100 - confidence))

            cv2.putText(img, str(namess), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
            cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (0, 0, 0), 1)#輸出置信度

        cv2.imshow(u'Identification punch', img)
        k = cv2.waitKey(5)
        if k == 13:
            theTime = datetime.datetime.now()
            # print(zh_name[idnum])
            strings = [str(zh_name[idnum]),str(theTime)]
            print(strings)
            with open("log.csv", "a",newline="") as csvFile:
                writer = csv.writer(csvFile)
                writer.writerow([str(zh_name[idnum]),str(theTime)])
        elif k==27:
            cap.release()
            cv2.destroyAllWindows()
            break
while True:
    a = int(input("輸入1,錄入臉部,輸入2進行識別打卡:"))
    if a==1:
        data_collection()
    elif a==2:
        face_ientification()
    elif a==3:
        face_training()

人臉識別代碼部分,詳細參考https://www.cnblogs.com/xp12345/p/9818435.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM