赞
踩
人脸识别技术已经在许多领域得到了广泛应用,例如安防、金融、医疗等等。人脸识别可以帮助我们识别和验证一个人的身份,这是一项非常重要的任务。本篇博客将介绍如何使用Python和OpenCV库进行人脸识别。我们将学习如何使用OpenCV中的人脸检测器检测图像中的人脸,如何与一个人的图像进行比较以检测是否属于该人,以及如何在GUI中显示识别结果。你可以嵌入到你的程序、机器上。现在,让我们开始学习人脸识别技术吧!
如果你已有python环境和opencv库可直接跳转到代码解读哦
目录
首先,你需要下载和安装Python。可以在Python官方网站上下载最新版本的Python安装程序:https://www.python.org/downloads/windows/请务必下载并安装3.x版本的Python,因为OpenCV不支持Python 2.x。
pip是Python的包管理器,可以轻松地安装、升级和删除Python软件包。可以使用以下命令检查是否已经安装了pip:
pip --version
如果pip没有安装,可以在终端中输入以下命令进行安装:
python -m ensurepip --default-pip
可以使用pip来安装OpenCV:
pip install opencv-python
为了让Python能够找到OpenCV,需要将OpenCV的路径添加到系统的环境变量中。
首先,找到OpenCV安装的路径,一般在Python的安装目录下的Lib\site-packages目录中。例如,在我的电脑上,OpenCV安装在以下目录下:
C:\Users\username\AppData\Local\Programs\Python\Python39\Lib\site-packages\cv2
然后,将这个路径添加到系统的环境变量中。在Windows 10中,可以按以下步骤进行操作:
- import cv2
- print(cv2.__version__)
如果OpenCV已经成功安装,应该会显示OpenCV的版本号。
希望这个简要的教程可以帮助你在Windows上成功安装和配置OpenCV和Python。
这是一个基于 OpenCV 库和 tkinter 库开发的人脸识别程序。它可以从摄像头实时获取视频,并在视频中检测人脸并显示其姓名。
person 文件夹中的某个人匹配的图像。代码中的函数 cv2AddChineseText 用于在图像上添加中文文本。函数 cv2AddChineseText 接受四个参数:
img:要添加文本的图像。text:要添加的文本。position:文本的位置。textColor:文本颜色,默认为绿色。textSize:文本大小,默认为 30。代码中的 person_images 列表用于存储 person 文件夹中的人脸图像。person_names 列表用于存储每个人脸图像对应的姓名。在处理捕获的图像时,程序将检查每个人脸图像是否匹配,并在图像中显示姓名。
该程序主要通过计算机视觉技术实现人脸识别。首先,程序使用OpenCV库中的Haar Cascade分类器来检测输入图像中的人脸。然后,它会将人脸与事先保存在“person”文件夹中的图像进行比较,以确定是否存在匹配的人脸。如果存在匹配的人脸,则程序会在图像中框出人脸并显示相应的姓名。如果不存在匹配的人脸,则程序仅在图像中框出人脸。
下面是程序的主要部分的解释:
- # 加载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)
-
-

我们已经成功地检测出了人脸,并将其框出来。现在我们将探讨如何与person文件夹中的图像进行比较以检测人脸。
首先,我们需要读取person文件夹中的图像和姓名。我们可以使用os模块中的listdir函数列出person文件夹中的所有文件名,然后使用cv2.imread函数读取每个图像。
- 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])
接下来,我们需要将每个person图像转换为灰度图像以进行比较。我们可以使用cv2.cvtColor函数将BGR图像转换为灰度图像。
- for i in range(len(person_images)):
- person_image = person_images[i]
- # 将person图像转换为灰度图像以进行比较
- person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
现在,我们可以使用matchTemplate函数将当前人脸与person图像进行比较,以确定当前人脸是否属于person文件夹中的某个人。matchTemplate函数可以将当前人脸的灰度图像与person图像的灰度图像进行比较,并返回一个相似度矩阵。我们可以使用max方法获取相似度矩阵中的最大值,并将其与一个预设的阈值(例如0.8)进行比较,以确定当前人脸是否与person图像匹配。
- 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()

这段代码将每个检测到的人脸与存储在“person”文件夹中的图像进行比较。如果存在与任何一个图像匹配的人脸,则在该人脸上方框和标注该人的名称。否则,将该人脸框在红色方框内,并标注“Unknown”。(完整代码中没有加入这行,如果需要可以加上)
最后,它将帧显示在GUI窗口中,并等待退出键按下后释放资源并关闭窗口。
在原生的cv2.putText()方法里并不支持中文只能显示英文,在网上查阅了很多方法都不奏效于是我决定重构这个方法:
- 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)
- 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()

人脸识别技术在现代生活中有着广泛的应用,例如人脸解锁手机、人脸识别支付、安防领域等。但是,人脸识别技术还存在一些局限性和改进的空间。
首先,人脸识别技术的准确性受到许多因素的影响,例如光照、姿势、表情、遮挡等。为了提高人脸识别的准确性,可以采用更先进的算法,例如基于深度学习的人脸识别算法。此外,还可以通过采用更好的硬件设备来提高图像采集的质量。
其次,当前的人脸识别技术主要针对单个人脸进行识别,对于多个人脸的情况处理较为困难。为了解决这个问题,可以探索如何将多个人脸的特征进行有效地提取和匹配。
最后,人脸识别技术还涉及到隐私保护等伦理问题。在应用人脸识别技术时,需要注意隐私保护的问题,避免对个人隐私造成侵害。
总的来说,人脸识别技术在未来还有很大的发展空间,随着科技的不断进步,相信人脸识别技术的应用将更加广泛,也将更加普及化和便利化。
人脸识别技术正在广泛应用于各个领域,例如安全监控、人脸支付、人脸解锁等等。本文介绍的人脸识别应用程序只是冰山一角,随着技术的不断发展,我们可以期待更加高效、准确的人脸识别应用程序的出现。如果您对人脸识别技术感兴趣,不妨关注相关的技术发展和应用案例,为您的职业生涯增添一份技术的底气。感谢阅读本文,如果您觉得有用,请点赞、收藏和关注,谢谢啦!!
过几天我会在此基础上加上录入人脸信息的功能,感兴趣的小伙伴不要错过哦。
再次感谢不离不弃的粉丝,之后仍会不定期更新哦~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。