亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

PyQt5+Caffe+Opencv搭建人臉識(shí)別登錄界面

 更新時(shí)間:2022年08月29日 08:45:32   作者:november2011  
這篇文章主要為大家詳細(xì)介紹了PyQt5+Caffe+Opencv搭建人臉識(shí)別登錄界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

最近開(kāi)始學(xué)習(xí)Qt,結(jié)合之前學(xué)習(xí)過(guò)的caffe一起搭建了一個(gè)人臉識(shí)別登錄系統(tǒng)的程序,新手可能有理解不到位的情況,還請(qǐng)大家多多指教。

我的想法是用opencv自帶的人臉檢測(cè)算法檢測(cè)出面部,利用caffe訓(xùn)練好的卷積神經(jīng)網(wǎng)絡(luò)來(lái)提取特征,通過(guò)計(jì)算當(dāng)前檢測(cè)到的人臉與已近注冊(cè)的所有用戶的面部特征之間的相似度,如果最大的相似度大于一個(gè)閾值,就可以確定當(dāng)前檢測(cè)到的人臉對(duì)應(yīng)為這個(gè)相似度最大的用戶了。

###Caffe人臉識(shí)別

因?yàn)椴粩嘤行碌挠脩艏尤?,然而添加新用戶后重新調(diào)整CNN的網(wǎng)絡(luò)結(jié)構(gòu)太費(fèi)時(shí)間,所以不能用CNN去判別一個(gè)用戶屬于哪一類。一個(gè)訓(xùn)練好的人臉識(shí)別網(wǎng)絡(luò)擁有很強(qiáng)大的特征提取能力(例如這里用到的VGG face),我們finetune預(yù)訓(xùn)練的網(wǎng)絡(luò)時(shí)會(huì)調(diào)整最后一層的分類數(shù)目,所以最后一層的目的是為了分類,倒數(shù)第二個(gè)全連接層(或者前面的)提取到的特征通過(guò)簡(jiǎn)單的計(jì)算距離也可以達(dá)到很高的準(zhǔn)確率,因此可以用計(jì)算相似度的方式判斷類別。

載入finetune后的VGG模型

代碼就不詳細(xì)解釋了,我用的是拿1000個(gè)人臉微調(diào)后的VGGface,效果比用直接下載來(lái)的weight文件好一點(diǎn),這里可以用原始的權(quán)重文件代替。

import caffe
model_def = 'VGG_FACE_deploy.prototxt'
model_weights = 'VGG_Face_finetune_1000_iter_900.caffemodel'
# create transformer for the input called 'data'
net = caffe.Net(model_def,   # defines the structure of the model
        model_weights, # contains the trained weights
        caffe.TEST) 
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension
transformer.set_mean('data', np.array([104, 117, 123]))      # subtract the dataset-mean value in each channel
transformer.set_raw_scale('data', 255)   # rescale from [0, 1] to [0, 255]
transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGRxpor

計(jì)算余弦相似度

import numpy as np

# 計(jì)算余弦距離
def cal_cos(A,B):
  num = A.dot(B.T) #若為行向量則 A * B.T
  print(B.shape)
  if B.ndim == 1:
    denom = np.linalg.norm(A) * np.linalg.norm(B)
  else:
    denom = np.linalg.norm(A) * np.linalg.norm(B, axis=1)
  #print(num)
  cos = num / denom #余弦值
  sim = 0.5 + 0.5 * cos #歸一化
  return sim

def cal_feature(image):
  #for i,img_name in enumerate(os.listdir(path)):
    #image = caffe.io.load_image(os.path.join(path,img_name))
  transformed_image = transformer.preprocess('data', image)
  net.blobs['data'].data[0,:,:,:] = transformed_image
  output = net.forward()
  return net.blobs['fc7'].data[0]

cal_feature函數(shù)返回fc7層的輸出,也就是image通過(guò)網(wǎng)絡(luò)提取到的特征;A的維度為[1, 4096],為需要檢測(cè)的目標(biāo),B的維度為[n,4096],表示所有已注冊(cè)的用戶的特征,cal_cos返回n個(gè)相似度,值越大,越可能是同一個(gè)人。

###Opencv人臉檢測(cè)

檢測(cè)人臉位置的算法用了opencv自帶的人臉檢測(cè)器。

import cv2

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

PyQt界面

定義全局變量存儲(chǔ)用戶的信息,提取到的特征,我用文件的形式將這些信息保存到本地,下一次運(yùn)行時(shí)提前載入。

import sys
import os
import pickle
global ALLFEATURE, NEWFEATURE, tempUsrName, ALLUSER, USRNAME

with open('USRNAME.pickle', 'rb') as f:
  USRNAME = pickle.load(f)
with open('ALLUSER.pickle', 'rb') as f:
  ALLUSER = pickle.load(f)

