国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

漢中門戶網(wǎng)工程招標杭州seo網(wǎng)站哪家好

漢中門戶網(wǎng)工程招標,杭州seo網(wǎng)站哪家好,查詢網(wǎng)站服務(wù)器提供商,wordpress ssl證書一、簡介 這個人臉識別考勤簽到系統(tǒng)是基于大佬的人臉識別陌生人報警系統(tǒng)二次開發(fā)的。 項目使用Python實現(xiàn),基于OpenCV框架進行人臉識別和攝像頭硬件調(diào)用,同時也用OpenCV工具包處理圖片。交互界面使用pyqt5實現(xiàn)。 該系統(tǒng)實現(xiàn)了從學(xué)生信息輸入、人臉數(shù)據(jù)…

在這里插入圖片描述

一、簡介

這個人臉識別考勤簽到系統(tǒng)是基于大佬的人臉識別陌生人報警系統(tǒng)二次開發(fā)的。

項目使用Python實現(xiàn),基于OpenCV框架進行人臉識別和攝像頭硬件調(diào)用,同時也用OpenCV工具包處理圖片。交互界面使用pyqt5實現(xiàn)。

該系統(tǒng)實現(xiàn)了從學(xué)生信息輸入、人臉數(shù)據(jù)錄入、人臉數(shù)據(jù)訓(xùn)練,學(xué)生信息多條件搜索、修改,多選刪除,人臉數(shù)據(jù)訓(xùn)練,人臉識別、追蹤、簽到等完整流程的各項功能。甚至允許生成簽到表格和導(dǎo)出Excel格式簽到表。

根據(jù)功能分配,系統(tǒng)分為三個部分實現(xiàn)各部分流程,

  1. 錄入端負責(zé)數(shù)據(jù)導(dǎo)入,
  2. 管理端負責(zé)數(shù)據(jù)刪改查以及人臉數(shù)據(jù)訓(xùn)練,
  3. 監(jiān)控端負責(zé)人臉識別以及簽到功能。

二、效果圖

源碼下載地址

源碼下載地址https://download.csdn.net/download/u013749113/87897481

監(jiān)控端使用界面如圖所示:

在這里插入圖片描述

管理端使用界面如圖所示:

在這里插入圖片描述

錄入端使用界面如圖所示:

在這里插入圖片描述

三、開發(fā)過程

本系統(tǒng)在原始項目的框架基礎(chǔ)上做了大量修改,針對系統(tǒng)功能的不同以及部分模塊實現(xiàn)的不完整做了補充和優(yōu)化。原項目在功能上實現(xiàn)了完整的人臉數(shù)據(jù)錄入過程,并已經(jīng)存在數(shù)據(jù)管理、數(shù)據(jù)錄入、核心(Core)三個基本模塊。

監(jiān)控端修改部分

(1)人臉識別實現(xiàn)
在主要部分【核心】的實現(xiàn)上,原項目采用LBPH實現(xiàn)了人臉識別的基本功能,并使用haar-like實現(xiàn)人臉位置捕獲,使用dlib目標追蹤器實現(xiàn)同一畫面下多個人臉的目標追蹤,嘗試主要追蹤,次要捕獲的方式優(yōu)化人臉捕獲的過程。識別速度與畫面幀率很高,

但識別準確率并不理想,并且嚴重受到光照條件影響。【實際使用時證明,若錄入人臉數(shù)據(jù)時存在單方面光源照射,在識別時,光源位置一旦改變就完全識別不出來了】
并且錄入數(shù)據(jù)時需要大量人臉數(shù)據(jù)集【100張人臉圖以上】,才能獲得較高的識別置信度。

二次開發(fā)后,保留原本速度較快的LBPH人臉識別,新增效果更好的dlib_face_recognition_resnet_model深度學(xué)習(xí)殘差網(wǎng)絡(luò)識別模型。實際使用時發(fā)現(xiàn),雖然實時視頻流幀率明顯降低,但是識別準確率大大提高。

(2)攝像頭啟動與關(guān)閉

在原項目中,在攝像頭調(diào)用的設(shè)計上,錄入端和監(jiān)控端同樣都是用了攝像頭,并進行人臉捕獲,但監(jiān)控端只允許打開和關(guān)閉一次攝像頭,之后就禁用了攝像頭控制按鈕,而錄入端則允許隨意多次的打開和關(guān)閉攝像頭。

