樹莓派3B+、opencv3+PyQt5實現人臉識別門禁系統

前言

總結、乾貨、知識點、注意實現。無個人背景(別人不會關心,捂臉)

效果展示

沒點效果,沒興趣往下看了吧(反正我是這樣)

下面是兩個界面:主頁和人臉檢測界面,主頁可以密碼鎖、以及其他操作(自己按需),另一個界面是人臉檢測的界面。

在這裏插入圖片描述
在這裏插入圖片描述

人臉錄入:

在這裏插入圖片描述

開始檢測:

在這裏插入圖片描述

識別成功之後就可以發指令控制步進電機轉動控制門鎖了

材料

樹莓派3B+ 一塊

USB攝像頭 一個

3.5寸LCD顯示屏(帶觸控)

HMDI接口的顯示器(你去試試在3.5寸顯示屏上面debug?)(或者試試ssh,下文逮到機會就說說一下)

飛鼠鍵盤(看個人興趣)

在這裏插入圖片描述

準備

電腦上

在電腦上先把程序跑通再移植到樹莓派上部署,我再pycharm上面把程序跑通(代碼在後頭)

pychram上安裝opencv的庫 opencv-python庫、opencv-contrib-python庫、PyQt5庫、pyqt-tools庫(這個是用來在qtdesinger拉控件,佈置界面的,還有將ui界面轉換成py文件),pycharm安裝庫看此鏈接

注意:

opencv-python庫、opencv-contrib-python庫這兩個庫的版本要一致。opencv-contrib-python庫是opencv-python庫的升級版,人臉識別的算法再裏面。就是opencv-python庫中有的,opencv-conteib-python庫中都有,opencv-contrib-python庫中有的opencv-python庫中不一定有。安裝opencv-contrib-python庫就行了理論上,我沒試過,可以試試,不然就兩個都安裝吧,反正不大。

樹莓派上

1.裝系統,網上很多教程,自己搞定。

2.裝完,先換源,換成清華源吧。

3.sudo apt-get update 一下

4.裝個輸入法吧,推薦谷歌輸入法,scim輸入法用起來沒有谷歌的好用

5.sudo apt-get install python3-opencv 安裝到底就行了,我的樹莓派系統是2019.7.15的版本,自帶PyQt5,我試過確實不用安裝。在終端上試試,python3 ,回車,之後

import PyQt5
import cv2

用這個方法看opencv是否可以用了,以及QT是否可以用如果沒有顯示其他問題,說明不用去安裝PyQt5了。

  1. 3.5寸顯示屏和HDMI顯示器總要切換吧,3.5寸上看看效果,安裝3.5寸顯示屏的驅動參考這個

安裝後你可以寫個腳本控制這兩種顯示屏切換,比較方便

在終端上,安裝vim,或者用自帶nano 寫一個腳本文件

1.sudo vim screen_choose.sh 這樣就會生成一個腳本文件

2.按i 插入,把下面的寫入到腳本中 ,

3.按esc退出編輯,

4.保存 輸入:wq! 回車

5.sudo chmod 777 screen_choose.sh 權限設置

#!/bin/bash
echo $1
if [ $1 == 0 ]
then
	echo "5秒後切換成3.5寸顯示屏。。。"
	sleep 5s
	echo "開始切換。。。"
	sleep 1s
	cd /這裏放你驅動解壓後的路徑/
	./LCD35-show
elif [ $1 == 1 ]
then 
	echo "5秒後切換成HMDI顯示器。。。"
	sleep 5s
	echo "開始切換。。。。"
	sleep 1s
	cd /這裏的路徑和上面一樣,你解壓後的路勁/
	./LCD-hdmi
fi

之後,在終端輸入 ./screen_choose.sh 0 切換成3.5寸顯示器,./screen_choose.sh 1切換成HDMI顯示屏。

用了什麼算子

流程

1.識別人臉,即人臉檢測

2.視頻中的人臉檢測,即一幀一幀的人臉檢測

3.錄入人臉,即roi,把感興趣的區域保存起來,存到對應文件夾

4.應用人臉識別算法,人臉識別,畫框貼標籤

5.PyQt5,佈局設計

6.將界面與人臉識別鏈接起來

7.調試,部署到樹莓派上

Haar級聯分類器

這個分類器,通過對比分析相鄰圖像區域來判斷給定圖像或子圖像與已知對象是否匹配。這裏與圖像特徵的檢測、識別計算有些關係。這裏這個分類器,根據我們要識別的對象來選擇對應的xml文件。

它有什麼特點:

1.具有尺度不變性,在尺度變化上具有魯棒性

2.不具有旋轉不變性,旋轉的人臉、側臉是識別不出來的

3.opencv提供了尺度不變Haar級聯的分類器和跟蹤器,並將它們保存成指定的文件格式。用到哪個加載哪個文件即可

