国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

這篇具有很好參考價值的文章主要介紹了使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。


最近在做一個人臉識別考勤系統(tǒng),已經(jīng)總結(jié)和記錄了大部分內(nèi)容,算是比較完善啦!后續(xù)把剩下的搞完,感興趣的同學(xué)可以關(guān)注一下哦~ 文末給出了代碼獲取方式,請自行獲取食用~

B站:馬上就更?。。bilibili
CSDN:使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)_百年后封筆-CSDN博客
公眾號:百年后封筆

一、 環(huán)境配置

這里我們使用的環(huán)境主要包括一下三個方面:

  • 首先是開發(fā)所需要的python環(huán)境、包管理工具和IDE等。這里我們主要需要安裝的就是anacondapycharm專業(yè)版,以及pip鏡像源。需要注意的是,pycharm專業(yè)版是付費(fèi)軟件,如果你不想后續(xù)查看數(shù)據(jù)庫的詳細(xì)信息等,那么社區(qū)版也足夠了,但專業(yè)版是可以通過學(xué)生作科研用途申請的。
  • 本項目使用到了sqlite3數(shù)據(jù)庫,但我們最好也配置mysql數(shù)據(jù)庫,然后方便在pycharm專業(yè)版中查看數(shù)據(jù)庫的表和信息。
  • 最后是人臉識別和開發(fā)過程中依賴的python包,后面我們展示了幾種使用python進(jìn)行人臉識別的方法,除了opencv-python,其他的基本都需要dlib這個庫,后面我會說具體所依賴的庫,不過對于No Module Error的情況,直接pip install xxx就也可以輕松解決。

1.1 python環(huán)境配置

這里我們只提供windows下python環(huán)境的配置方法,其實(shí)都大同小異。

1.1.1 安裝 anaconda

anaconda是一個python的包管理軟件,可以方便的管理你的虛擬環(huán)境依賴的包

  1. 首先去官網(wǎng)下載安裝包
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

  2. 按照要求一步步進(jìn)行安裝即可,一直next就行。如果不清楚怎么安裝的話,可以直接搜一下anaconda的安裝方法,參考其他博主的詳細(xì)安裝指導(dǎo),這里我們不再贅述。
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

  3. 檢查anaconda是否安裝成功

打開cmd,輸入conda -V,一般會有兩種情況,下面這種就是安裝好了的。
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
如果報錯了,那么需要你將anaconda的安裝路徑先找到,比如,是在C:\Users\xxx\anaconda3,那么接著你就需要在你的系統(tǒng)環(huán)境變量里面,把下面幾個路徑加入到path里面,也就是把a(bǔ)naconda的binScripts路徑加入到環(huán)境變量里面去,如下:

C:\Users\xxx\anaconda3\bin
C:\Users\xmhh\anaconda3\Scripts
C:\Users\xmhh\anaconda3

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

操作完之后,再檢驗(yàn)一下conda有沒有安裝好就行了,一般出問題就是環(huán)境變量沒加入進(jìn)去,其他沒啥問題。

  1. 下面羅列一些常用的conda命令
# 建立新環(huán)境
conda create -n new env_name  python=3.8
# conda初始化
conda init
# 激活虛擬環(huán)境
conda activate env_name 或者  activate env_name
# 查看虛擬環(huán)境
conda env list
# 刪除虛擬環(huán)境
conda remove -n env_name --all

1.1.2 安裝pycharm

  1. 去官網(wǎng)下載安裝包
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
  • 需要注意的是,左邊專業(yè)版安裝包可以免費(fèi)用30天,或者可以認(rèn)證一下教育優(yōu)惠延期用,右邊社區(qū)版是免費(fèi)的。專業(yè)版可以查看數(shù)據(jù)庫,遠(yuǎn)程連接等,功能更加全面,社區(qū)版也勉強(qiáng)夠用吧。
  • 安裝的話,就也是一直next就行了,沒什么好說的。好了并打開項目后的效果如下:
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

1.1.3 配置pip源

由于我們后續(xù)需要配置虛擬環(huán)境,安裝相關(guān)依賴包,國內(nèi)下載python非常慢,因此我們需要先配置一下pip鏡像源,具體做法如下:

  1. C:\Users\xxx中創(chuàng)建一個名為pip的文件夾,然后在里面創(chuàng)建一個pip.ini文件,注意后續(xù)需要修改這個文件內(nèi)容,因此可以先把名字改成pip.txt,后續(xù)再改成pip.ini
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
  2. 修改pip.ini文件內(nèi)容,然后保存就可以了,如下:如果還不是很明白的,可以參考一下其他博主的,例如這個教程
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
  1. 后面pip install

1.2 mysql數(shù)據(jù)庫安裝

mysql數(shù)據(jù)庫很多時候會用到,所以最好是安裝配置一下,下面給一個大致的安裝教程

  1. 下載mysql數(shù)據(jù)庫的安裝包
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
    如上圖,選第一個就行啦,解壓之后,就ok,如下圖,最開始是沒有這個my.inidata的好像,不過不重要,官網(wǎng)下下來解壓就完事了,后面再配
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

  2. 配置環(huán)境變量,也就是mysql文件夾下的bin文件夾
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

  3. 在mysqll文件根目錄下創(chuàng)建并配置my.ini

my.ini的配置信息如下,注意把里面的路徑設(shè)置成你自己的就可以了,其他不用改。