其原因是具體實現(xiàn)上,因為監(jiān)控端需要啟動單獨線程執(zhí)行人臉識別任務(wù),而錄入端沒有人臉識別的復(fù)雜處理過程,在一個線程中就可以實現(xiàn)需要的功能。監(jiān)控端開啟攝像頭后,同時啟動人臉識別線程處理單幀圖像,并啟動報警監(jiān)聽線程,設(shè)計思路上是報警線程一旦開啟,全程保持監(jiān)聽,直到程序關(guān)閉,而關(guān)閉攝像頭時代碼實現(xiàn)上只關(guān)閉,也只能夠關(guān)閉人臉識別線程,對于報警監(jiān)聽線程無法控制。導(dǎo)致如果容許攝像頭二次開啟,人臉識別線程能夠啟動,但作為同一個線程實例的報警監(jiān)聽模塊將被二次啟動,導(dǎo)致程序出錯。

這里的人臉識別線程繼承自QTread類,允許使用.stop()函數(shù)控制線程實例的開始與終止,而報警監(jiān)聽模塊則是普通的threading.Thread(),開啟后無法控制關(guān)閉,導(dǎo)致出現(xiàn)上述問題。改進方法是將報警監(jiān)聽線程使用QTread實現(xiàn),使用與人臉識別線程相同的控制方法,攝像頭開啟時啟動,攝像頭關(guān)閉時終止,實現(xiàn)二次啟動功能。

(3)報警系統(tǒng)改為簽到系統(tǒng)
因為系統(tǒng)的功能修改前后有所改變,但是實現(xiàn)的技術(shù)實際上是一樣的。原始項目的報警功能實際上可以作為簽到系統(tǒng)的監(jiān)聽線程。原始代碼邏輯為,發(fā)現(xiàn)置信度低于閾值的臉即陌生人臉,隨機人臉識別線程通過通信隊列告知報警系統(tǒng)執(zhí)行截圖拍攝、消息推送、報警響鈴等功能。改變?yōu)楹灥较到y(tǒng)后,人臉識別線程將置信度閾值以上【即數(shù)據(jù)庫中存在并認為可信的臉】,且匹配度最高的人臉作為簽到信號,通過隊列通信發(fā)送給簽到線程,并執(zhí)行之前沒有的數(shù)據(jù)庫錄入操作。

簡單來說就是,之前是把認不出來的臉進行記錄和報警,轉(zhuǎn)變?yōu)檎J出來且最像的人臉進行記錄和執(zhí)行聲音提示。

(4)簽到表格的創(chuàng)建
這個屬于簽到系統(tǒng)特有的新增功能,說道考勤簽到就一定會想到教師用來點名的簽到表,因此該簽到系統(tǒng)需要生成一個包含當前課程需要簽到的所有學(xué)生信息,通過預(yù)處理進行創(chuàng)建,并在人臉識別過程中實時修改記錄簽到信息,主要內(nèi)容為學(xué)生姓名、學(xué)號、簽到時間。該功能內(nèi)建了一個基于MySQL查詢的QTableWidget控件,用于方便用戶之間從數(shù)據(jù)庫中選擇并創(chuàng)建需要簽到的學(xué)生名單。

管理端修改部分

(1)學(xué)生信息管理
原始的管理端非常簡陋,存儲信息僅包含學(xué)生姓名、faceID、學(xué)號這樣的普通信息,想要查詢學(xué)生信息也只能進行單人查詢,并且只能通過學(xué)號,查詢的唯一目的就是通過學(xué)號刪除查詢結(jié)果。因此無論是查詢還是刪除都非常簡陋。甚至根本不存在修改信息的功能。

修改后的管理端新增了多條件模糊查詢,并且大大增加了信息維數(shù),允許直接雙擊修改學(xué)生信息,并實時同步到數(shù)據(jù)庫中。同時刪除信息的功能也和信息查詢分離開來,信息查詢結(jié)果動態(tài)顯示在QTableWidget控件中【與原項目使用的技術(shù)相同,只是做了更大的功能擴展】。支持用戶多選刪除,不不必“查一個,刪一個”。

(2)人臉數(shù)據(jù)訓(xùn)練
原項目中的人臉數(shù)據(jù)訓(xùn)練功能同樣集成在管理端中,原作者自定義了一個讀取數(shù)據(jù)集并將其與學(xué)生通過faceID進行唯一匹配的函數(shù),也就是LBPH數(shù)據(jù)訓(xùn)練中的人臉數(shù)據(jù)(faces)與分類標簽(labels)。讀取并整理成LBPH.train()所需要的數(shù)據(jù)結(jié)構(gòu)后即可直接將數(shù)據(jù)作為參數(shù)調(diào)用封裝好的函數(shù)進行訓(xùn)練。

值得一提的是,LBPH的數(shù)據(jù)訓(xùn)練非???#xff0c;即使在三百人的,每人人臉數(shù)據(jù)集平均20張的情況下,訓(xùn)練時間依然能控制在十幾秒內(nèi)【但是結(jié)果其實并不好】,因此原作者并沒有將其作為單獨的線程來執(zhí)行,而是直接甩給用戶一個提示:訓(xùn)練期間系統(tǒng)窗口可能會無響應(yīng),請耐心等待。。。

這樣的結(jié)果是導(dǎo)致用戶體驗極差,會以為程序崩了,其實只是訓(xùn)練計算時間過長,導(dǎo)致windows消息監(jiān)聽一段時間內(nèi)無回應(yīng),被認為是程序無響應(yīng)。。。

二次開發(fā)后我將其獨立為一個線程單獨執(zhí)行,并為執(zhí)行函數(shù)增加了進度條,讓用戶直觀的看到訓(xùn)練過程。順便,在代碼實現(xiàn)過程中,發(fā)現(xiàn)大量時間實際上消耗在圖片數(shù)據(jù)集的讀取上,訓(xùn)練的過程反倒沒有那么久,因此進度條實際展示的是讀取過程,邏輯上是先進行的數(shù)據(jù)讀取,再計算特征值,然后繼續(xù)讀取下一個數(shù)據(jù)集,因此將數(shù)據(jù)讀取作為進度來衡量不會有時間上的偏差。


三、代碼具體實現(xiàn)

這里就簡單貼一下數(shù)據(jù)錄入端的代碼。項目完整代碼還請移步本文開始位置的鏈接。

