Python implements face recognition based on opencv and tkinter [complete code attached]

Foreword:

Face recognition technology has been widely used in many fields, such as security, finance, medical care and so on. Facial recognition can help us identify and verify a person's identity, which is a very important task. This blog will introduce how to use Python and OpenCV library for face recognition. We will learn how to detect faces in an image using the face detector in OpenCV, how to compare with an image of a person to detect if it belongs to that person, and how to display the recognition results in a GUI. You can embed it in your program, on your machine. Now, let's start learning face recognition technology!

If you already have a python environment and an opencv library, you can jump directly to the code interpretation


Table of contents

Foreword:

Environment construction:

Install Python

install pip

Install OpenCV

Configure environment variables

code interpretation

The general flow of the program is as follows:

Load the Haar Cascade classifier for face detection.

Turn on the camera and capture live images.

Loop through captured images:

Closes the camera and destroys the window.

code analysis

Compare with images in person folder to detect faces

 cv2AddChineseText method

 full code


Environment construction:

Install Python

First, you need to download and install Python. The latest version of the Python installer can be downloaded on the Python official website: https://www.python.org/downloads/windows/ Be sure to download and install the 3.x version of Python, because OpenCV does not support Python 2.x.

install pip

pip is a package manager for Python that makes it easy to install, upgrade, and remove Python packages. You can check if pip is installed with the following command:

pip --version

 If pip is not installed, you can enter the following command in the terminal to install it:

python -m ensurepip --default-pip

Install OpenCV

OpenCV can be installed using pip:

pip install opencv-python

Configure environment variables

In order for Python to find OpenCV, the path of OpenCV needs to be added to the environment variables of the system.

First, find the path of OpenCV installation, usually in the Lib\site-packages directory under the Python installation directory. For example, on my computer, OpenCV is installed in the following directory:

C:\Users\username\AppData\Local\Programs\Python\Python39\Lib\site-packages\cv2

Then, add this path to your system's environment variables. In Windows 10, it can be done as follows:

  1. Enter "Environment Variables" in the Windows search bar, and click "Edit System Environment Variables";
  2. Under the "Advanced" tab, click the "Environment Variables" button;
  3. Find the "Path" variable under "System Variables", and click the "Edit" button;
  4. In the "Edit Environment Variables" dialog box, click the "New" button and add the OpenCV path to it.
  5. Test OpenCV
  6. Finally, you can test whether OpenCV has been installed correctly. You can enter the following code in the terminal:
import cv2 
print(cv2.__version__)

If OpenCV has been successfully installed, the version number of OpenCV should be displayed.

Hope this brief tutorial helps you to successfully install and configure OpenCV and Python on Windows.

code interpretation

This is a face recognition program developed based on OpenCV library and tkinter library. It can get video from the camera in real time, detect faces in the video and display their names.

The general flow of the program is as follows:

  1. Load the Haar Cascade classifier for face detection.

  2. Turn on the camera and capture live images.

  3. Loop through captured images:

    1. Convert the image to a grayscale image.
    2. Detect faces using Haar Cascade classifier.
    3. If a face is detected, finds if there personis an image that matches a person in the folder.
    4. If a matching face is found, the face is framed in the image and the name is displayed.
    5. If no matching face is found, the face is framed in the image without the name.
    6. Convert the image to PIL Image format for display in the GUI.
    7. Update labels to display images.
    8. Handle GUI events to avoid program hangs.
  4. Closes the camera and destroys the window.

The function in the code cv2AddChineseTextis used to add Chinese text on the image. The function cv2AddChineseTextaccepts four parameters:

  • img: The image to add text to.
  • text: The text to add.
  • position: The position of the text.
  • textColor: Text color, the default is green.
  • textSize: Text size, default is 30.

person_imagesThe list in the code is used to store personthe face images in the folder. person_namesThe list is used to store the name corresponding to each face image. While processing the captured images, the program checks each face image for a match and displays the name in the image.

code analysis

The program mainly realizes face recognition through computer vision technology. First, the program uses the Haar Cascade classifier from the OpenCV library to detect faces in the input image. It then compares the face to images previously saved in the "person" folder to see if there is a matching face. If there is a matching face, the program frames the face in the image and displays the corresponding name. If no matching face exists, the program simply frames the face in the image.

Here is an explanation of the main parts of the program:

# 加载Haar Cascade分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 打开摄像头并捕获实时图像
cap = cv2.VideoCapture(0)