[mysqld]
explicit_defaults_for_timestamp=true
character-set-server=utf8mb4
#綁定IPv4和3306端口
bind-address = 0.0.0.0
port = 3306
sql_mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"
default_storage_engine=innodb
innodb_buffer_pool_size=1000M
innodb_log_file_size=50M
# 設(shè)置mysql的安裝目錄
basedir=G:\Program Files\mysql
# 設(shè)置mysql數(shù)據(jù)庫的數(shù)據(jù)的存放目錄
datadir=G:\Program Files\mysql\data
# 允許最大連接數(shù)
max_connections=200
# skip_grant_tables
[mysql]
default-character-set=utf8mb4
[mysql.server]
default-character-set=utf8mb4
[mysql_safe]
default-character-set=utf8mb4
[client]
port = 3306
default-character-set=utf8mb4
plugin-dir=G:\Program Files\mysql\lib\plugin
  1. 打開cmd,輸入mysqld --initialize完成初始化。在根目錄就出現(xiàn)了data文件夾,這下就齊活了。注意初始化的時候,會有一個初始密碼,記得記一下,后面登錄和修改密碼需要用到。
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
  2. 相關(guān)使用
# 安裝mysql服務(wù)
mysqld -install
# 啟動mysql服務(wù)
net start mysql
# 登錄數(shù)據(jù)庫 
mysql -u root -p
# 修改 root 密碼為 root123
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root123';

1.3 相關(guān)依賴安裝

這里我們介紹一下本次項目所需要的依賴和環(huán)境吧。這里我們主要需要用到:首先,numpypandas是數(shù)據(jù)處理的基本庫;其次,一些圖像處理的python庫,cv2Pillow;接著,gui的庫,pyqt5;最后人臉識別的庫,cmakedlibface_recognition?;旧暇褪沁@些吧,如果有問題的話,大家根據(jù)報錯再安裝吧。下面給出一般配置步驟:

  1. 首先在你的項目路徑下cmd中使用conda命令創(chuàng)建虛擬環(huán)境,然后激活一下
# 創(chuàng)建虛擬環(huán)境 名字是face_login python版本是3.8
conda create -n new face_login python=3.8

# 激活虛擬環(huán)境
activate face_login  或者  conda activate face_login
  1. 在你的項目路徑下創(chuàng)建一個文件名叫做requirements.txt,在里面填寫如下信息,版本上似乎是沒有什么大的問題的,按順序裝就可以了,dlib裝起來可能會有些慢如果嫌太慢的話,也可以最后單獨(dú)使用pip install dlib去安裝,但是需要先pip安裝cmake包,不然會出錯的。
numpy
pandas
pyqt5
cmake
opencv-python
Pillow
dlib
face_recognition
  1. 運(yùn)行pip install -r requirements.txt安裝依賴

二、 人臉識別模塊測試

作為人臉識別系統(tǒng)中最重要的模塊,我們需要首先對人臉識別的功能進(jìn)行測試,然后將其作為一個模塊嵌入到我們的系統(tǒng)中即可。人臉識別功能按照流程主要分為兩步,首先是讀取圖片(本地文件夾或者攝像頭);其次是使用人臉識別算法(基于opencv的dnn或者其他深度學(xué)習(xí)框架的人臉識別模型)進(jìn)行人臉檢測和識別。下面分別就上述的兩部分來分別說明。

2.1 使用opencv從攝像頭中讀取圖片

從opencv中讀取圖片主要分為三種,下面分別給出三種方式的代碼:

2.1.1 opencv讀取圖片/攝像頭的視頻幀

  • 讀取單張圖片
# 單張圖片讀取
import cv2
img_filename = 'demo.png'
img = cv2.imread(img_filename, cv2.IMREAD_COLOR) # 彩色圖像
# img = cv2.imread(img_filename, cv2.IMREAD_GRAYSCALE) # 灰度圖像
  • 讀取文件夾中的圖片
# 從文件夾讀取
import glob
import cv2
img_dir = r'path/to/your/database'
for img_filename in glob.glob(img_dir + '/*.jpg' ) # 針對jpg圖片
	img = cv2.imread(img_filename, cv2.IMREAD_COLOR)
  • 讀取攝像頭中的視頻幀
import cv2

def get_cap():
    cap = cv2.VideoCapture(0)
    return cap
    
cap = get_cap() # 獲取攝像頭視頻流
id = 1
while True:
    ret, frame = cap.read()
    if cv2.waitKey(1) == ord('q'):#按Q退出
        img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        img = cv2.resize(img, (480, 480))
        # img = np.array(img)
        break
    else:
        cv2.imshow('win', frame)
cv2.waitKey(10) # 可以理解為控制幀率

2.1.2 opencv將圖像保存為gif和視頻

有的時候,我們甚至還需要展示,那么就需要一個視頻流保存為視頻文件、圖片轉(zhuǎn)gif或者圖像轉(zhuǎn)視頻的需求,下面同樣給出這幾種操作的示例代碼:

  • 視頻流保存視頻文件參考
    需要注意的是,盡量按照攝像頭的編碼來保存視頻,否則可能會出問題。
    cv2.VideoWriter_fourcc('I','4','2','0'):YUV編碼,4:2:0色度子采樣。這種編碼廣泛兼容,但會產(chǎn)生大文件。文件擴(kuò)展名應(yīng)為.avi。
    cv2.VideoWriter_fourcc('P','I','M','1'):MPEG-1編碼。文件擴(kuò)展名應(yīng)為.avi。
    cv2.VideoWriter_fourcc('X','V','I','D'):MPEG-4編碼。如果要限制結(jié)果視頻的大小,這是一個很好的選擇。文件擴(kuò)展名應(yīng)為.avi。
    cv2.VideoWriter_fourcc('m', 'p', '4', 'v'):較舊的MPEG-4編碼。如果要限制結(jié)果視頻的大小,這是一個很好的選擇。文件擴(kuò)展名應(yīng)為.m4v。
    cv2.VideoWriter_fourcc('X','2','6','4'):較新的MPEG-4編碼。如果你想限制結(jié)果視頻的大小,這可能是最好的選擇。文件擴(kuò)展名應(yīng)為.mp4。
    cv2.VideoWriter_fourcc('T','H','E','O'):這個選項是Ogg Vorbis。文件擴(kuò)展名應(yīng)為.ogv。
    cv2.VideoWriter_fourcc('F','L','V','1'):此選項為Flash視頻。文件擴(kuò)展名應(yīng)為.flv。