ALLFEATURE = np.load('usrfeature.npy')
NEWFEATURE = np.array([])
tempUsrName = {}

設(shè)計(jì)一個(gè)登錄界面

用PyQt設(shè)計(jì)一個(gè)界面,實(shí)現(xiàn)用戶注冊(cè),注冊(cè)時(shí)錄入照片,用戶密碼登錄,人臉識(shí)別登錄等功能。

創(chuàng)建一個(gè)TabWidget界面

tab1用來(lái)實(shí)現(xiàn)密碼登錄,注冊(cè),tab2用來(lái)實(shí)現(xiàn)人臉識(shí)別登錄。

 

from PyQt5.QtWidgets import (QWidget, QMessageBox, QLabel, QDialog,
  QApplication, QPushButton, QDesktopWidget, QLineEdit, QTabWidget)
from PyQt5.QtGui import QIcon, QPixmap, QImage, QPalette, QBrush
from PyQt5.QtCore import Qt, QTimer

class TabWidget(QTabWidget):

  def __init__(self, parent=None):
    super(TabWidget, self).__init__(parent)
    self.setWindowTitle('Face Recognition')
    self.setWindowIcon(QIcon('camera.png'))
    self.resize(400, 260)
    self.center()
    self.mContent = passWordSign()
    self.mIndex = faceSign()
    self.addTab(self.mContent, QIcon('camera.png'), u"密碼登錄")
    self.addTab(self.mIndex, u"人臉識(shí)別")
    palette=QPalette()
    icon=QPixmap('background.jpg').scaled(400, 260)
    palette.setBrush(self.backgroundRole(), QBrush(icon)) #添加背景圖片
    self.setPalette(palette)

  def center(self):
     
    qr = self.frameGeometry()
    cp = QDesktopWidget().availableGeometry().center()
    qr.moveCenter(cp)
    self.move(qr.topLeft())

  def closeEvent(self, event):
     
    reply = QMessageBox.question(self, 'Message',
      "Are you sure to quit?", QMessageBox.Yes |
      QMessageBox.No, QMessageBox.No)
 
    if reply == QMessageBox.Yes:
      event.accept()
    else:
      event.ignore() 


if __name__ == '__main__':
   
  app = QApplication(sys.argv)
  t = TabWidget()
  t.show()
  #ex = Example()
sys.exit(app.exec_())

用戶注冊(cè)和密碼登錄

分別添加兩個(gè)按鈕和兩個(gè)文本框,文本框用于用戶名和密碼輸入,按鈕分別對(duì)應(yīng)事件注冊(cè)和登錄。addPicture用于注冊(cè)時(shí)錄入用戶照片。

class passWordSign(QWidget):
   
  def __init__(self):
    super().__init__()
     
    self.initUI()
         
  def initUI(self):       
     
    #self.setGeometry(0, 0, 450, 300)    
    self.signUpButton = QPushButton(QIcon('camera.png'), 'Sign up', self)
    self.signUpButton.move(300, 200)
    self.signInButton = QPushButton(QIcon('camera.png'), 'Sign in', self)
    self.signInButton.move(200, 200)
    self.usrNameLine = QLineEdit( self )
    self.usrNameLine.setPlaceholderText('User Name')
    self.usrNameLine.setFixedSize(200, 30)
    self.usrNameLine.move(100, 50)
    self.passWordLine = QLineEdit(self)
    self.passWordLine.setEchoMode(QLineEdit.Password) 
    self.passWordLine.setPlaceholderText('Pass Word')
    self.passWordLine.setFixedSize(200, 30)
    self.passWordLine.move(100, 120)
    self.signInButton.clicked.connect(self.signIn)
    self.signUpButton.clicked.connect(self.signUp)
    self.show()

  def signIn(self):
    global ALLFEATURE, NEWFEATURE, tempUsrName, ALLUSER, USRNAME
    if self.usrNameLine.text() not in ALLUSER:
      QMessageBox.information(self,"Information","用戶不存在,請(qǐng)注冊(cè)")
    elif ALLUSER[self.usrNameLine.text()] == self.passWordLine.text():
      QMessageBox.information(self,"Information","Welcome!")

    else:
      QMessageBox.information(self,"Information","密碼錯(cuò)誤!")

  def signUp(self):
    global ALLFEATURE, NEWFEATURE, tempUsrName, ALLUSER, USRNAME
    if self.usrNameLine.text() in ALLUSER:
      QMessageBox.information(self,"Information","用戶已存在!")
    elif len(self.passWordLine.text()) < 3:
      QMessageBox.information(self,"Information","密碼太短!")
    else:
      tempUsrName.clear()
      tempUsrName[self.usrNameLine.text()] = self.passWordLine.text()
      self.addPicture()
      

  def addPicture(self):
    dialog = Dialog(parent=self)
    dialog.show()

