Python|使用 GUI 进行人脸识别
在本文中,提到了使用Python和 OpenCV 模块实现面部识别系统的一种相当简单的方法,并在评论中逐步解释了代码。
在开始之前,我们需要安装一些库来实现代码。下面您将看到该库的用法以及安装它的代码:
- 开放式简历:
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它旨在为机器学习算法和计算机视觉提供通用基础设施。它有数以千计的优化算法,可以用于不同的目的,如检测和识别面部、识别对象等等。我们需要它使用我们的网络摄像头拍照,并且需要在图像中进行一些操作。
要安装库,您需要在系统中安装 pip 之后,您可以按照命令提示符中的步骤操作:
第 1 步:点安装 opencv-python
第 2 步:点安装 opencv-contrib-python - 数字货币:
NumPy 是Python中科学计算的基础包,它提供了一个多维数组对象,可以使用它执行其他数学运算,但简单地说,我们只需要它来将我们的图像转换为某种形式的数组,以便我们可以存储具有受过训练。
要安装该库,您可以在命令 shell 中键入一行简单的代码:
点安装 numpy - 哈尔级联:
Haar Cascade 基本上是一个分类器,用于从源头检测其训练过的对象。结果是一个存储训练结果的 XML 文件。如果简单地说,Haar Cascade 是通过将正图像叠加在一组负图像上来训练的。培训需要一个高规格的系统和良好的互联网连接以及数千张培训图像,这就是为什么它在服务器中进行。为了提高结果的效率,他们使用高质量的图像并增加训练分类器的阶段数。我们需要 haar 级联正面人脸识别器来检测来自我们网络摄像头的人脸。
要下载不同对象的 haar 级联文件,您可以访问以下链接:
GitHub: HaarCascades - Python GUI(tkinter):
Tkinter 是一个简单的 GUI 模块,用于实现相当简单的 GUI,并帮助我们以简单的方式与代码交互。虽然对于理解代码来说,了解它是如何工作的并不重要。
如果您想了解有关 Tkinter 的更多信息,请单击下面的链接
Python GUI – tkinter
代码: Python实现使用GUI识别人脸
Python3
# importing libraries
import tkinter as tk
from tkinter import Message, Text
import cv2
import os
import shutil
import csv
import numpy as np
from PIL import Image, ImageTk
import pandas as pd
import datetime
import time
import tkinter.ttk as ttk
import tkinter.font as font
from pathlib import Path
window = tk.Tk()
window.title("Face_Recogniser")
window.configure(background ='white')
window.grid_rowconfigure(0, weight = 1)
window.grid_columnconfigure(0, weight = 1)
message = tk.Label(
window, text ="Face-Recognition-System",
bg ="green", fg = "white", width = 50,
height = 3, font = ('times', 30, 'bold'))
message.place(x = 200, y = 20)
lbl = tk.Label(window, text = "No.",
width = 20, height = 2, fg ="green",
bg = "white", font = ('times', 15, ' bold ') )
lbl.place(x = 400, y = 200)
txt = tk.Entry(window,
width = 20, bg ="white",
fg ="green", font = ('times', 15, ' bold '))
txt.place(x = 700, y = 215)
lbl2 = tk.Label(window, text ="Name",
width = 20, fg ="green", bg ="white",
height = 2, font =('times', 15, ' bold '))
lbl2.place(x = 400, y = 300)
txt2 = tk.Entry(window, width = 20,
bg ="white", fg ="green",
font = ('times', 15, ' bold ') )
txt2.place(x = 700, y = 315)
# The function below is used for checking
# whether the text below is number or not ?
def is_number(s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False
# Take Images is a function used for creating
# the sample of the images which is used for
# training the model. It takes 60 Images of
# every new user.
def TakeImages():
# Both ID and Name is used for recognising the Image
Id =(txt.get())
name =(txt2.get())
# Checking if the ID is numeric and name is Alphabetical
if(is_number(Id) and name.isalpha()):
# Opening the primary camera if you want to access
# the secondary camera you can mention the number
# as 1 inside the parenthesis
cam = cv2.VideoCapture(0)
# Specifying the path to haarcascade file
harcascadePath = "data\haarcascade_frontalface_default.xml"
# Creating the classier based on the haarcascade file.
detector = cv2.CascadeClassifier(harcascadePath)
# Initializing the sample number(No. of images) as 0
sampleNum = 0
while(True):
# Reading the video captures by camera frame by frame
ret, img = cam.read()
# Converting the image into grayscale as most of
# the the processing is done in gray scale format
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# It converts the images in different sizes
# (decreases by 1.3 times) and 5 specifies the
# number of times scaling happens
faces = detector.detectMultiScale(gray, 1.3, 5)
# For creating a rectangle around the image
for (x, y, w, h) in faces:
# Specifying the coordinates of the image as well
# as color and thickness of the rectangle.
# incrementing sample number for each image
cv2.rectangle(img, (x, y), (
x + w, y + h), (255, 0, 0), 2)
sampleNum = sampleNum + 1
# saving the captured face in the dataset folder
# TrainingImage as the image needs to be trained
# are saved in this folder
cv2.imwrite(
"TrainingImage\ "+name +"."+Id +'.'+ str(
sampleNum) + ".jpg", gray[y:y + h, x:x + w])
# display the frame that has been captured
# and drawn rectangle around it.
cv2.imshow('frame', img)
# wait for 100 milliseconds
if cv2.waitKey(100) & 0xFF == ord('q'):
break
# break if the sample number is more than 60
elif sampleNum>60:
break
# releasing the resources
cam.release()
# closing all the windows
cv2.destroyAllWindows()
# Displaying message for the user
res = "Images Saved for ID : " + Id +" Name : "+ name
# Creating the entry for the user in a csv file
row = [Id, name]
with open('UserDetails\UserDetails.csv', 'a+') as csvFile:
writer = csv.writer(csvFile)
# Entry of the row in csv file
writer.writerow(row)
csvFile.close()
message.configure(text = res)
else:
if(is_number(Id)):
res = "Enter Alphabetical Name"
message.configure(text = res)
if(name.isalpha()):
res = "Enter Numeric Id"
message.configure(text = res)
# Training the images saved in training image folder
def TrainImages():
# Local Binary Pattern Histogram is an Face Recognizer
# algorithm inside OpenCV module used for training the image dataset
recognizer = cv2.face.LBPHFaceRecognizer_create()
# Specifying the path for HaarCascade file
harcascadePath = "data\haarcascade_frontalface_default.xml"
# creating detector for faces
detector = cv2.CascadeClassifier(harcascadePath)
# Saving the detected faces in variables
faces, Id = getImagesAndLabels("TrainingImage")
# Saving the trained faces and their respective ID's
# in a model named as "trainner.yml".
recognizer.train(faces, np.array(Id))
recognizer.save("TrainingImageLabel\Trainner.yml")
# Displaying the message
res = "Image Trained"
message.configure(text = res)
def getImagesAndLabels(path):
# get the path of all the files in the folder
imagePaths =[os.path.join(path, f) for f in os.listdir(path)]
faces =[]
# creating empty ID list
Ids =[]
# now looping through all the image paths and loading the
# Ids and the images saved in the folder
for imagePath in imagePaths:
# loading the image and converting it to gray scale
pilImage = Image.open(imagePath).convert('L')
# Now we are converting the PIL image into numpy array
imageNp = np.array(pilImage, 'uint8')
# getting the Id from the image
Id = int(os.path.split(imagePath)[-1].split(".")[1])
# extract the face from the training image sample
faces.append(imageNp)
Ids.append(Id)
return faces, Ids
# For testing phase
def TrackImages():
recognizer = cv2.face.LBPHFaceRecognizer_create()
# Reading the trained model
recognizer.read("TrainingImageLabel\Trainner.yml")
harcascadePath = "data\haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(harcascadePath)
# getting the name from "userdetails.csv"
df = pd.read_csv("UserDetails\UserDetails.csv")
cam = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX
while True:
ret, im = cam.read()
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray, 1.2, 5)
for(x, y, w, h) in faces:
cv2.rectangle(im, (x, y), (x + w, y + h), (225, 0, 0), 2)
Id, conf = recognizer.predict(gray[y:y + h, x:x + w])
if(conf < 50):
aa = df.loc[df['Id'] == Id]['Name'].values
tt = str(Id)+"-"+aa
else:
Id ='Unknown'
tt = str(Id)
if(conf > 75):
noOfFile = len(os.listdir("ImagesUnknown"))+1
cv2.imwrite("ImagesUnknown\Image"+
str(noOfFile) + ".jpg", im[y:y + h, x:x + w])
cv2.putText(im, str(tt), (x, y + h),
font, 1, (255, 255, 255), 2)
cv2.imshow('im', im)
if (cv2.waitKey(1)== ord('q')):
break
cam.release()
cv2.destroyAllWindows()
takeImg = tk.Button(window, text ="Sample",
command = TakeImages, fg ="white", bg ="green",
width = 20, height = 3, activebackground = "Red",
font =('times', 15, ' bold '))
takeImg.place(x = 200, y = 500)
trainImg = tk.Button(window, text ="Training",
command = TrainImages, fg ="white", bg ="green",
width = 20, height = 3, activebackground = "Red",
font =('times', 15, ' bold '))
trainImg.place(x = 500, y = 500)
trackImg = tk.Button(window, text ="Testing",
command = TrackImages, fg ="white", bg ="green",
width = 20, height = 3, activebackground = "Red",
font =('times', 15, ' bold '))
trackImg.place(x = 800, y = 500)
quitWindow = tk.Button(window, text ="Quit",
command = window.destroy, fg ="white", bg ="green",
width = 20, height = 3, activebackground = "Red",
font =('times', 15, ' bold '))
quitWindow.place(x = 1100, y = 500)
window.mainloop()
GUI 的示例图像:
文件夹结构供参考: