一、樹(shù)莓派Opencv以及擴(kuò)展模塊的安裝
1、概述:本次在樹(shù)莓派上安裝Opencv及其擴(kuò)展模塊,考慮到樹(shù)莓派的SD卡容量和內(nèi)存的限制,不采用直接pip安裝方法,而采用編譯Opencv源碼的方式進(jìn)行安裝。
2、遇到的問(wèn)題及解決方法
遇到的問(wèn)題 | 解決方法 |
---|---|
缺少”cuda.hpp” | 將/home/pi/opencv_contrib3.4.1/modules/xfeatures2d/include/opencv2下的xfeatures2d文件夾復(fù)制到home/pi/opencv-3.4.1/modules/stitching/include/opencv2下 |
缺少”bosstdesc_bgm.i” | 下載對(duì)應(yīng)的文件到opencv_contrib/modules/xfeatures2d/src下 |
運(yùn)行至99%時(shí)樹(shù)莓派卡死 | 原本采用make -j4進(jìn)行源碼編譯加速,但是多次嘗試仍然卡死,之后采用make解決了問(wèn)題,可能原因是make -j4所需的交換空間太大導(dǎo)致卡死。 |
3、運(yùn)行結(jié)果
導(dǎo)入opencv庫(kù)沒(méi)有問(wèn)題,說(shuō)明安裝成功。
二、樹(shù)莓派人臉檢測(cè)
1、概述:本次在樹(shù)莓派上檢測(cè)人臉用Opencv自帶的Haar特征分類器。
2、代碼編寫(xiě):
將.xml文件拷貝到mu_code文件夾下,在mu_code下編寫(xiě)代碼,則工程的根目錄默認(rèn)在mu_code。
import cv2
cap=cv2.VideoCapture(0)
cascadePath = "/home/pi/opencv-3.4.3/data/haarcascades/haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath)
while (True):
ret, img = cap.read()
# 灰度化處理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray, 1.3, 5)
if len(faces)!=0:
x = faces[0][0]
y = faces[0][1]
w = faces[0][2]
h = faces[0][3]
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.imshow("fle",img)
cv2.waitKey(10)
3、運(yùn)行結(jié)果:
由圖中可以看出可以正確檢測(cè)出人臉。
三、樹(shù)莓派人臉識(shí)別
1、概述:
本次在樹(shù)莓派上進(jìn)行人臉識(shí)別采用OpenCV人臉識(shí)別類LBPHFaceRecognizer。
2、代碼編寫(xiě):
import cv2
from PIL import Image
import numpy as np
imagePath="face.png"
img_face=cv2.imread(imagePath,0)
cv2.imshow("fle",img_face)
cv2.waitKey(0)
recognizer = cv2.face.LBPHFaceRecognizer_create()
PIL_img = Image.open(imagePath).convert('L')
img_numpy = np.array(PIL_img, 'uint8')
faces=[]
ids=[]
faces.append(img_numpy)
ids.append(2)
recognizer.train(faces, np.array(ids))
id, confidence = recognizer.predict(img_face)
print("id=",id)
print("confidence=",confidence)
3、運(yùn)行結(jié)果:
人臉圖片用于訓(xùn)練,用于訓(xùn)練的id是2,這里只是為了檢測(cè)代碼的正確性,所以依然用這張圖片是做識(shí)別,識(shí)別的結(jié)果是id=2,confidence≈9.8。Id號(hào)識(shí)別正確,confidence接近于0,說(shuō)明識(shí)別率很高。
四、樹(shù)莓派利用雙色LED模擬開(kāi)關(guān)門動(dòng)作
1、概述:
設(shè)計(jì)一個(gè)雙色LED類,該類應(yīng)該能夠向外提供兩個(gè)方法,分別設(shè)置紅燈和綠燈的PWM。
這里在主函數(shù)調(diào)用是都是設(shè)置為滿PWM。
2、接線
樹(shù)莓派 | 3mm雙色LED模塊 |
---|---|
GND | 負(fù)極(-) |
P17 | 紅色燈正極(中間引腳) |
P18 | 綠色燈正極 |
3、代碼編寫(xiě)
import RPi.GPIO as GPIO
import time
class Double_LED_Class:
def __init__(self): # double_led 初始化工作
makerobo_pins = (11, 12) # PIN管腳字典
GPIO.setmode(GPIO.BOARD) # 采用實(shí)際的物理管腳給GPIO口
GPIO.setwarnings(False) # 去除GPIO口警告
GPIO.setup(makerobo_pins, GPIO.OUT) # 設(shè)置Pin模式為輸出模式
GPIO.output(makerobo_pins, GPIO.LOW) # 設(shè)置Pin管腳為低電平(0V)關(guān)閉LED
self.p_R = GPIO.PWM(makerobo_pins[0], 2000) # 設(shè)置頻率為2KHz
self.p_G = GPIO.PWM(makerobo_pins[1], 2000) # 設(shè)置頻率為2KHz
# 初始化占空比為0(led關(guān)閉)
self.p_R.start(0)
self.p_G.start(0)
def makerobo_pwm_map(self,x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def makerobo_set_red_Color(self,col): # 例如:col = 0x1122
# 把0-255的范圍同比例縮小到0-100之間
R_val = self.makerobo_pwm_map(col, 0, 255, 0, 100)
self.p_R.ChangeDutyCycle(R_val) # 改變占空比
def makerobo_set_green_Color(self,col): # 例如:col = 0x1122
# 把0-255的范圍同比例縮小到0-100之間
G_val = self.makerobo_pwm_map(col, 0, 255, 0, 100)
self.p_G.ChangeDutyCycle(G_val) # 改變占空比
# 釋放資源
def makerobo_destroy(self):
self.p_G.stop()
self.p_R.stop()
GPIO.output(self.makerobo_pins, GPIO.LOW) # 關(guān)閉所有LED
GPIO.cleanup() # 釋放資源
# 測(cè)試用例
if __name__ == "__main__":
Hardware_double_led=Double_LED_Class()
Hardware_double_led.makerobo_set_red_Color(200)
time.sleep(3)#顯示紅燈3s后顯示綠燈
Hardware_double_led.makerobo_set_red_Color(0)
Hardware_double_led.makerobo_set_green_Color(200)
4、運(yùn)行結(jié)果
五、樹(shù)莓派門禁系統(tǒng)界面設(shè)計(jì)與整體邏輯代碼整合
1、概述:
樹(shù)莓派門禁系統(tǒng)總共包括4個(gè)界面設(shè)計(jì),分別是人臉識(shí)別開(kāi)門界面、管理員登錄界面、人臉?shù)浫虢缑妗⑷四様?shù)據(jù)庫(kù)展示界面。這四個(gè)界面都用PyQt5進(jìn)行設(shè)計(jì),先在Window上用Qt Designer搭建界面,用Python編寫(xiě)邏輯關(guān)系,最后移植到樹(shù)莓派上,樹(shù)莓派上只需要安裝PyQt庫(kù)即可運(yùn)行程序。
下面為四個(gè)界面的展示圖:
界面控件的邏輯關(guān)系如下圖:
2、代碼編寫(xiě):
代碼思路:
創(chuàng)建了四個(gè)界面類,分別繼承于用Qt Designer創(chuàng)建 的四個(gè)界面類,這樣做是為了能夠在更改界面的時(shí)候不會(huì)改變邏輯部分代碼。另外創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù)操作類,主要是為了能夠查詢,讀寫(xiě)數(shù)據(jù)庫(kù),這里采用的是SQlite數(shù)據(jù)庫(kù)。
Main文件:
#########################################
#Author:郭先達(dá)
#date:2021.12.22
#######################################33
import sys
import cv2
import threading
from PyQt5.QtCore import QBasicTimer
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit, QGridLayout, QMessageBox, QGroupBox
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QWidget, QLabel, QApplication
from PIL import Image
import numpy as np
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QPalette, QBrush, QPixmap
from PyQt5.QtSql import *
import time
from double_led import Double_LED_Class
import os
from MainWindow import Ui_Dialog as Ui_Dialog_MainWindow
from Admin_enter import Ui_Dialog as Ui_Dialog_Admin_enter
from Face_rec import Ui_Dialog as Ui_Dialog_Face_rec
from SQliteWindow import Ui_Dialog as Ui_Dialog_SQliteWindow
# 導(dǎo)入OpenCV自帶的數(shù)據(jù)集,定義多個(gè)是因?yàn)樵诤竺嬗卸啻握{(diào)用,用一個(gè)的話會(huì)報(bào)錯(cuò)
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade1 = cv2.CascadeClassifier(cascadePath)
faceCascade2= cv2.CascadeClassifier(cascadePath)
faceCascade3 = cv2.CascadeClassifier(cascadePath)
faceCascade4=cv2.CascadeClassifier(cascadePath)
#人臉識(shí)別開(kāi)門界面
class Fle_MainWindow(QDialog,Ui_Dialog_MainWindow):
def __init__(self):
super(Fle_MainWindow,self).__init__()
self.setupUi(self)
# 創(chuàng)建定時(shí)器,定時(shí)器用來(lái)定時(shí)拍照
self.timer_camera = QtCore.QTimer()
self.user = []
#進(jìn)入人臉識(shí)別開(kāi)門界面之前先把所有數(shù)據(jù)訓(xùn)練一遍,以滿足新數(shù)據(jù)的錄入
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
faces, ids = self.getImagesAndLabels("./Face_data")#拍攝的照片放在這個(gè)文件夾下
self.recognizer.train(faces, np.array(ids))#開(kāi)始訓(xùn)練
self.font = cv2.FONT_HERSHEY_SIMPLEX
#攝像頭初始化
self.camera_init()
#綁定函數(shù)show_camera
self.timer_camera.timeout.connect(self.show_camera)
#30ms拍一次照片
self.timer_camera.start(30)
# 點(diǎn)擊管理員按鈕事件
self.pushButton_administrators.clicked.connect(self.slot_btn_admin)
#新建一個(gè)雙色LED類
self.Hardware_double_led=Double_LED_Class()
# 函數(shù)獲取圖像和標(biāo)簽數(shù)據(jù)
def getImagesAndLabels(self,path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
faceSamples = []#人臉數(shù)據(jù)
ids = []#人臉對(duì)應(yīng)的id標(biāo)簽
for imagePath in imagePaths:
# 轉(zhuǎn)換為灰度
PIL_img = Image.open(imagePath).convert('L')
img_numpy = np.array(PIL_img, 'uint8')
#print(imagePath),打印出具體信息,怎么分割就怎么設(shè)置序號(hào)
id = int(imagePath.split("/")[2].split(".")[1])
faces = faceCascade3.detectMultiScale(img_numpy)
for (x, y, w, h) in faces:
faceSamples.append(img_numpy[y:y + h, x:x + w])
ids.append(id)
print(ids)
return faceSamples, ids
def camera_init(self):
# 打開(kāi)設(shè)置攝像頭對(duì)象
self.cap = cv2.VideoCapture(0)
self.__flag_work = 0
self.x = 0
self.count = 0
#這里的minW和minH用于限制人臉的最小寬高,防止誤測(cè)
self.minW = 0.2 * self.cap.get(3)#視頻流的幀寬度
self.minH = 0.2 * self.cap.get(4)#視頻流的幀高度
def show_camera(self):
flag, self.image = self.cap.read()
# 將圖片變化成灰度圖
gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
# 探測(cè)圖片中的人臉
faces = faceCascade1.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(int(self.minW), int(self.minH)),
)
# 判斷是否檢測(cè)到人臉,檢測(cè)到設(shè)置為綠燈,沒(méi)檢測(cè)到設(shè)置為紅燈
if len(faces)!=0:
#下面這個(gè)操作是為了能夠只檢測(cè)到一張臉,檢測(cè)面積最大的那個(gè)臉
WxH_max=0 #人臉矩形的面積
WxH_max_face=faces[0]
for i in faces:
if(i[2]*i[3]>WxH_max):
WxH_max=i[2]*i[3]
WxH_max_face=i
# 圍繞臉的框
x=WxH_max_face[0]
y = WxH_max_face[1]
w = WxH_max_face[2]
h = WxH_max_face[3]
cv2.rectangle(self.image, (x, y), (x + w, y + h), (0, 255, 0), 2)
#用recognizer進(jìn)行識(shí)別判斷
id, confidence = self.recognizer.predict(gray[y:y + h, x:x + w])
# 對(duì)置信度進(jìn)行判斷,這里設(shè)定為70
if (confidence < 70):
confidence = " {0}%".format(round(100 - confidence))
for i in range(0,mysqlite.get_rows()):
if mysqlite.find_data(i,0)==id:
self.label_ID.setText(str(mysqlite.find_data(i,1)))
self.label_name.setText(str(mysqlite.find_data(i,2)))
self.Hardware_double_led.makerobo_set_red_Color(0)
self.Hardware_double_led.makerobo_set_green_Color(100)
else:
confidence = " {0}%".format(round(100 - confidence))
self.label_ID.setText("不認(rèn)識(shí)")
self.label_name.setText("不認(rèn)識(shí)")
self.Hardware_double_led.makerobo_set_red_Color(100)
self.Hardware_double_led.makerobo_set_green_Color(0)
# 給圖片添加文本 圖片矩陣, 添加文本名稱, 設(shè)置文本顯示位置,
# 字體樣式, 字體大小, 字體顏色, 字體粗細(xì)
cv2.putText(self.image, str(id), (x + 5, y - 5), self.font, 1, (255, 255, 255), 2)
cv2.putText(self.image, str(confidence), (x + 5, y + h - 5), self.font, 1, (255, 255, 0), 1)
else:
self.Hardware_double_led.makerobo_set_red_Color(0)
self.Hardware_double_led.makerobo_set_green_Color(0)
# 將視頻顯示在了label上
show = cv2.resize(self.image, (640, 480))
show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
self.lab_face.setPixmap(QtGui.QPixmap.fromImage(showImage))
# 點(diǎn)點(diǎn)擊管理員按鈕事件
def slot_btn_admin(self):
#應(yīng)該在釋放攝像頭之前先關(guān)閉定時(shí)器
self.timer_camera.stop()
self.cap.release()
self.logon = Fle_Admin_enter()
self.logon.show()
self.hide()
#其他界面不用雙色LED模擬開(kāi)關(guān)門,把燈滅掉
self.Hardware_double_led.makerobo_set_red_Color(0)
self.Hardware_double_led.makerobo_set_green_Color(0)
# 管理員登錄界面
class Fle_Admin_enter(QDialog,Ui_Dialog_Admin_enter):
def __init__(self):
super(Fle_Admin_enter, self).__init__()
self.setupUi(self)
#將輸入信息初始化為空
self.lineEdit_admin_ID.setText("")
self.lineEdit_admin_key.setText("")
#設(shè)置密碼為隱藏方式顯示
self.lineEdit_admin_key.setEchoMode(QLineEdit.Password)
# lineEdit改變事件
self.lineEdit_admin_ID.textEdited[str].connect(self.changeEdit_ID)
self.lineEdit_admin_key.textEdited[str].connect(self.changeEdit_key)
# 點(diǎn)擊返回按鈕事件
self.pushButton_admin_back.clicked.connect(self.slot_btn_back)
# 點(diǎn)擊登錄按鈕事件
self.pushButton_admin_enter.clicked.connect(self.slot_btn_logon)
# 點(diǎn)擊Edit_ID事件
def changeEdit_ID(self):
Edit_ID = self.lineEdit_admin_ID.text()
print("Edit_ID=",Edit_ID)
# 點(diǎn)擊Edit_key事件
def changeEdit_key(self):
Edit_key = self.lineEdit_admin_key.text()
print("Edit_ID=",Edit_key)
# 點(diǎn)擊返回按鈕事件
def slot_btn_back(self):
self.menu = Fle_MainWindow()
self.menu.show()
self.hide()
# 點(diǎn)擊登錄按鈕事件
def slot_btn_logon(self):
# 判斷賬號(hào)和密碼是否輸入正確
print(self.lineEdit_admin_ID.text)
print(self.lineEdit_admin_key.text)
#這里設(shè)置管理員的賬號(hào)和密碼,這里都設(shè)置為1
if self.lineEdit_admin_ID.text() == "1" and self.lineEdit_admin_key.text() == "1":
self.manager_face = Fle_Face_rec()
self.manager_face.show()
self.hide()
#print("enter Ui_manager_face")
else:
QMessageBox.warning(self, "提示", "賬號(hào)或密碼錯(cuò)誤!", QMessageBox.Close)
#人臉?shù)浫虢缑?/span>
class Fle_Face_rec(QDialog,Ui_Dialog_Face_rec):
def __init__(self):
super(Fle_Face_rec, self).__init__()
self.setupUi(self)
# 初始化為空
self.lineEdit_ID.setText("")
self.lineEdit_name.setText("")
# 初始化進(jìn)度條定時(shí)器
self.timer = QBasicTimer()
self.step = 0
# 創(chuàng)建定時(shí)器
self.timer_camera = QtCore.QTimer()
# 初始化攝像頭數(shù)據(jù)
self.camera_init()
# 定時(shí)器函數(shù),用來(lái)顯示人臉檢測(cè)結(jié)果,并不錄入數(shù)據(jù)
self.timer_camera.timeout.connect(self.show_camera)
self.timer_camera.start(30)
self.pushButton_begin_rec.clicked.connect(self.slot_btn_enter)
self.pushButton_back.clicked.connect(self.slot_btn_back)
self.pushButton_show_sqlite.clicked.connect(self.show_sqlitedata)
# 初始化攝像頭數(shù)據(jù)
def camera_init(self):
self.cap = cv2.VideoCapture(0)
self.__flag_work = 0
self.x =0
self.count = 0
#設(shè)置分辨率為640*480
self.cap.set(4,640)
self.cap.set(3,480)
# 點(diǎn)擊返回按鍵返回上一界面
def slot_btn_back(self):
self.timer_camera.stop()
self.cap.release()
self.logon = Fle_MainWindow()
self.logon.show()
self.hide()
def show_camera(self):
flag, self.image = self.cap.read()
gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
faceCascade2 = cv2.CascadeClassifier(cascadePath);
faces = faceCascade2.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(200, 200)
)
if len(faces)!=0:
WxH_max = 0
WxH_max_face = faces[0]
for i in faces:
if (i[2] * i[3] > WxH_max):
WxH_max = i[2] * i[3]
WxH_max_face = i
# 圍繞臉的框
x = WxH_max_face[0]
y = WxH_max_face[1]
w = WxH_max_face[2]
h = WxH_max_face[3]
cv2.rectangle(self.image, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = self.image[y:y + h, x:x + w]
# 將視頻顯示在了label上
show = cv2.resize(self.image, (640, 480))
show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
self.label_face.setPixmap(QtGui.QPixmap.fromImage(showImage))
# 點(diǎn)擊按鈕開(kāi)啟人臉?shù)浫刖€程
def slot_btn_enter(self):
self.count = 0
# 創(chuàng)建線程并開(kāi)啟
self.thread = threading.Thread(target=self.thread_pic)
self.thread.start()
# 開(kāi)啟進(jìn)度條定時(shí)器
self.timer.start(100, self)
# 加載進(jìn)度條
def timerEvent(self, e):
self.progressBar.setValue(self.count)
# 錄入人臉線程
def thread_pic(self):
tip="正在錄入"+str(self.lineEdit_ID.text())+str(self.lineEdit_name.text())+"的人臉!!"
print(tip)
# 創(chuàng)建目錄,將獲取的人臉照片放入指定的文件夾
self.file = "./Face_data"
file_ID=str(self.lineEdit_ID.text())
while (True):
# 灰度化處理
gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
faces = faceCascade4.detectMultiScale(gray, 1.3, 5)
if len(faces)!=0:
WxH_max = 0
WxH_max_face = faces[0]
for i in faces:
if (i[2] * i[3] > WxH_max):
WxH_max = i[2] * i[3]
WxH_max_face = i
# 圍繞臉的框
x = WxH_max_face[0]
y = WxH_max_face[1]
w = WxH_max_face[2]
h = WxH_max_face[3]
self.count += 1
# 將捕獲的圖像命名為User.0.1.png,其中0是id號(hào)
print(self.file + "/User." + file_ID + '.' + str(self.count) + ".png")
bool = cv2.imwrite(self.file + "/User." + file_ID + '.' + str(self.count) + ".png",
gray[y:y + h, x:x + w])
# 取100張人臉樣本,停止錄像
if self.count >= 100:
print("人臉數(shù)據(jù)采集已完成!")
break
#將數(shù)據(jù)存入數(shù)據(jù)庫(kù)
mysqlite.add_row(self.lineEdit_ID.text(),self.lineEdit_xuehao.text(),str(self.lineEdit_name.text()))
def show_sqlitedata(self):
self.logon = Fle_SQliteWindow()
self.logon.show()
#self.hide()
#人臉數(shù)據(jù)庫(kù)展示界面
class Fle_SQliteWindow(QDialog,Ui_Dialog_SQliteWindow):
def __init__(self):
super(Fle_SQliteWindow,self).__init__()
self.setupUi(self)
self.tableView.setModel(mysqlite.model)
self.pushButton_add.clicked.connect(self.addrow)
self.pushButton_delete.clicked.connect(lambda: mysqlite.model.removeRow(self.tableView.currentIndex().row()))
def addrow(self):
# 不是在QTableView上添加,而是在模型上添加,會(huì)自動(dòng)將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中!
# 參數(shù)一:數(shù)據(jù)庫(kù)共有幾行數(shù)據(jù) 參數(shù)二:添加幾行
ret = mysqlite.model.insertRows(mysqlite.model.rowCount(), 1) # 返回是否插入
print('數(shù)據(jù)庫(kù)共有%d行數(shù)據(jù)' % mysqlite.model.rowCount())
print('insertRow=%s' % str(ret))
#數(shù)據(jù)庫(kù)操作類
class Fle_Sqlite():
def __init__(self):
self.db = QSqlDatabase.addDatabase('QSQLITE')
self.db.setDatabaseName('./people_data.db')
if not self.db.open():
print('無(wú)法建立與數(shù)據(jù)庫(kù)的連接')
query = QSqlQuery()
query.exec('create table people(id varcahr(10),xuehao varcahr(15),name varcahr(50))')
self.model = QSqlTableModel() # MVC模式中的模型
# 初始化將數(shù)據(jù)裝載到模型當(dāng)中
self.initializeModel()
# 初始化
def initializeModel(self):
self.model.setTable('people')
# 當(dāng)字段變化時(shí)會(huì)觸發(fā)一些事件
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
# 將整個(gè)數(shù)據(jù)裝載到model中
self.model.select()
# 設(shè)置字段頭
#只是設(shè)置字段頭,不是顯示
self.model.setHeaderData(0, Qt.Horizontal, 'ID')
self.model.setHeaderData(1, Qt.Horizontal, 'xuehao')
self.model.setHeaderData(2, Qt.Horizontal, 'name')
#找指定位置的數(shù)據(jù)
def find_data(self, row, col):
# 序號(hào)從0開(kāi)始
index = self.model.index(row, col)
return self.model.data(index)
#新加一行
def add_row(self,ID,xuehao,name):
row = self.model.rowCount()
self.model.insertRow(row)
self.model.setData(self.model.index(row, 0), ID)
self.model.setData(self.model.index(row, 1), xuehao)
self.model.setData(self.model.index(row, 2), name)
self.model.submitAll()
print(ID)
print(xuehao)
print(name)
#刪除最后一行
def del_row(self):
row = self.model.rowCount()-1
self.model.removeRow(row)
self.model.submitAll()
def get_rows(self):
#print(self.model.rowCount())
return self.model.rowCount()
if __name__ == "__main__":
mysqlite=Fle_Sqlite()
app = QApplication(sys.argv)
w = Fle_MainWindow()
w.show()
sys.exit(app.exec_())
3、運(yùn)行結(jié)果:
由上面兩圖可以看出識(shí)別效果正確。
識(shí)別出人臉時(shí)亮綠燈。
由上圖可知,顯示“不認(rèn)識(shí)”時(shí)亮紅燈。
六、總結(jié)與體會(huì)
①本次實(shí)驗(yàn)采用的LBPH人臉識(shí)別模型精度欠缺,受光線影響非常嚴(yán)重,或許可以通過(guò)攝像頭加紅外濾光片外加紅外補(bǔ)光燈解決。
②本次實(shí)驗(yàn)中多次遇到攝像頭調(diào)用打開(kāi)不了導(dǎo)致imread出錯(cuò)的情況,具體原因沒(méi)有找到,猜測(cè)是攝像頭的序列號(hào)改變了。
③本次實(shí)驗(yàn)中創(chuàng)建了多個(gè)界面類,而人臉識(shí)別界面類和人臉?shù)浫虢缑骖惗夹枰{(diào)用攝像頭,導(dǎo)致了攝像頭經(jīng)常報(bào)錯(cuò),所以在界面切換的時(shí)候關(guān)掉了攝像頭,在界面初始化的時(shí)候又打開(kāi)了攝像頭,但是這樣做有時(shí)也會(huì)造成攝像頭來(lái)不及釋放而報(bào)錯(cuò)。
④對(duì)于數(shù)據(jù)庫(kù)的操作,卡了很長(zhǎng)的時(shí)間才分清楚數(shù)據(jù)庫(kù)和數(shù)據(jù)表的區(qū)別,最后才搞清楚讀寫(xiě)操作都是對(duì)鏈接到數(shù)據(jù)庫(kù)的數(shù)據(jù)表操作。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-418361.html
附錄
代碼:https://gitee.com/guoxianda/face-recognition-base-on-Raspberry-pie文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-418361.html
到了這里,關(guān)于基于樹(shù)莓派的人臉識(shí)別門禁系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!