錄入用戶人臉

點(diǎn)擊sign up按鈕后彈出一個(gè)對(duì)話框,用一個(gè)label控件顯示攝像頭獲取的照片。首先用opencv打開(kāi)攝像頭,用自帶的人臉檢測(cè)器檢測(cè)到人臉self.face后,繪制一個(gè)藍(lán)色的框,然后resize到固定的大?。▽?duì)應(yīng)網(wǎng)絡(luò)的輸入)。將opencv的圖片格式轉(zhuǎn)換為Qlabel可以顯示的格式,用Qtimer定時(shí)器每隔一段時(shí)間刷新圖片。檢測(cè)鼠標(biāo)點(diǎn)擊事件mousePressEvent,點(diǎn)擊鼠標(biāo)后保存當(dāng)前錄入的用戶注冊(cè)信息和對(duì)應(yīng)的特征。關(guān)閉攝像頭,提示注冊(cè)成功。

class Dialog(QDialog):
  def __init__(self, parent=None):
    QDialog.__init__(self, parent)
    self.resize(240, 200)
    self.label = QLabel(self) 
    self.label.setFixedWidth(150) 
    self.label.setFixedHeight(150) 
    self.label.move(40, 20)
    pixMap = QPixmap("face.jpg").scaled(self.label.width(),self.label.height()) 
    self.label.setPixmap(pixMap)
    self.label.show()
    self.timer = QTimer()
    self.timer.start()
    self.timer.setInterval(100)
    self.cap = cv2.VideoCapture(0)
    self.timer.timeout.connect(self.capPicture)

  def mousePressEvent(self, event):
    global ALLFEATURE, NEWFEATURE, tempUsrName, ALLUSER, USRNAME 
    self.cap.release()
    NEWFEATURE = cal_feature(self.face).reshape([1,-1])
    if NEWFEATURE.size > 0:
      for key, value in tempUsrName.items():
        ALLUSER[key] = value
        USRNAME.append(key)
        with open('ALLUSER.pickle', 'wb') as f:
          pickle.dump(ALLUSER, f)
        with open('USRNAME.pickle', 'wb') as f:
          pickle.dump(USRNAME, f)
        print(ALLFEATURE,NEWFEATURE)
        ALLFEATURE = np.concatenate((ALLFEATURE, NEWFEATURE), axis=0)
        np.save('usrfeature.npy', ALLFEATURE)
        QMessageBox.information(self,"Information","Success!")


  def capPicture(self):
    
    if (self.cap.isOpened()):
      # get a frame
      ret, img = self.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),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        self.face = cv2.resize(img[y:y+h, x:x+w],(224, 224), interpolation=cv2.INTER_CUBIC)
      height, width, bytesPerComponent = img.shape
      bytesPerLine = bytesPerComponent * width
      # 變換彩色空間順序
      cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img)
      # 轉(zhuǎn)為QImage對(duì)象
      self.image = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888)
      self.label.setPixmap(QPixmap.fromImage(self.image).scaled(self.label.width(),self.label.height()))

人臉識(shí)別登錄

登錄部分與之前類似,添加一個(gè)label控件用來(lái)顯示圖片,兩個(gè)按鈕用來(lái)開(kāi)始檢測(cè)和選定圖片。當(dāng)最大的相似度大于0.9時(shí),顯示登錄成功。

 

class faceSign(QWidget):
   
  def __init__(self):
    super().__init__()
     
    self.initUI()
       
  def initUI(self):
    self.label = QLabel(self) 
    self.label.setFixedWidth(260) 
    self.label.setFixedHeight(200) 
    self.label.move(20, 15)
    self.pixMap = QPixmap("face.jpg").scaled(self.label.width(),self.label.height()) 
    self.label.setPixmap(self.pixMap)
    self.label.show()
    self.startButton = QPushButton('start', self)
    self.startButton.move(300, 50)
    self.capPictureButton = QPushButton('capPicture', self)
    self.capPictureButton.move(300, 150)
    self.startButton.clicked.connect(self.start)
    self.capPictureButton.clicked.connect(self.cap)
    #self.cap = cv2.VideoCapture(0)
    #self.ret, self.img = self.cap.read()
    self.timer = QTimer()
    self.timer.start()
    self.timer.setInterval(100)
    
    

  def start(self,event):
    self.cap = cv2.VideoCapture(0)
    self.timer.timeout.connect(self.capPicture)

  def cap(self,event):
    global ALLFEATURE, NEWFEATURE, tempUsrName, ALLUSER, USRNAME
    self.cap.release()
    feature = cal_feature(self.face)
    #np.save('usrfeature.npy', ALLFEATURE)
    sim = cal_cos(feature,np.array(ALLFEATURE))
    m = np.argmax(sim)
    if max(sim)>0.9:
      print(sim, USRNAME)
      QMessageBox.information(self,"Information","Welcome," + USRNAME[m])
    else:
      QMessageBox.information(self,"Information","識(shí)別失敗!")
    self.label.setPixmap(self.pixMap)
   
  def capPicture(self):
    
    if (self.cap.isOpened()):
      # get a frame
      ret, img = self.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),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        self.face = cv2.resize(img[y:y+h, x:x+w],(224, 224), interpolation=cv2.INTER_CUBIC)
      height, width, bytesPerComponent = img.shape
      bytesPerLine = bytesPerComponent * width
      # 變換彩色空間順序
      cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img)
      # 轉(zhuǎn)為QImage對(duì)象
      self.image = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888)
      self.label.setPixmap(QPixmap.fromImage(self.image).scaled(self.label.width(),self.label.height()))

###效果

密碼登錄,輸入合法的密碼后點(diǎn)擊sign in,顯示歡迎。

注冊(cè)界面

識(shí)別界面

登錄成功

點(diǎn)擊capPicture按鈕后,開(kāi)始計(jì)算相似度,大于0.9提示登錄成功,并顯示用戶名。

###缺點(diǎn)和不足

程序用pyinstaller打包后,親測(cè)可以在別的linux電腦下運(yùn)行。代碼和文件可以參考我的Github(沒(méi)有VGG face的權(quán)重),第一次寫博客,非常感謝大家的意見(jiàn)??偨Y(jié)一下不足:

1.初始話caffe模型很費(fèi)時(shí)間,所以程序打開(kāi)時(shí)要等一兩秒;
2.用戶信息用文件的形式保存并不安全,可以用mysql保存到數(shù)據(jù)庫(kù),需要時(shí)調(diào)出;
3.人臉位置檢測(cè)可以用faster rcnn代替,再加上對(duì)齊;
4.識(shí)別很耗費(fèi)時(shí)間,因此不能實(shí)時(shí)檢測(cè),應(yīng)該可以用多線程解決。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python神經(jīng)網(wǎng)絡(luò)VGG16模型復(fù)現(xiàn)及其如何預(yù)測(cè)詳解

    python神經(jīng)網(wǎng)絡(luò)VGG16模型復(fù)現(xiàn)及其如何預(yù)測(cè)詳解

    這篇文章主要為大家介紹了VGG16模型的復(fù)現(xiàn)及其詳解(包含如何預(yù)測(cè)),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • python 消除 futureWarning問(wèn)題的解決

    python 消除 futureWarning問(wèn)題的解決

    今天小編就為大家分享一篇python 消除 futureWarning問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • 使用Python中的tkinter模塊作圖的方法

    使用Python中的tkinter模塊作圖的方法

    Python是一種解釋型、面向?qū)ο?、?dòng)態(tài)數(shù)據(jù)類型的高級(jí)程序設(shè)計(jì)語(yǔ)言。tkinter模塊(“Tk 接口”)是Python的標(biāo)準(zhǔn)Tk GUI工具包的接口。接下來(lái)通過(guò)本文給大家介紹Python中的tkinter模塊作圖教程,需要的朋友參考下
    2017-02-02
  • scrapy利用selenium爬取豆瓣閱讀的全步驟

    scrapy利用selenium爬取豆瓣閱讀的全步驟

    這篇文章主要給大家介紹了關(guān)于scrapy利用selenium爬取豆瓣閱讀的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • python?判斷字符串當(dāng)中是否包含字符(str.contain)

    python?判斷字符串當(dāng)中是否包含字符(str.contain)

    這篇文章主要介紹了python?判斷字符串當(dāng)中是否包含字符(str.contain),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • pycharm必知的一些簡(jiǎn)單設(shè)置方法

    pycharm必知的一些簡(jiǎn)單設(shè)置方法

    這篇文章主要介紹了pycharm必知的一些簡(jiǎn)單設(shè)置方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • PyQt5創(chuàng)建一個(gè)新窗口的實(shí)例

    PyQt5創(chuàng)建一個(gè)新窗口的實(shí)例

    今天小編就為大家分享一篇PyQt5創(chuàng)建一個(gè)新窗口的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • Python對(duì)象體系深入分析

    Python對(duì)象體系深入分析

    這篇文章主要介紹了Python對(duì)象體系,以實(shí)例的形式進(jìn)行了較為深入的分析,需要的朋友可以參考下
    2014-10-10
  • python實(shí)現(xiàn)批量解析郵件并下載附件

    python實(shí)現(xiàn)批量解析郵件并下載附件

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)批量解析郵件并下載附件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Python分割單詞和轉(zhuǎn)換命名法的實(shí)現(xiàn)

    Python分割單詞和轉(zhuǎn)換命名法的實(shí)現(xiàn)

    本文主要介紹了Python分割單詞和轉(zhuǎn)換命名法的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03

最新評(píng)論