人臉的Haar特徵分類器就是一個XML文件,該文件中會描述人臉的Haar特徵值。當然Haar特徵的用途可不止可以用來描述人臉這一種,用來描述眼睛,嘴脣或是其它物體也是可以的。

OpenCV有已經自帶了人臉的Haar特徵分類器。OpenCV安裝目錄中的\data\ haarcascades目錄下的haarcascade_frontalface_alt.xml與haarcascade_frontalface_alt2.xml都是用來檢測人臉的Haar分類器。這個haarcascades目錄下還有人的全身,眼睛,嘴脣的Haar分類器。

在這裏插入圖片描述

按需選擇。。

下面代碼,引入這個分類器。

face_cascade = cv2.CascadeClassifier('/home/pi/pyqt/helloworld/Lib/site- packages/cv2/data/haarcascade_frontalface_default.xml')

人臉檢測

靜態圖像人臉檢測

識別一張圖片中人臉(正臉,這個是這個級聯分類器的缺點),用這個級聯分類器還是比較方便快速的。流程如下:

1.加載圖像

2.檢測人臉

3.根據檢測出人臉位置參數,繪製矩形框

4.顯示最終圖片

def detect(filename):#靜態人臉檢測
        img = cv2.imread(filename)
        gray = cv2.cvtColor(img , cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray , 1.3 , 5)#多尺度檢測,參數有框這個框位置的準確性,需要了解自行百度
        for (x , y, w, h) in faces:
            img = cv2.rectangle(img, (x, y) , (x+w , y+h) , (0,0,255) , 2)
        cv2.namedWindow('get_face')
        cv2.imshow('get_face',img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

視頻中的人臉檢測

在靜態圖像人臉檢測的基礎上,對視頻中的每一幀圖像進行檢測。流程如下:

1.打開攝像頭,讀取幀

2.檢測幀中的人臉

3.畫框

4.顯示

5.按‘c’結束檢測

代碼如下:

要開啓攝像頭:

cap = cv2.VideoCapture(0)
def video_face_detect():#視頻人臉檢測
        while True:
            ret, frame = cap.read()
            #img = cv2.imread(frame)
            frame1 = frame.copy()  #圖像拷貝
            gray = cv2.cvtColor(frame , cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(gray , 1.3 , 5)
            for (x , y , w, h) in faces:
                img = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
            cv2.namedWindow('after_detect')
            img1 = np.hstack((frame1 , img))
            cv2.imshow('after_detect',img1)
            if cv2.waitKey(1) == ord('c'):
                break

人臉識別

人臉檢測是人臉識別的基礎。人臉識別就是一個程序能識別給定圖像或視頻中的人臉。opencv中是採用一系列分類好的圖像(生成樣本)來訓練程序。

人臉識別另一個重要的特徵就是有個置信度評分,可設置閾值來進行篩選。

人臉識別所需要的樣本是有兩種方式得到,一是自己採集來的圖像、二是互聯網上有許多人臉數據庫(不是這裏的重點,知道即可)

生成人臉識別數據

要滿足一下條件:

1.圖像是灰度,後綴名爲.pgm

2.圖像形狀爲正方形(程序中調整一下即可)

3.圖像大小要一樣大

def generate():                                          #2020.4.9已測試成功可以用
        counts = 1
        path1 = '/home/pi/pyqt/my_user'
        files = os.listdir(path1)
        count,nums = 1,0
        for filename in files:#計算文件夾中有多少個pgm文件 ,比較靈活點
            count += 1
            nums +=1
        Id = nums/200
        print('開始錄入用戶臉部信息!請摘掉眼鏡........')
        print('不要固定的表情。。。。')
        Face_process.ass.stop()                                    #關閉定時器
        while True:
            ret , frame = cap.read()
            gray = cv2.cvtColor( frame , cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale( gray , 1.3 , 5 )
            for (x , y , w , h) in faces:
                img = cv2.rectangle(frame , (x, y) , (x+w,y+h) , (0,0,255) , 3)
                after = cv2.resize(gray[y:y+h,x:x+w] , (200 , 200))  #調整圖片規格
                cv2.imwrite('/home/pi/pyqt/my_user/%s.pgm' %str(count) , after)
                Csv_file.write_csv(('my_user/%s.pgm'%str(count)) , Id)  #####################################################
                print('已錄入' + str(counts) + '張圖像....')
                cv2.putText(img,str(counts) + 'pictures have been entered...',(10, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255),3)
                count += 1
                counts += 1
            cv2.namedWindow('camera')
            print(frame.shape)
            cv2.imshow('camera' , frame)
            cv2.waitKey(80)  #延時500毫秒
            if counts > 200:   #錄入20張照片
                print('錄入結束!')
                Face_process.ass.start(10)#開啓定時器
                break

我錄入的是2一個人200個樣本。

運行之後:對應文件夾下,就會有
在這裏插入圖片描述

在這裏插入圖片描述

pgm文件就是你的錄入的人臉。上一個csv文件是後面訓練程序時,分類、以及告訴程序樣本在哪的作用。

人臉識別

opencv中提供了3種算法,這幾種都是機器學習的算法,比如SVM,k均值聚類,這些算法背後都有用到它們。

1.Fisherfaces算法

2.Eigenfaces算法

3.LBPH算法

上面三種算法,第三種的效果是最好的。

前兩種的置信度評分和最後一種是不一樣的,前兩種是產生的置信度在0到20000之內,評分低於4000的都可以被認爲是可靠的識別了。而最後一種算法評分低於50的則可以被看成爲可靠的識別,高於80則會被視爲評分比較低的了

用上它們也不難,一行代碼搞定:

model = cv2.face.createLBPHFaceRecognizer()

相應的,用其他算法就把LBPHFace改成其他算法名稱就可以了

注意:

opencv3的版本就用上面這種格式,如果是opencv4,即版本的問題,就得改成下面的格式:

model = cv2.face.LBPHFaceRecognizer_create()

訓練及人臉識別

直接上代碼了,就是導入上面採集好的樣本,訓練模型,之後對視頻幀進行識別顯示即可

def face_distinguish():
        names = []
        f = open('/home/pi/pyqt/yonghu.csv' , 'r+')
        csv_read = csv.reader(f)
        for name in csv_read:
            names.append(name[0])
        [x , y] = Face_process.read_images('/home/pi/pyqt/ja.csv') #加載圖片
        y = np.asarray(y , dtype=np.int32)
        Face_process.ass.stop()                                                        #關閉定時器,不顯示圖像
        Face_process.sd.setPixmap(QtGui.QPixmap(""))                                   #模型訓練時需要一段事件,將最後卡頓是照片清理掉。。
        Face_process.sd.setText('系統正在工作,請耐心等候........')
        cv2.waitKey(1)                                                                 #延時一毫秒纔有效果
        model = cv2.face.createLBPHFaceRecognizer()                                   #人臉識別模型c
        model.train(np.asarray(x) , np.asarray(y))                                     #訓練模型
        while True:
            read , img = cap.read()                                                    #讀取攝像頭信息
            gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)                                #灰度化
            faces = face_cascade.detectMultiScale(gray, 1.3 , 5)                       #人臉檢測
            for (x,y,w,h) in faces:
                img = cv2.rectangle(img , (x , y) , (x+w , y+h) , (0,0,255) , 3)       #畫框
                roi = gray[x:x+w , y:y+h]                                              #扣出人臉圖
                try:
                    roi = cv2.resize(roi,(200,200) , interpolation=cv2.INTER_LINEAR)   #圖像規格大小調整
                    params = model.predict(roi)                                        #預測、識別
                    if params[1]<=50:
                        print('label:%s,confidence:%.2f' % (params[0], params[1]))  # 打印識別信息
                        cv2.putText(img, names[params[0]+1], (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0),3)  # 貼標籤
                except:
                    continue
            cv2.namedWindow('camera')
            cv2.imshow('camera' , img)
            cv2.waitKey(1)
            print(Face_process.zuiz)
            #print(System.cc)
            if Face_process.zuiz == 1:                                        #退出檢測
                Face_process.zuiz = 0
                Face_process.ass.start(10)                                    #開始定時器
                break

PyQt5界面

直接安裝pyqt-tools庫,用qtdesiger搭建一個心儀的界面出來,之後將ui文件轉換成py文件,想個法子將它和人臉識別整合到一塊,不過上面的代碼都是模塊化的,用按鍵來執行相應動作一個也不難。我直接上我的效果圖(捂臉)

在這裏插入圖片描述

在這裏插入圖片描述

畢竟是個系統所以還是要功能完整一些的啦,密碼鎖也在其中。上面就是我在pycharm下面開發出來的界面,debug、debug最終就滿足了自己想要的效果。

移植到樹莓派上

把整個工程文件複製到樹莓派上面,在終端上面執行main.py文件就可以了。文件最好要多拷貝幾份(樹莓派很容易炸雞、黑屏,特別不要隨便斷電,不然系統某些文件一旦丟失、缺損。各種蜜汁bug。),然後部署的時候可能得debug,運氣好,直接運行成功。
執行語句用

sudo python3 +你的文件名.py

與單片機端通訊

樹莓派負責人臉識別,之後,與單片機端,即下位機通訊,發送指令控制下位機端。

下位機參考這篇博客,我一個大二師弟搞的。這兩端構成整個系統。

最後

好吧,有空可以搞搞看,其實每那麼難。
需要的知識點:
1.python
2.opencv-python
3.PyQt5
4.linux命令、指令、相關知識
5.腳本文件知識。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章