#!/usr/bin/env python3
# Author: kuronekonano <god772525182@gmail.com>
# 人臉信息錄入
import re
import string
import timeimport cv2
import pymysql
import shutilfrom PyQt5.QtCore import QTimer, QRegExp, pyqtSignal, QThread
from PyQt5.QtGui import QImage, QPixmap, QIcon, QRegExpValidator, QTextCursor
from PyQt5.QtWidgets import QDialog, QApplication, QWidget, QMessageBox, QFileDialog, QProgressBar
from PyQt5.uic import loadUiimport logging
import logging.config
import queue
import threading
import os
import sys
import xlrd
import randomfrom datetime import datetime# 用戶取消了更新數(shù)據(jù)庫操作
class OperationCancel(Exception):pass# 采集過程中出現(xiàn)干擾
class RecordDisturbance(Exception):passclass DataRecordUI(QWidget):receiveLogSignal = pyqtSignal(str)messagebox_signal = pyqtSignal(dict)# 日志隊列logQueue = queue.Queue()def __init__(self):super(DataRecordUI, self).__init__()loadUi('./ui/DataRecord.ui', self)  # 讀取UI布局self.setWindowIcon(QIcon('./icons/icon.png'))self.setFixedSize(1528, 856)# OpenCV# 攝像頭self.cap = cv2.VideoCapture()# 分類器self.faceCascade = cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')# 圖像捕獲self.isExternalCameraUsed = Falseself.useExternalCameraCheckBox.stateChanged.connect(lambda: self.useExternalCamera(self.useExternalCameraCheckBox))self.startWebcamButton.toggled.connect(self.startWebcam)self.startWebcamButton.setCheckable(True)# 定時器self.timer = QTimer(self)self.timer.timeout.connect(self.updateFrame)# 人臉檢測self.isFaceDetectEnabled = Falseself.enableFaceDetectButton.toggled.connect(self.enableFaceDetect)self.enableFaceDetectButton.setCheckable(True)# 數(shù)據(jù)庫# self.database = 'users'self.datasets = './datasets'self.isDbReady = Falseself.initDbButton.setIcon(QIcon('./icons/warning.png'))self.initDbButton.clicked.connect(self.initDb)# 用戶信息self.isUserInfoReady = Falseself.userInfo = {'stu_id': '','cn_name': '','en_name': '','stu_grade': '','stu_class': '','stu_sex': '','major': ''}self.addOrUpdateUserInfoButton.clicked.connect(self.addOrUpdateUserInfo)self.migrateToDbButton.clicked.connect(self.migrateToDb)  # 插入新數(shù)據(jù)按鍵綁定# 人臉采集self.startFaceRecordButton.clicked.connect(lambda: self.startFaceRecord(self.startFaceRecordButton))  # 開始人臉采集按鈕綁定,并傳入按鈕本身用于結(jié)束狀態(tài)控制# self.startFaceRecordButton.setCheckable(True)self.faceRecordCount = 0  # 已采集照片計數(shù)器self.minFaceRecordCount = 100  # 最少采集照片數(shù)量self.isFaceDataReady = Falseself.isFaceRecordEnabled = Falseself.enableFaceRecordButton.clicked.connect(self.enableFaceRecord)  # 按鍵綁定錄入單幀圖像# 日志系統(tǒng)self.receiveLogSignal.connect(lambda log: self.logOutput(log))  # pyqtsignal信號綁定self.messagebox_signal.connect(lambda log: self.message_output(log))self.logOutputThread = threading.Thread(target=self.receiveLog, daemon=True)self.logOutputThread.start()# 批量導(dǎo)入self.isImage_path_ready = False# self.ImagepathButton.clicked.connect(self.import_images_data)  # 使用同一線程會導(dǎo)致窗口無響應(yīng)self.ImagepathButton.clicked.connect(self.import_image_thread)  # 使用多線程實現(xiàn)圖片導(dǎo)入self.isExcel_path_ready = Falseself.ExcelpathButton.clicked.connect(self.import_excel_data)self.ImportPersonButton.clicked.connect(self.person_import_thread)@staticmethoddef connect_to_sql():conn = pymysql.connect(host='localhost',user='root',password='******',db='mytest',port=3306,charset='utf8')cursor = conn.cursor()return conn, cursor# 單人導(dǎo)入圖片集【主線程】棄用def import_person_imageset(self):if self.isUserInfoReady:  # 學(xué)生信息確認stu_id = self.userInfo.get('stu_id')self.ImportPersonButton.setIcon(QIcon('./icons/success.png'))image_paths = QFileDialog.getOpenFileNames(self, '選擇圖片',"./",'JEPG files(*.jpg);;PNG files(*.PNG)')if not os.path.exists('{}/stu_{}'.format(self.datasets, stu_id)):os.makedirs('{}/stu_{}'.format(self.datasets, stu_id))image_paths = image_paths[0]for index, path in enumerate(image_paths):try:img = cv2.imread(path)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度圖faces = self.faceCascade.detectMultiScale(gray, 1.3, 5, minSize=(90, 90))  # 分類器偵測人臉if len(faces) == 0:self.logQueue.put('圖片{}中沒有檢測到人臉!'.format(path))continuefor (x, y, w, h) in faces:if len(faces) > 1:raise RecordDisturbancecv2.imwrite('{}/stu_{}/img.{}-{}.jpg'.format(self.datasets, stu_id, index, ''.join(random.sample(string.ascii_letters + string.digits, 4))),img[y - 20:y + h + 20, x - 20:x + w + 20])  # 灰度圖的人臉區(qū)域except RecordDisturbance:logging.error('檢測到多張人臉或環(huán)境干擾')self.logQueue.put('Warning:檢測到圖片{}存在多張人臉或環(huán)境干擾,已忽略。'.format(path))continueexcept Exception as e:logging.error('寫入人臉圖像文件到計算機過程中發(fā)生異常')self.logQueue.put('Error:無法保存人臉圖像,導(dǎo)入該圖片失敗')print(e)self.migrateToDbButton.setEnabled(True)  # 允許提交至數(shù)據(jù)庫self.isFaceDataReady = Trueelse:self.ImportPersonButton.setIcon(QIcon('./icons/error.png'))self.ImportPersonButton.setChecked(False)self.logQueue.put('Error:操作失敗,系統(tǒng)未檢測到有效的用戶信息')# 表格導(dǎo)入學(xué)生信息def import_excel_data(self):excel_paths = QFileDialog.getOpenFileNames(self, '選擇表格',"./",'EXCEL 文件 (*.xlsx;*.xls;*.xlm;*.xlt;*.xlsm;*.xla)')excel_paths = excel_paths[0]conn, cursor = self.connect_to_sql()error_count = 0for path in excel_paths:sheets_file = xlrd.open_workbook(path)for index, sheet in enumerate(sheets_file.sheets()):self.logQueue.put("正在讀取文件:" + str(path) + "的第" + str(index) + "個sheet表的內(nèi)容...")for row in range(sheet.nrows):row_data = sheet.row_values(row)if row_data[1] == '姓名':continueself.userInfo['stu_id'] = row_data[4]self.userInfo['cn_name'] = row_data[1]self.userInfo['en_name'] = row_data[0]self.userInfo['stu_grade'] = '20' + self.userInfo['stu_id'][:2]self.userInfo['stu_class'] = row_data[3].rsplit('-', 1)[1]self.userInfo['stu_sex'] = row_data[5]self.userInfo['major'] = row_data[2]self.userInfo['province'] = row_data[-1]self.userInfo['nation'] = row_data[-2]# print(self.userInfo)try:stu_id = row_data[4]if not os.path.exists('{}/stu_{}'.format(self.datasets, stu_id)):os.makedirs('{}/stu_{}'.format(self.datasets, stu_id))db_user_count = self.commit_to_database(cursor)self.dbUserCountLcdNum.display(db_user_count)  # 數(shù)據(jù)庫人數(shù)計數(shù)器except OperationCancel:passexcept Exception as e:print(e)logging.error('讀寫數(shù)據(jù)庫異常,無法向數(shù)據(jù)庫插入/更新記錄')self.logQueue.put('Error:讀寫數(shù)據(jù)庫異常,同步失敗')error_count += 1self.logQueue.put('導(dǎo)入完畢!其中導(dǎo)入失敗 {} 條信息'.format(error_count))cursor.close()conn.commit()conn.close()# 啟用新線程導(dǎo)入圖片,并添加進度條def import_image_thread(self):self.image_paths = QFileDialog.getOpenFileNames(self, '選擇圖片',"./",'JEPG files(*.jpg);;PNG files(*.PNG)')self.image_paths = self.image_paths[0]if len(self.image_paths) != 0:  # 點擊導(dǎo)入但是沒有選擇文件時不需啟動線程progress_bar = ActionsImportImage(self)print('import success!')# 啟用新線程 單人圖片導(dǎo)入 使用進度條def person_import_thread(self):if self.isUserInfoReady:  # 學(xué)生信息確認stu_id = self.userInfo.get('stu_id')self.ImportPersonButton.setIcon(QIcon('./icons/success.png'))image_paths = QFileDialog.getOpenFileNames(self, '選擇圖片',"./",'JEPG files(*.jpg);;PNG files(*.PNG)')self.image_paths = image_paths[0]if len(self.image_paths) != 0:  # 點擊導(dǎo)入但是沒有選擇文件時不需啟動線程if not os.path.exists('{}/stu_{}'.format(self.datasets, stu_id)):os.makedirs('{}/stu_{}'.format(self.datasets, stu_id))progress_bar = ActionsPersonImport(self)self.migrateToDbButton.setEnabled(True)  # 允許提交至數(shù)據(jù)庫self.isFaceDataReady = Trueelse:self.ImportPersonButton.setIcon(QIcon('./icons/error.png'))self.ImportPersonButton.setChecked(False)self.logQueue.put('Error:操作失敗,系統(tǒng)未檢測到有效的用戶信息')# 圖片批量導(dǎo)入【主線程】棄用def import_images_data(self):image_paths = QFileDialog.getOpenFileNames(self, '選擇圖片',"./",'JEPG files(*.jpg);;PNG files(*.PNG)')image_paths = image_paths[0]error_count = 0self.logQueue.put('開始讀取圖片數(shù)據(jù)...')for index, path in enumerate(image_paths):stu_id = os.path.split(path)[1].split('.')[0]# print(stu_id)if not os.path.exists('{}/stu_{}'.format(self.datasets, stu_id)):text = '命名錯誤!'informativeText = '<b>文件 <font color=red>{}</font> 存在問題,數(shù)據(jù)庫中沒有以該圖片名為學(xué)號的用戶。</b>'.format(path)DataRecordUI.callDialog(QMessageBox.Critical, text, informativeText, QMessageBox.Ok)error_count += 1continuedstpath = '{}/stu_{}/img.{}.jpg'.format(self.datasets, stu_id, stu_id + '-0')try:shutil.copy(path, dstpath)except:text = '命名格式錯誤!'informativeText = '<b>文件 <font color=red>{}</font> 命名格式不正確。</b>'.format(path)DataRecordUI.callDialog(QMessageBox.Critical, text, informativeText, QMessageBox.Ok)error_count += 1self.logQueue.put('圖片批量導(dǎo)入完成!其中導(dǎo)入失敗 {} 張圖片'.format(error_count))# 是否使用外接攝像頭def useExternalCamera(self, useExternalCameraCheckBox):if useExternalCameraCheckBox.isChecked():self.isExternalCameraUsed = Trueelse:self.isExternalCameraUsed = False# 打開/關(guān)閉攝像頭def startWebcam(self, status):if status:if not self.cap.isOpened():camID = 1 if self.isExternalCameraUsed else 0 + cv2.CAP_DSHOWself.cap.open(camID)self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)ret, frame = self.cap.read()  # 獲取攝像頭調(diào)用結(jié)果if not ret:logging.error('無法調(diào)用電腦攝像頭{}'.format(camID))self.logQueue.put('Error:初始化攝像頭失敗')self.cap.release()self.startWebcamButton.setIcon(QIcon('./icons/error.png'))self.startWebcamButton.setChecked(False)else:self.timer.start(5)self.enableFaceDetectButton.setEnabled(True)self.startWebcamButton.setIcon(QIcon('./icons/success.png'))self.startWebcamButton.setText('關(guān)閉攝像頭')else:if self.cap.isOpened():if self.timer.isActive():self.timer.stop()self.cap.release()self.faceDetectCaptureLabel.clear()self.faceDetectCaptureLabel.setText('<font color=red>攝像頭未開啟</font>')self.startWebcamButton.setText('打開攝像頭')self.enableFaceDetectButton.setEnabled(False)self.startWebcamButton.setIcon(QIcon())# 開啟/關(guān)閉人臉檢測def enableFaceDetect(self, status):if self.cap.isOpened():if status:self.enableFaceDetectButton.setText('關(guān)閉人臉檢測')self.isFaceDetectEnabled = Trueelse:self.enableFaceDetectButton.setText('開啟人臉檢測')self.isFaceDetectEnabled = False# 采集當前捕獲幀def enableFaceRecord(self):if not self.isFaceRecordEnabled:self.isFaceRecordEnabled = True# 開始/結(jié)束采集人臉數(shù)據(jù)def startFaceRecord(self, startFaceRecordButton):if startFaceRecordButton.text() == '開始采集人臉數(shù)據(jù)':  # 只能用==判斷,不能用isif self.isFaceDetectEnabled:if self.isUserInfoReady:  # 學(xué)生信息確認self.addOrUpdateUserInfoButton.setEnabled(False)  # 采集人臉數(shù)據(jù)時禁用修改學(xué)生信息if not self.enableFaceRecordButton.isEnabled():  # 啟用單幀采集按鈕self.enableFaceRecordButton.setEnabled(True)self.enableFaceRecordButton.setIcon(QIcon())self.startFaceRecordButton.setIcon(QIcon('./icons/success.png'))self.startFaceRecordButton.setText('結(jié)束當前人臉采集')  # 開始采集按鈕狀態(tài)修改為結(jié)束采集else:self.startFaceRecordButton.setIcon(QIcon('./icons/error.png'))self.startFaceRecordButton.setChecked(False)self.logQueue.put('Error:操作失敗,系統(tǒng)未檢測到有效的用戶信息')else:self.startFaceRecordButton.setIcon(QIcon('./icons/error.png'))self.logQueue.put('Error:操作失敗,請開啟人臉檢測')else:  # 根據(jù)按鈕文本信息判斷是結(jié)束采集還是開始采集if self.faceRecordCount < self.minFaceRecordCount:text = '系統(tǒng)當前采集了 <font color=blue>{}</font> 幀圖像,采集數(shù)據(jù)過少會導(dǎo)致較大的識別誤差。'.format(self.faceRecordCount)informativeText = '<b>請至少采集 <font color=red>{}</font> 幀圖像。</b>'.format(self.minFaceRecordCount)DataRecordUI.callDialog(QMessageBox.Information, text, informativeText, QMessageBox.Ok)else:text = '系統(tǒng)當前采集了 <font color=blue>{}</font> 幀圖像,繼續(xù)采集可以提高識別準確率。'.format(self.faceRecordCount)informativeText = '<b>你確定結(jié)束當前人臉采集嗎?</b>'ret = DataRecordUI.callDialog(QMessageBox.Question, text, informativeText,QMessageBox.Yes | QMessageBox.No,QMessageBox.No)if ret == QMessageBox.Yes:self.isFaceDataReady = True  # 結(jié)束采集,人臉數(shù)據(jù)準備完畢if self.isFaceRecordEnabled:self.isFaceRecordEnabled = Falseself.enableFaceRecordButton.setEnabled(False)  # 結(jié)束采集,單幀采集按鈕禁用self.enableFaceRecordButton.setIcon(QIcon())self.startFaceRecordButton.setText('開始采集人臉數(shù)據(jù)')  # 修改按鈕文本為開始狀態(tài)self.startFaceRecordButton.setEnabled(False)  # 不可重新開始采集self.startFaceRecordButton.setIcon(QIcon())self.migrateToDbButton.setEnabled(True)  # 允許提交至數(shù)據(jù)庫# 定時器,實時更新畫面def updateFrame(self):ret, frame = self.cap.read()# frame = cv2.flip(frame, 1)  # 水平翻轉(zhuǎn)圖片if ret:# self.displayImage(frame)  # ?兩次輸出?if self.isFaceDetectEnabled:  # 人臉檢測detected_frame = self.detectFace(frame)self.displayImage(detected_frame)else:self.displayImage(frame)# 檢測人臉def detectFace(self, frame):gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 灰度圖faces = self.faceCascade.detectMultiScale(gray, 1.3, 5, minSize=(90, 90))  # 分類器偵測人臉# 1.image為輸入的灰度圖像# 2.objects為得到被檢測物體的矩形框向量組# 3.scaleFactor為每一個圖像尺度中的尺度參數(shù),默認值為1.1。scale_factor參數(shù)可以決定兩個不同大小的窗口掃描之間有多大的跳躍,# 這個參數(shù)設(shè)置的大,則意味著計算會變快,但如果窗口錯過了某個大小的人臉,則可能丟失物體。# 4.minNeighbors參數(shù)為每一個級聯(lián)矩形應(yīng)該保留的鄰近個數(shù),默認為3。# minNeighbors控制著誤檢測,默認值為3表明至少有3次重疊檢測,我們才認為人臉確實存。# 6.cvSize()指示尋找人臉的最小區(qū)域。設(shè)置這個參數(shù)過大,會以丟失小物體為代價減少計算量。stu_id = self.userInfo.get('stu_id')#  遍歷所有人臉,只允許有一個人的臉for (x, y, w, h) in faces:if self.isFaceRecordEnabled:try:  # 創(chuàng)建學(xué)號對應(yīng)的圖片數(shù)據(jù)集if not os.path.exists('{}/stu_{}'.format(self.datasets, stu_id)):os.makedirs('{}/stu_{}'.format(self.datasets, stu_id))if len(faces) > 1:raise RecordDisturbancecv2.imwrite('{}/stu_{}/img.{}.jpg'.format(self.datasets, stu_id, self.faceRecordCount + 1),frame[y - 20:y + h + 20, x - 20:x + w + 20])  # 灰度圖的人臉區(qū)域except RecordDisturbance:self.isFaceRecordEnabled = Falselogging.error('檢測到多張人臉或環(huán)境干擾')self.logQueue.put('Warning:檢測到多張人臉或環(huán)境干擾,請解決問題后繼續(xù)')self.enableFaceRecordButton.setIcon(QIcon('./icons/warning.png'))continueexcept Exception as e:logging.error('寫入人臉圖像文件到計算機過程中發(fā)生異常')self.enableFaceRecordButton.setIcon(QIcon('./icons/error.png'))self.logQueue.put('Error:無法保存人臉圖像,采集當前捕獲幀失敗')else:self.enableFaceRecordButton.setIcon(QIcon('./icons/success.png'))self.faceRecordCount = self.faceRecordCount + 1self.isFaceRecordEnabled = False  # 單幀拍攝完成后馬上關(guān)閉self.faceRecordCountLcdNum.display(self.faceRecordCount)  # 更新采集數(shù)量cv2.rectangle(frame, (x - 5, y - 10), (x + w + 5, y + h + 10), (0, 0, 255), 2)  # 紅色追蹤框return frame