# 读取person文件夹中的图像和姓名
person_images = []
person_names = []
for filename in os.listdir('person'):
    if filename.endswith('.jpg'):
        # 使用utf-8编码打开文件
        with open(os.path.join('person', filename), 'rb') as f:
            person_images.append(cv2.imdecode(np.frombuffer(f.read(), np.uint8), cv2.IMREAD_COLOR))
        person_names.append(os.path.splitext(filename)[0])

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 转换图像格式以进行人脸检测
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 使用Haar Cascade分类器检测人脸
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

    # 在图像中框出检测到的人脸
    for (x, y, w, h) in faces:
        # 检查人脸是否属于person文件夹中的某个人
        found_person = False
        for i in range(len(person_images)):
            person_image = person_images[i]
            person_name = person_names[i]
            # 将person图像转换为灰度图像以进行比较
            person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
            # 检查是否存在与person图像相匹配的人脸
            match = cv2.matchTemplate(gray[y:y + h, x:x + w], person_gray, cv2.TM_CCOEFF_NORMED)
            if match.max() > 0.8:
                # 如果找到匹配的人脸,则将其标记为“found_person”,并绘制人脸框
                found_person = True
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                # 在人脸框上方写出人名
                cv2.putText(frame, person_name, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
                break
        if not found_person:
            # 如果没有找到匹配的人脸,则将其标记为“unknown”,并绘制人脸框
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
            cv2.putText(frame, 'unknown', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)

          

Compare with images in person folder to detect faces

We have successfully detected the face and framed it. Now we will explore how to compare with the images in the person folder to detect faces.

First, we need to read the image and name in the person folder. We can use the listdir function in the os module to list all the filenames in the person folder, and then use the cv2.imread function to read each image.

import os

person_folder = 'person'
person_images = []
person_names = []

# 获取person文件夹中的所有文件名
for filename in os.listdir(person_folder):
    # 如果文件名以'.jpg'或'.png'结尾,则读取该图像并将其添加到person_images列表中
    if filename.endswith('.jpg') or filename.endswith('.png'):
        image = cv2.imread(os.path.join(person_folder, filename))
        person_images.append(image)
        # 使用文件名中的数字作为该人员的姓名
        person_names.append(filename.split('.')[0])

Next, we need to convert each person image to a grayscale image for comparison. We can convert a BGR image to a grayscale image using the cv2.cvtColor function.

for i in range(len(person_images)):
    person_image = person_images[i]
    # 将person图像转换为灰度图像以进行比较
    person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)