def save_video(video_name):
    cap = cv2.VideoCapture(video_name)
    # setting
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 獲取原視頻的寬
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 獲取原視頻的搞
    fps = int(cap.get(cv2.CAP_PROP_FPS))  # 幀率
    fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))  # 視頻的編碼

    # 定義視頻保存的輸出屬性
    out = cv2.VideoWriter('out.mp4', fourcc, fps, (width, height))
    while cap.isOpened():
        ret, frame = cap.read()
        cv2.imshow('fame', frame)
        key = cv2.waitKey(25)

        out.write(frame)  

        if key == ord('q'):
            break
    cap.release()  
    out.release()
    cv2.destroyAllWindows() 

  • 圖片轉(zhuǎn)gif
import cv2
import imageio

def save_gif(video_name):
    cap = cv2.VideoCapture(video_name)

    # 定義視頻保存的輸出屬性
    out = []
    while cap.isOpened():
        ret, frame = cap.read()
        cv2.imshow('fame', frame)
        key = cv2.waitKey(15)

        if not ret: continue
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        out.append(cv2.resize(frame, (w//2, h//2))) # 適當(dāng)縮放,防止gif過大

        if key == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

    imageio.mimsave('demo.gif', out, fps=30) # 調(diào)整保存的幀率

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

  • 圖片轉(zhuǎn)視頻
import cv2
import os

def img2video(img_dir, save_name):
    # setting
    width = 1080 # 獲取原視頻的寬
    height = 720  # 獲取原視頻的搞
    fps = 30  # 幀率
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')  # 視頻的編碼

    # 定義視頻保存的輸出屬性
    out = cv2.VideoWriter(save_name, fourcc, fps, (width, height))

    for r, ds, fs in os.walk(img_dir):
        for f in fs:
            file_name = os.path.join(r, f)
            img = cv2.imread(file_name)
            out.write(img)
	return

2.2 使用不同人臉識別算法進(jìn)行檢測和識別

人臉識別最簡單的就是使用dlib框架,其檢測流程如下圖所示:
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

2.2.1 模型加載

這里需要加載三個模型,分別是人臉檢測模型、人臉關(guān)鍵點(diǎn)預(yù)測模型、描述子特征計算模型,人臉檢測模型直接調(diào)用dlib的dlib.get_frontal_face_detector()即可,另外兩個可以直接從dlib的官網(wǎng)下載對應(yīng)的兩個模型:

  1. shape_predictor_68_face_landmarks.dat
  2. dlib_face_recognition_resnet_model_v1.dat

2.2.2 讀取圖片

讀取圖片直接使用2.1所講的就可以了,不再贅述。

2.2.3 人臉檢測和關(guān)鍵點(diǎn)提取

import dlib

def detect_img():
    cap = cv2.VideoCapture(0)
    detector = dlib.get_frontal_face_detector() # 檢測模型
    path_pre = "../models/shape_predictor_68_face_landmarks.dat"  # 68點(diǎn)模型
    pre = dlib.shape_predictor(path_pre)

    # 定義視頻保存的輸出屬性
    out = []
    while cap.isOpened():
        ret, frame = cap.read()
        key = cv2.waitKey(15)
        if not ret: continue
        rects = detector(frame, 0)

        for obj in rects: # 繪制所有的人臉
            # print(dir(obj))
            pt1, pt2 = rect2bb(obj)
            cv2.rectangle(frame, pt1, pt2, (0, 255, 0), 2)

            shapes = pre(frame, obj) # 對當(dāng)前的人臉框做68點(diǎn)特征點(diǎn)預(yù)測
            shapes = shape_to_np(shapes)
            for (x, y) in shapes:
                cv2.circle(frame, (x, y), 1, (255, 0, 0), -1)

        cv2.imshow('fame', frame)

        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        h, w, c = frame.shape
        out.append(cv2.resize(frame, (w//2, h//2)))
        if key == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

    imageio.mimsave('demo.gif', out, fps=20)

可以發(fā)現(xiàn),上述代碼中有兩個函數(shù)沒有定義,rect2bbshape_to_np。由于dlib的輸出是個自定義的類,雖然print可以獲取他的rect信息,但是我們不能直接傳給cv2.rectangle,因此我們需要對dlib推理得到的rects和shapes重新處理從而方便處理:

def rect2bb(rect):

    x1 = rect.left()
    y1 = rect.top()
    x2 = rect.right()
    y2 = rect.bottom()

    return (x1, y1), (x2, y2)

def shape_to_np(shape):
    coords = np.zeros((68, 2), dtype=int)
    for i in range(0, 68):
        coords[i] = (shape.part(i).x, shape.part(i).y)
    return coords

通過這個demo,我們可以獲取到下面的檢測結(jié)果,看起來還可以hhh。
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

2.2.4 描述子匹配

通過上述例子,我們已經(jīng)完成了人臉檢測和關(guān)鍵點(diǎn)估計,那么如何進(jìn)行人臉的匹配,也就是說怎么將當(dāng)前人臉和我們數(shù)據(jù)庫里面的人臉進(jìn)行匹配呢?我認(rèn)為主要分為以下幾個步驟:

  1. 創(chuàng)建一個人臉數(shù)據(jù)集
    這里我們可以按照學(xué)號或者按照人名將人臉數(shù)據(jù)分文件夾放置,如下圖所示:
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
    使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

每個人的文件夾下放置該人不同姿態(tài)下的人臉圖片,用來作為原始的圖片數(shù)據(jù)集,但其實(shí)匹配的過程中我們往往不太直接用數(shù)據(jù)庫中的原圖,因?yàn)?code>計算特征是耗時的,因此更為合適的做法是,將數(shù)據(jù)庫中的圖片提前進(jìn)行人臉識別、特征點(diǎn)檢測和特征提取,產(chǎn)生一個特征數(shù)據(jù)集替代這一原始圖片的數(shù)據(jù)集,如下圖所示:
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

  1. 分別計算未知人臉特征和數(shù)據(jù)庫中的人臉特征

    顧名思義,我們需要在2.2.3中的代碼的基礎(chǔ)上,完成人臉特征提取,代碼如下:

def load_model():
    detector = dlib.get_frontal_face_detector()
    path_pre = "../models/shape_predictor_68_face_landmarks.dat"  # 68點(diǎn)模型
    pre = dlib.shape_predictor(path_pre)

    path_model = "../models/dlib_face_recognition_resnet_model_v1.dat"  # resent模型
    model = dlib.face_recognition_model_v1(path_model)

    return detector, pre, model


def get_describe_for_face(detector, pre, model, img):
    det_img = detector(img, 0)
    try:
        shape = pre(img, det_img[0])
        know_encode = model.compute_face_descriptor(img, shape)
    except:
        return -1
    return know_encode

# 獲取待檢測圖片的encode
unknown_encod = get_describe_for_face(detector, pre, model, unknown_img)

上面我們給出了計算未知人臉特征的代碼,而數(shù)據(jù)庫中的已知人臉數(shù)據(jù)我們同樣需要進(jìn)行特征提取,正如前面2.2.4第一步所說,我們需要提前預(yù)處理數(shù)據(jù)集中的特征,保存為一個類似face_fea_database的數(shù)據(jù)集備用。這里給出批處理獲取特征的參考代碼:

import os
import pickle
import numpy as np
from PIL import Image

def Eu(a, b):  # 距離函數(shù)
    return np.linalg.norm(np.array(a) - np.array(b), ord=2)

face_dir = '../face_database'
face_feature_dir = '../face_fea_database'
unknown_img = np.array(Image.open('../face_database/20221000/1.jpg'))

detector, pre, model = load_model()
unknown_fea = get_describe_for_face(detector, pre, model, unknown_img)

for id in os.listdir(face_dir):
    face_path = os.path.join(face_dir, id)
    face_fea_path = os.path.join(face_feature_dir, id)
    os.makedirs(face_fea_path, exist_ok=True)
    for img_name in os.listdir(face_path):
        img_path = os.path.join(face_path, img_name)
        fea_path = os.path.join(face_fea_path, img_name.replace('.jpg', '.ft'))
        img = np.array(Image.open(img_path))
        img_feature = get_describe_for_face(detector, pre, model, img)
        with open(fea_path, 'wb') as f:
            pickle.dump(img_feature, f)

        with open(fea_path, 'rb') as f:
            data = pickle.load(f)

        print("save and load result is same? ", Eu(img_feature, unknown_fea) == Eu(data, unknown_fea))

  1. 將未知人臉和數(shù)據(jù)庫中的人臉進(jìn)行匹配
    匹配這部分我們需要定義我們自己的匹配規(guī)則,這里我使用的是將未知了雙閾值篩選,如果兩個人臉特征差距太大,那么就跳過;如果兩個人臉的差距很小,那么直接返回結(jié)果;介于倆個閾值之間的,就放在一個list中,最后按照距離排序,返回距離最小的人臉?biāo)鶎?yīng)的人員屬性。

下面給出macth部分的函數(shù)代碼:

def record_status(status, name=None):
    f = open('../recog_status.txt', 'w', encoding='utf-8')
    if status == 3: # 打卡成功
        info = STATUS_DICT[status] + name
    else:
        info = STATUS_DICT[status]
    f.write(info)
    f.close()

def match_face_by_face_recognize(unknown_img, face_dir, stu_lists, thres=0.4, min_thres=0.55):

    MODEL_STATUS = 1
    record_status(MODEL_STATUS)

    # detector, pre, model = load_model()

    MODEL_STATUS = 2
    record_status(MODEL_STATUS)
    # 獲取待檢測圖片的encode
    unknown_encod = face_recognition.face_encodings(unknown_img)

    if unknown_encod == []:
        record_status(4)
        print('無法識別攝像頭中的人臉')
        return -1, 'Unknown'
    else:
        unknown_encod = unknown_encod[0]

    stus_conf = {stu[0]:[stu[1], 2] for stu in stu_lists}
    for id, name in stu_lists:
        # 獲取當(dāng)前學(xué)生的人臉地址
        stu_face_dir = os.path.join(face_dir, str(id))
        for img_name in os.listdir(stu_face_dir):
            img_path = os.path.join(stu_face_dir, img_name)

            # func1. use dlib to get encode if necessary
            # img = np.array(Image.open(img_path))
            # know_encode = get_describe_for_face(detector, pre, model, img)

            # func2. use feature prepared by utils.prepare_feature.py
            f = open(img_path, 'rb')
            know_encode = pickle.load(f)

            # func3. use face recognize
            # img = face_recognition.load_image_file(img_path)
            # know_encode = face_recognition.face_encodings(img)

            if know_encode == []:
                record_status(4)
                print('無法識別人臉庫中的人臉')
                return -1, 'Unknown' # 人臉庫一般不存在這種情況!??!必須保證高質(zhì)量人臉
            else:
                know_encode = know_encode[0]

            # 如果檢測到差距小于閾值,認(rèn)為檢測成功, 退出
            distance = Eu(know_encode, unknown_encod)

            if distance > min_thres: break # 這個人必然不是
            else:
                if distance < thres: # 閾值很小了
                    MODEL_STATUS = 3
                    record_status(MODEL_STATUS, name)
                    return id, name
                else: # 閾值一般
                    stus_conf[id][1] = min(stus_conf[id][1], distance)
    # print(stus_conf)
    res = sorted(stus_conf.items(), key=lambda x:x[1][1])[0]
    print(res)

    id, (name, conf) = res
    if conf > min_thres:
        MODEL_STATUS = 4
        record_status(MODEL_STATUS)
        return -1, 'Unknown'
    else:
        MODEL_STATUS = 3
        record_status(MODEL_STATUS, name)
        return id, name

if __name__ == '__main__':
    cap = get_cap()
    id = 1
    while True:
        ret, frame = cap.read()
        if cv2.waitKey(1) == ord('q'):#按Q退出
            img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            img = cv2.resize(img, (480, 480))
            # img = np.array(img)
            break
        else:
            cv2.imshow('win', frame)

    stu_lists = [(20221001, '錢全'), (20221002, '葛娟'), (20221003, '衛(wèi)雅'), (20221004, '王寧'), (20221005, '韓惠'),
                 (20221006, '鄒慧')]
    detector, pre, model = load_model()
    result = match_face(img, '../face_fea_database', stu_lists, detector, pre, model)
    print(result)

其實(shí)從上面的代碼上可以看出,我們其實(shí)還有一種快速提取圖像特征的方式,那就是使用face_recognize這個庫,代碼如下,但速度上肯定還是加載預(yù)處理得到的特征文件(第二種方法)更快。

func3. use face recognize
img = face_recognition.load_image_file(img_path)
know_encode = face_recognition.face_encodings(img)

三、 基于sqlite3的數(shù)據(jù)庫設(shè)計

數(shù)據(jù)庫本身不是這個項目的重點(diǎn),因此這里淺淺地使用一下python自帶的sqlite3數(shù)據(jù)庫,這里我只簡單地定義了一些必要的類,因?yàn)檫@是一個人臉打卡系統(tǒng),因此不免就需要有學(xué)生、課程、打卡信息以及選課信息表。

3.1 簡單定義數(shù)據(jù)庫類

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
先定義一個數(shù)據(jù)庫的類,用來管理我們的數(shù)據(jù),包括數(shù)據(jù)的導(dǎo)入、數(shù)據(jù)的讀取和數(shù)據(jù)的更新等等,通過一個類的方式來進(jìn)行數(shù)據(jù)庫的操作更為清晰和直觀一些。E-R圖這里就不畫了,這個任務(wù)也比較簡單吧,簡化起見就設(shè)計了四個表,具體內(nèi)容下面詳細(xì)敘述。

3.1.1 CardRecord 打卡信息表

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

3.1.2 Course 課程表

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

3.1.3 Relation 選課關(guān)系表

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

3.1.4 Student 學(xué)生表

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

對于選擇困難的人而言起名字真的很痛苦,為了快速生成不同學(xué)生名和課程名,我使用了隨機(jī)拼接的方式生成csv文件,后面在導(dǎo)入數(shù)據(jù)庫,這里只給出csv的生成代碼,大家可以根據(jù)需要選擇和修改:

def random_get_datas():
    import random
    start_id = 20221000
    firstName = "趙錢孫李周吳鄭王馮陳褚衛(wèi)蔣沈韓陶姜戚謝鄒喻水云蘇潘葛奚范彭"
    lastName = "秀娟英華慧巧美娜靜淑惠珠翠雅力明永健寧貴福生龍元全國勝學(xué)祥才"
    stu_infos, class_infos = [], []
    with open('student.csv', 'w', encoding='utf-8') as f:
        f.writelines('id,name,age,details\n')
        for i in range(10):
            id, name, age, details = start_id, \
                                     random.choice(firstName) + random.choice(lastName), \
                                     random.randint(18, 24), \
                                     "喜歡" + random.choice(['足球', '籃球', '排球'])

            start_id += 1
            f.writelines("{},{},{},{}\n".format(id, name, age, details))
            stu_infos.append((id, name, age, details))

    with open('class.csv', 'w', encoding='utf-8') as f:
        f.writelines('id,name,status\n')
        start_id = 19334
        firstName = ['高等','基礎(chǔ)' ,'線性' ,'隨機(jī)' ]
        lastName = ['數(shù)學(xué)', '物理', '信號分析']
        for i in range(4):
            id, name, status = start_id, \
                                   random.choice(firstName) + random.choice(lastName), \
                                   1

            start_id += 1
            f.writelines("{},{},{}\n".format(id, name, status))
            class_infos.append((id, name, status))

    with open('relation.csv', 'w', encoding='utf-8') as f:
        id = 0
        f.writelines("id,stu_id,course_id,create_time\n")
        for classes in class_infos:
            a, b = random.randint(0, 4), random.randint(5, len(stu_infos))
            for stu in stu_infos[a:b]:
                time = "2022-5-" + str(random.randint(1, 10))
                f.writelines("{},{},{},{}\n".format(id, stu[0], classes[0], time))
                id += 1

    print('random init success.')

從csv導(dǎo)入sqlite還是挺容易的,示例代碼如下,其中conn = sqlite3.connect(self.db_path)

def get_class_from_csv(self, csv_file):
    df = pd.read_csv(csv_file)
    try:
        df.to_sql('Course', self.conn, if_exists='append', index=False)
    except Exception as e:
        print(e)
    finally:
        print("導(dǎo)入成功")

3.2 封裝常用的sql查詢到數(shù)據(jù)庫類成員函數(shù)中

這個也比較基本,把一些常用的查詢函數(shù)集成到database類里

def get_courses(self):
    # 返回課程編號和名稱
    sql = '''
        select * from Course where status == 1;
    '''
    curr = self.conn.cursor()
    curr.execute(sql)

    return [item[:2] for item in curr.fetchall()]

def get_stu_info(self):
    sql = '''
        select * from student;
    '''
    curr = self.conn.cursor()
    curr.execute(sql)

    return {item[0]:item[1:] for item in curr.fetchall()}


def get_stus_by_course(self, course_id):
    # 返回課程編號和名稱
    sql = '''
        select Student.id, Student.name from Student, Relation  where Relation.course_id == ? and Student.id == Relation.stu_id
    '''
    curr = self.conn.cursor()
    curr.execute(sql, [course_id])

其實(shí)這里面我寫的也比較簡單,拋磚引玉,大家可以參照類似的方式把一些功能sql語句寫入函數(shù)中,方便調(diào)用。

四、 基于PyQt5的GUI設(shè)計

GUI設(shè)計這部分的話,主要就是一個交互的作用,大家根據(jù)自己的熟悉程度選擇不同的框架,python客戶端主要就是tkinterpyqt5吧,熟悉前后端框架的也可以用html+css+js+django/flask之類的解決。我之前做過pyqt5的客戶端,算是比較熟悉吧,這里也就用pyqt5為例來說明一下吧。
想使用pyqt5的同志們,處理要安裝基本的pyqt5的python庫,為了方便開展GUI設(shè)計,最好可以配置一下三件套,也就是:

  • qt designer :把GUI設(shè)計變得更簡單,可以理解為可以把組件拖來拖去,完成框架設(shè)計的軟件。
  • pyrcc:把pyqt5界面所引用的多個資源轉(zhuǎn)換為一個二進(jìn)制文件,方便使用,不用在去一個個文件調(diào)用。
  • pyuic:pyqt5的GUI文件是.ui文件,這個工具可以把ui文件轉(zhuǎn)py文件,供我們做類的復(fù)用。

這里我就不贅述這三個玩意的配置和用法啦,如果大家感興趣,我在專門搞一篇講解吧 ~

4.1 框架和文件夾結(jié)構(gòu)設(shè)計

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
下面我講一下gui文件的結(jié)構(gòu)吧,其實(shí)做任何pyqt5的應(yīng)用,都是大同小異的,在你的主目錄下,可以創(chuàng)建一個resource文件夾,里面分別創(chuàng)建一個UI文件夾和一個images文件夾;

  • UI主要就存放了你的不同界面的ui源文件,以及你用pyuic轉(zhuǎn)換好的py文件(花括號括起來的),轉(zhuǎn)換后的py文件其實(shí)就是你在qt designer中設(shè)計的那個面板對應(yīng)的py類定義和實(shí)現(xiàn),你后面可以直接繼承這個類然后再做一些邏輯,包括信號和槽函數(shù)的實(shí)現(xiàn)。
  • images 主要存一些你的圖片資源文件,資源文件最后保存在.qrc中,后面通過pyrcc可以將資源文件轉(zhuǎn)為images_rc.py,方便后面使用。當(dāng)然,如果你有一些音頻數(shù)據(jù),也可以按照類似的方式創(chuàng)建。

剩下的文件夾和定義就隨意啦 ~ 最好是整一個main文件,然后在里面完成不同界面的跳轉(zhuǎn)和交互,這樣比較清晰直觀,界面之間盡量解耦,依賴低一些。

4.2 開始界面設(shè)計

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
如上圖所示,其實(shí)可以看出,開始界面的組成比較簡單,就是一些按鈕、label和組合框的堆疊,主要就是為了顯示我們的軟件名,增加選擇框?qū)φn程進(jìn)行選擇,考勤時間的選擇,界面切換按鈕和自定義的最小化,最大化按鈕(qt自帶的很丑hhh)

你只需要選擇合適的widget(布局),把這些組織在一起就好啦。對于初學(xué)的同學(xué)不需要關(guān)心太多,我覺得你只要把想要的組件放進(jìn)去,然后哪怕是固定他們的位置呢,只要能用,就是勝利;這里要說的話就有點(diǎn)多了哈哈哈。如果你要自己設(shè)計的話,那么就就點(diǎn)擊左上角的file,按如下的創(chuàng)建就可以啦,然后在左邊選則不同的組件,拖過去就ok啦。

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

大家回頭配置好了qt designer,可以打開我的ui文件,看看具體的布局設(shè)計等等,其實(shí)想要把qt弄得好看一些還是需要費(fèi)一些功夫的,qt的qss感覺相比于css還是差點(diǎn)意思,所以一些圓角設(shè)計、配色和鼠標(biāo)事件下,控件的變化想變得絲滑還是需要大家費(fèi)點(diǎn)心思。

4.3 驗(yàn)證界面設(shè)計

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
驗(yàn)證界面還是挺簡單的,其實(shí)就是為了防止同學(xué)們或者非管理員瞎玩開始界面和導(dǎo)出打開數(shù)據(jù),因此需要驗(yàn)證身份,也比較簡單吧,就只需要輸入密碼,然后驗(yàn)證或者返回就ok。

4.4 自定義的listwidget設(shè)計

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
這里設(shè)計這個listwidget的目的其實(shí)是為了顯示打卡人的頭像、姓名、學(xué)號和打卡信息,把他放在一個listwidget里面,但是qt并沒有一個基本組件可以滿足這一需求,因此我們可以設(shè)計一個form,然后把他嵌入到listwidget里面就ok啦,當(dāng)然后面如何對listwidget的元素進(jìn)行狀態(tài)更新和排序,也是有一些細(xì)節(jié)的,這里不贅述,大家感興趣可以從我的代碼中找到答案。
使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

4.4 主界面設(shè)計

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)
主界面應(yīng)該是最復(fù)雜的,但其實(shí)也只是相對復(fù)雜,我按照上述的8部分來敘述吧:

  1. 打卡面板:
  2. 狀態(tài)顯示欄
  3. 剩余時間顯示:
  4. 打卡進(jìn)度更新:
  5. 自定義打卡人物和狀態(tài)顯示:
  6. 攝像頭和打卡:
  7. 數(shù)據(jù)導(dǎo)出:
  8. 界面跳轉(zhuǎn):