源碼下載地址

源碼下載地址https://download.csdn.net/download/u013749113/87897481

http://aloenet.com.cn/news/29745.html

相關(guān)文章:

  • 高端網(wǎng)站建設(shè)費用深圳網(wǎng)絡(luò)推廣公司哪家好
  • 個人接做網(wǎng)站多少錢app優(yōu)化方案
  • 汕頭有建網(wǎng)站公司嗎seo案例
  • 公司和網(wǎng)站備案查詢密碼網(wǎng)絡(luò)營銷和傳統(tǒng)營銷的區(qū)別有哪些
  • 宣傳片視頻西安seo排名
  • wordpress采集網(wǎng)頁文章安卓優(yōu)化大師app下載
  • 工作總結(jié)ppt模板免費寧波優(yōu)化推廣選哪家
  • 桂林做網(wǎng)站的公司seo是哪里
  • 購物網(wǎng)站開發(fā)技術(shù)河北網(wǎng)站優(yōu)化公司
  • 網(wǎng)站風(fēng)格類型百度流量統(tǒng)計
  • 為什么做電子商務(wù)網(wǎng)站的原因中國建設(shè)網(wǎng)官方網(wǎng)站
  • 制作一個買股票的網(wǎng)站怎么做seo比較好的公司
  • 網(wǎng)站畢業(yè)設(shè)計怎么做網(wǎng)絡(luò)營銷推廣活動有哪些
  • 合伙做網(wǎng)站怎么分配股權(quán)各地疫情最新消息
  • 大連小型網(wǎng)站建設(shè)關(guān)鍵的近義詞
  • 做本地團購網(wǎng)站游戲網(wǎng)站交換友情鏈接
  • 合肥網(wǎng)站建設(shè)找佳達百度seo服務(wù)方案
  • 廣西網(wǎng)站建設(shè)開發(fā)外包市場營銷方案范文5篇
  • 泗陽做網(wǎng)站公司競價托管就選微競價
  • 網(wǎng)站logo用什么做百度網(wǎng)站打不開
  • 網(wǎng)站批量做httpsseo優(yōu)化實訓(xùn)報告
  • 深圳租房建設(shè)局網(wǎng)站天天外鏈官網(wǎng)
  • 淮安建設(shè)工程協(xié)會網(wǎng)站查詢站長之家 seo查詢
  • 淄博網(wǎng)站制作seo優(yōu)化專員
  • 在什么網(wǎng)站可以自承包活來做搜索引擎入口
  • 廈門功夫廣告設(shè)計網(wǎng)站建設(shè)工作室網(wǎng)站優(yōu)化排名資源
  • 市總工會智慧網(wǎng)站建設(shè)總結(jié)奶茶的營銷推廣軟文
  • 綿陽 網(wǎng)站設(shè)計推廣引流哪個軟件最好
  • 新疆網(wǎng)站建設(shè)一條龍服務(wù)網(wǎng)絡(luò)營銷產(chǎn)品的首選產(chǎn)品
  • 做資訊網(wǎng)站要什么手續(xù)公司怎么推廣網(wǎng)絡(luò)營銷