Now, we can use the matchTemplate function to compare the current face with the person image to determine if the current face belongs to someone in the person folder. The matchTemplate function can compare the grayscale image of the current face with the grayscale image of the person image and return a similarity matrix. We can use the max method to obtain the maximum value in the similarity matrix, and compare it with a preset threshold (such as 0.8) to determine whether the current face matches the person image. 

    for (x, y, w, h) in faces:
        # 检查人脸是否属于person文件夹中的某个人
        found_person = False
        for i in range(len(person_images)):
            person_image = person_images[i]
            person_name = person_names[i]
            # 将person图像转换为灰度图像以进行比较
            person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
            # 检查是否存在与person图像相匹配的人脸
            match = cv2.matchTemplate(gray[y:y + h, x:x + w], person_gray, cv2.TM_CCOEFF_NORMED)
            if match.max() > 0.8:
                found_person = True
                # 将人物名称绘制在检测到的人脸上
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                cv2.putText(frame, person_name, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
                break

        # 如果找不到相应的人物,则将“Unknown”绘制在检测到的人脸上
        if not found_person:
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
            cv2.putText(frame, 'Unknown', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
        
    # 将帧显示在窗口中
    cv2.imshow('Face Recognition', frame)
    
    # 等待退出键
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()

This code compares each detected face to the images stored in the "person" folder. If there is a face matching any of the images, the face is framed and the person's name is labeled. Otherwise, frame the face in the red box and mark "Unknown". (This line is not included in the complete code, but can be added if necessary)

Finally, it displays the frame in a GUI window and waits for the escape key to be pressed to release resources and close the window.

 cv2AddChineseText method

The original cv2.putText() method does not support Chinese and can only display English. Many methods found on the Internet did not work, so I decided to refactor this method:

def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(img)
    # 字体的格式
    fontStyle = ImageFont.truetype(
        "simsun.ttc", textSize, encoding="utf-8")
    # 绘制文本
    draw.text(position, text, textColor, font=fontStyle)
    # 转换回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

 full code

import cv2
import os
import tkinter as tk
from PIL import Image, ImageTk,ImageDraw
import numpy as np

from PIL import ImageFont

def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(img)
    # 字体的格式
    fontStyle = ImageFont.truetype(
        "simsun.ttc", textSize, encoding="utf-8")
    # 绘制文本
    draw.text(position, text, textColor, font=fontStyle)
    # 转换回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

# 加载自定义字体
font = ImageFont.truetype(r"C:\Users\ge\Desktop\test1\Cuesor\msyh.ttc", size=30)

# 加载Haar Cascade分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 创建GUI窗口
root = tk.Tk()
root.geometry('640x480')
root.title('人脸识别')

# 创建标签用于显示图像
image_label = tk.Label(root)
image_label.pack()

# 打开摄像头并捕获实时图像
cap = cv2.VideoCapture(0)

# 创建 PhotoImage 对象
photo = None

# 读取person文件夹中的图像和姓名
person_images = []
person_names = []
for filename in os.listdir('person'):
    if filename.endswith('.jpg'):
        # 使用utf-8编码打开文件
        with open(os.path.join('person', filename), 'rb') as f:
            person_images.append(cv2.imdecode(np.frombuffer(f.read(), np.uint8), cv2.IMREAD_COLOR))
        person_names.append(os.path.splitext(filename)[0])


# 循环处理摄像头捕获的图像
while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 转换图像格式以进行人脸检测
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 使用Haar Cascade分类器检测人脸
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

    # 在图像中框出检测到的人脸
    for (x, y, w, h) in faces:
        # 检查人脸是否属于person文件夹中的某个人
        found_person = False
        for i in range(len(person_images)):
            person_image = person_images[i]
            person_name = person_names[i]
            # 将person图像转换为灰度图像以进行比较
            person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
            # 检查是否存在与person图像相匹配的人脸
            match = cv2.matchTemplate(gray[y:y + h, x:x + w], person_gray, cv2.TM_CCOEFF_NORMED)
            if match.max() > 0.8:
                print(person_name)
                found_person = True
                # 在图像中框出人脸并显示姓名
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
                # 在图像中框出人脸并显示姓名
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
                frame = cv2AddChineseText(frame, person_name, (x + (w/2)-10, y - 30), (0, 255, 255), 30)
                break

        # 如果没有找到匹配的人脸,则在图像中框出人脸但不显示姓名
        if not found_person:
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

    # 将图像转换为PIL Image格式以在GUI中显示

    image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    photo = ImageTk.PhotoImage(image)

    # 更新标签以显示图像
    image_label.configure(image=photo)
    image_label.image = photo

    # 处理GUI事件以避免程序挂起
    root.update()
#关闭摄像头并销毁窗口
cap.release()
cv2.destroyAllWindows()

Face recognition technology has a wide range of applications in modern life, such as face unlocking mobile phones, face recognition payment, security fields, etc. However, face recognition technology still has some limitations and room for improvement.

First of all, the accuracy of face recognition technology is affected by many factors, such as lighting, posture, expression, occlusion, etc. In order to improve the accuracy of face recognition, more advanced algorithms can be used, such as face recognition algorithms based on deep learning. In addition, the quality of image acquisition can be improved by adopting better hardware equipment.

Secondly, the current face recognition technology mainly recognizes a single face, and it is difficult to deal with the situation of multiple faces. In order to solve this problem, we can explore how to effectively extract and match the features of multiple faces.

Finally, face recognition technology also involves ethical issues such as privacy protection. When applying face recognition technology, it is necessary to pay attention to the issue of privacy protection to avoid infringement of personal privacy.

In general, face recognition technology still has a lot of room for development in the future. With the continuous advancement of technology, it is believed that the application of face recognition technology will be more extensive, and it will also become more popular and convenient.

Face recognition technology is being widely used in various fields, such as security monitoring, face payment, face unlocking and so on. The face recognition applications introduced in this article are just the tip of the iceberg. As technology continues to develop, we can expect more efficient and accurate face recognition applications to emerge. If you are interested in face recognition technology, you may wish to pay attention to relevant technology development and application cases, so as to add a technical confidence to your career. Thanks for reading this article, if you find it useful, please like, bookmark and follow, thank you! !

In a few days, I will add the function of entering face information on this basis, and interested friends should not miss it.

Thanks again to the fans who never leave, and will continue to update from time to time~~

 

Guess you like

Origin blog.csdn.net/m0_62814033/article/details/129807611