4.5 如何有效組織不同的UI界面類

五、效果展示

5.1 檢測和識別效果展示

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)

5.2 數(shù)據(jù)庫導(dǎo)出和查看

六、代碼獲取和下載

完整項目代碼放在了我的公眾號:百年后封筆,
大家回復(fù) “人臉打卡系統(tǒng)”,即可免費(fèi)獲取完整代碼的下載鏈接!

創(chuàng)作不易,也歡迎大家批評指正,動動小手,評論,收藏一哈!

我也會繼續(xù)不定期更新感興趣的項目~文章來源地址http://www.zghlxwxcb.cn/news/detail-513845.html

到了這里,關(guān)于使用python和pyqt5輕松上手人臉識別系統(tǒng)(含代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 基于PyQt5GUI的人臉識別系統(tǒng)設(shè)計與實(shí)現(xiàn)

    基于PyQt5GUI的人臉識別系統(tǒng)設(shè)計與實(shí)現(xiàn)

    目 錄 前 言 1 第 1 章 人臉識別系統(tǒng)概述 1 第 2 章 人臉檢測技術(shù) 1 §2.1 基于 Harr 級聯(lián)的人臉檢測 2 §2.2 基于 face_recognition 開源庫的人臉檢測… 錯誤!未定義書簽。第 3 章 人臉識別技術(shù) 5 §3.1 構(gòu)造人臉數(shù)據(jù)集 5 §3.2 模型訓(xùn)練 7 §3.3 實(shí)時人臉識別 9 第 4 章 基于 PyQt5 的應(yīng)用平臺 1

    2024年02月04日
    瀏覽(27)
  • 基于opencv和PyQt5的人臉識別

    基于opencv和PyQt5的人臉識別

    目? ? 錄 一、準(zhǔn)備工作 二、分割任務(wù) 三、代碼實(shí)現(xiàn)階段 1、基于opencv讀取照片 2、在圖片上繪制矩形 3、在讀取照片成功的前提下理解視頻的本質(zhì),讀取視頻 4、在視頻上繪制矩形 5、調(diào)用人臉識別模塊 ?6、動態(tài)調(diào)整矩形,讓矩形通過人臉識別算法追蹤人臉 7、調(diào)用Qt組件,創(chuàng)

    2024年02月03日
    瀏覽(17)
  • python、pyqt5實(shí)現(xiàn)人臉檢測、性別和年齡預(yù)測

    python、pyqt5實(shí)現(xiàn)人臉檢測、性別和年齡預(yù)測

    摘要:這篇博文介紹基于opencv:DNN模塊自帶的殘差網(wǎng)絡(luò)的人臉、性別、年齡識別系統(tǒng),系統(tǒng)程序由OpenCv, PyQt5的庫實(shí)現(xiàn)。如圖系統(tǒng)可通過攝像頭獲取實(shí)時畫面并識別其中的人臉表情,也可以通過讀取圖片識別,本文提供完整的程序文件并詳細(xì)介紹其實(shí)現(xiàn)過程。博文要點(diǎn)如下:

    2024年02月07日
    瀏覽(34)
  • 基于YOLOv8深度學(xué)習(xí)的100種蝴蝶智能識別系統(tǒng)【python源碼+Pyqt5界面+數(shù)據(jù)集+訓(xùn)練代碼】目標(biāo)檢測、深度學(xué)習(xí)實(shí)戰(zhàn)

    基于YOLOv8深度學(xué)習(xí)的100種蝴蝶智能識別系統(tǒng)【python源碼+Pyqt5界面+數(shù)據(jù)集+訓(xùn)練代碼】目標(biāo)檢測、深度學(xué)習(xí)實(shí)戰(zhàn)

    《博主簡介》 小伙伴們好,我是阿旭。專注于人工智能、AIGC、python、計算機(jī)視覺相關(guān)分享研究。 ? 更多學(xué)習(xí)資源,可關(guān)注公-仲-hao:【阿旭算法與機(jī)器學(xué)習(xí)】,共同學(xué)習(xí)交流~ ?? 感謝小伙伴們點(diǎn)贊、關(guān)注! 《------往期經(jīng)典推薦------》 一、AI應(yīng)用軟件開發(fā)實(shí)戰(zhàn)專欄【鏈接】

    2024年01月25日
    瀏覽(148)
  • 基于YOLOv8深度學(xué)習(xí)的102種花卉智能識別系統(tǒng)【python源碼+Pyqt5界面+數(shù)據(jù)集+訓(xùn)練代碼】目標(biāo)檢測、深度學(xué)習(xí)實(shí)戰(zhàn)

    基于YOLOv8深度學(xué)習(xí)的102種花卉智能識別系統(tǒng)【python源碼+Pyqt5界面+數(shù)據(jù)集+訓(xùn)練代碼】目標(biāo)檢測、深度學(xué)習(xí)實(shí)戰(zhàn)

    《博主簡介》 小伙伴們好,我是阿旭。專注于人工智能、AIGC、python、計算機(jī)視覺相關(guān)分享研究。 ? 更多學(xué)習(xí)資源,可關(guān)注公-仲-hao:【阿旭算法與機(jī)器學(xué)習(xí)】,共同學(xué)習(xí)交流~ ?? 感謝小伙伴們點(diǎn)贊、關(guān)注! 《------往期經(jīng)典推薦------》 一、AI應(yīng)用軟件開發(fā)實(shí)戰(zhàn)專欄【鏈接】

    2024年01月21日
    瀏覽(173)
  • 基于YOLOv8深度學(xué)習(xí)的智能車牌檢測與識別系統(tǒng)【python源碼+Pyqt5界面+數(shù)據(jù)集+訓(xùn)練代碼】目標(biāo)檢測、深度學(xué)習(xí)實(shí)戰(zhàn)

    基于YOLOv8深度學(xué)習(xí)的智能車牌檢測與識別系統(tǒng)【python源碼+Pyqt5界面+數(shù)據(jù)集+訓(xùn)練代碼】目標(biāo)檢測、深度學(xué)習(xí)實(shí)戰(zhàn)

    《博主簡介》 小伙伴們好,我是阿旭。專注于人工智能、AIGC、python、計算機(jī)視覺相關(guān)分享研究。 ? 更多學(xué)習(xí)資源,可關(guān)注公-仲-hao:【阿旭算法與機(jī)器學(xué)習(xí)】,共同學(xué)習(xí)交流~ ?? 感謝小伙伴們點(diǎn)贊、關(guān)注! 《------往期經(jīng)典推薦------》 一、AI應(yīng)用軟件開發(fā)實(shí)戰(zhàn)專欄【鏈接】

    2024年02月20日
    瀏覽(101)
  • 打架識別(AI+Python+PyQt5)(一)

    打架識別(AI+Python+PyQt5)(一)

    ????????最近做了一個打架識別的項目,有感于當(dāng)時開發(fā)資料的匱乏,特做一個小結(jié),供大家參考。閑話少敘,看看效果先。? ? ? ? ? ? ? ? ? ? ? ????????目前打架檢測,主要有3種主流的方法,分別是: (1)基于Detection的打架檢測。其主要思想是: 將打架作為一種

    2023年04月08日
    瀏覽(16)
  • [python]使用pyqt5搭建yolov8 竹簽計數(shù)一次性筷子計數(shù)系統(tǒng)

    [python]使用pyqt5搭建yolov8 竹簽計數(shù)一次性筷子計數(shù)系統(tǒng)

    【官方框架地址】 github地址:https://github.com/ultralytics/ultralytics 【算法介紹】 Yolov8是一種先進(jìn)的深度學(xué)習(xí)算法,用于目標(biāo)檢測任務(wù),特別是針對圖像中物體的實(shí)時檢測。它是Yolov3和Yolov4之后的又一重要迭代,帶來了諸多改進(jìn)和新特性。本文將詳細(xì)介紹Yolov8算法的原理、特點(diǎn)、

    2024年04月10日
    瀏覽(99)
  • 基于深度學(xué)習(xí)mediapipe的人臉打碼人臉模糊教程pyqt5界面附源碼

    基于深度學(xué)習(xí)mediapipe的人臉打碼人臉模糊教程pyqt5界面附源碼

    人臉識別是一門比較成熟的技術(shù)。 它的身影隨處可見,刷臉支付,信息審核,監(jiān)控搜索,人臉打碼等。 更多的時候,它是方便了我們的生活,足不出戶,就可以實(shí)現(xiàn)各種 APP 的實(shí)名認(rèn)證,信息審核。 一些公司,也都有對內(nèi)部員工開放的刷臉支付系統(tǒng),不用帶手機(jī),不用帶工

    2024年02月02日
    瀏覽(44)
  • 是否佩戴安全帽識別從零開始使用YOLOv5+PyQt5+OpenCV實(shí)現(xiàn)

    是否佩戴安全帽識別從零開始使用YOLOv5+PyQt5+OpenCV實(shí)現(xiàn)

    全流程 教程,從數(shù)據(jù)采集到模型使用到最終展示。若有任何疑問和建議歡迎評論區(qū)討論。 先放上最終實(shí)現(xiàn)效果 檢測效果 在施工現(xiàn)場,對于來往人員,以及工作人員而言,安全問題至關(guān)重要。而安全帽更是保障施工現(xiàn)場在場人員安全的第一防線,因此需要對場地中的人員進(jìn)行

    2024年02月03日
    瀏覽(46)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包