当前位置: 首页 > news >正文

建筑兔零基础自学python记录22|实战人脸识别项目——视频人脸识别(下)11

这次我们继续解读代码,我们主要来看下面两个部分;

至于人脸识别成功的要点我们在最后总结~

具体代码学习:

#定义人脸名称
def name():
    #预学习照片存放位置
    path = 'M:/python/workspace/PythonProject/face/'
    imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
    for imagePath in imagePaths:
       name = str(os.path.split(imagePath)[1].split('.',2)[1])
       names.append(name)

(1)os.path.join()协调文件路径中'/'   '\'差异

     将多个路径组件智能地拼接成一个完整的路径。由于不同操作系统的差异,os.path.join() 可以根据当前操作系统自动处理这些差异。

补充:不同操作系统使用不同的路径分隔符。

           Windows 使用反斜杠 \,Unix/Linux 和 macOS 使用正斜杠 /

#举例:
import os

# 拼接路径
path = os.path.join('home', 'user', 'documents')
print(path)
  • 在 Windows 系统上,输出可能是 home\user\documents
  • 在 Unix/Linux 或 macOS 系统上,输出为 home/user/documents

(2)os.listdir()输出某目录下所有文件名

即os.listdir(path)获得了['1.lss.jpg', '2.lss.jpg']

os.path.join()将路径M:\python\workspace\PythonProject\face替换为

M:/python/workspace/PythonProject/face/1.lss.jpg

M:/python/workspace/PythonProject/face/2.lss.jpg

  • os.path.join(path, f)这里path 是前面指定的目录路径,fos.listdir(path) 返回列表中的每个元素(即文件或文件夹名称)。
  • 代码比较长,我们来看一下这个循环的内容:

      这行代码遍历 os.listdir(path) 返回的列表,对每个文件名 调用 os.path.join(path, f) 进行路径拼接,最终将所有拼接好的完整路径组成一个新的列表。

    我们可以把整段代码的阅读顺序做如下表达:

让我们继续解读:

  for imagePath in imagePaths:
       name = str(os.path.split(imagePath)[1].split('.',2)[1])
       names.append(name) 

for imagePath in imagePaths是在刚形成的imagePath列表里自己进行循环

(3)os.path.split()将一个文件路径拆分为目录部分和文件名部分。

  • 通过上一个代码我们获取了imagePath=M:/python/workspace/PythonProject/face/1.lss.jpg
  • os.path.split(imagePath)就是把M:/python/workspace/PythonProject/face/1.lss.jpg拆为:
  • 文件目录M:/python/workspace/PythonProject/face/
  • 文件名1.lss.jpg

os.path.split(imagePath)[1]是从文件目录和文件名中获取第二个文件名,即1.lss.jpg

补充:这里的第二个元素是因为列表、元组和字符串的索引都是从 0 开始,即[0]代表首位,[1]代表第二个,以此类推。

(4)split() 将字符串按照指定的分隔符分割成多个子字符串,并返回一个包含这些子字符串的列表

str.split(sep=None, maxsplit=-1)
  • sep:可选参数,指定分隔符。如果不提供该参数,默认使用空白字符(空格、制表符、换行符等)作为分隔符。
  • maxsplit:可选参数,指定最大分割次数。如果不提供该参数,表示不限制分割次数。

  • split('.', 2)的含义就是分隔符为 . 最多分隔2次。

  • '1.lss.jpg' 调用 split( ) 后,会得到列表 ['1', 'lss', 'jpg']

  • split('.',2)[1]这里从文件名1.lss.jpg中取出第二个元素,即lss

整行代码解读为:

(5)append()在列表的末尾添加一个新元素

list.append(object)
  • list:表示要操作的列表对象。
  • object:表示要添加到列表末尾的任意 Python 对象,比如字符串、整数、列表、元组等。

names.append(name)这里就是把开头创建的names列表填进了内容name

解读主函数:

内容我们都学过,就直接标注了

#打开视频test3.mp4读取每一帧
cap=cv2.VideoCapture('test3.mp4')
#调用自定义name函数
name()
while True:
    #读取视频里的帧
    flag,frame=cap.read()
    #如果没有帧则中断
    if not flag:
        break
    #调用自定义face_detect_demo函数,进行人脸识别和标注
    face_detect_demo(frame)
    if ord(' ') == cv2.waitKey(10):
        break

 (5)全部代码解读为:

import cv2
#导入与操作系统交互 os 模块
import os

#创建一个 LBPH(局部二值模式直方图)人脸识别器对象,用于训练和识别人脸。
recogizer=cv2.face.LBPHFaceRecognizer_create()
#读取训练好的人脸识别模型yml文件
recogizer.read('M:/python/workspace/PythonProject/trainer/trainer.yml')
#初始化一个空列表names,用于存储人脸对应的名称。
names=[]
#初始化一个全局变量warningtime,用于记录未知人脸出现的次数。
warningtime = 1

#自定义人脸识别
def face_detect_demo(img):
    #彩图转化为灰图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #调用人脸识别分类器
    face_detector=cv2.CascadeClassifier('M:/python/pythoninstall/Lib/site-packages/cv2/data/haarcascade_frontalface_alt.xml')
    #灰图中检测人脸
    face=face_detector.detectMultiScale(gray)
    for x,y,w,h in face:
        #原彩图中用红色矩形框人脸
        cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
        #人脸中心画绿圆
        cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1)
        #识别输入人脸,获取标签ids,置信度confidence
        ids, confidence = recogizer.predict(gray[y:y + h, x:x + w])
        #如果置信度confidence>80
        if confidence > 80:
            #warningtime作为全局变量
            global warningtime
            #每次出现都+1
            warningtime += 1
            #控制台输出warningtime=,值为warningtime
            print('warningtime=',warningtime)
            #图像上绘制文本,文本是unknown,位置是x向右偏移10个像素。y向上偏移10个像素,字体无衬线,字体大小0.75,绿色
            cv2.putText(img, 'unknown', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
        else:
            #图像上绘制文本,文本是names列表中的,其余同上
            #坐标移动规律:+ 号撒腿右下跑,- 号转身左上飘
            cv2.putText(img,str(names[ids - 1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
    #弹出窗口名为result
    cv2.imshow('result',img)

#定义人脸名称
def name():
    #预学习照片存放位置
    path = 'M:/python/workspace/PythonProject/face/'
    #获取path路径下文件名,将文件名+路径拼接完整路径,将完整路径存到imagePaths中
    imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
    for imagePath in imagePaths:
       #获取文件名中的一部分作为name,即name=lss
       name = str(os.path.split(imagePath)[1].split('.',2)[1])
       #将提取出的人脸名称 name 添加到 names 列表中
       names.append(name)

#打开视频test3.mp4读取每一帧
cap=cv2.VideoCapture('test3.mp4')
#调用自定义name函数
name()
while True:
    #读取视频里的帧
    flag,frame=cap.read()
    #如果没有帧则中断
    if not flag:
        break
    #调用自定义face_detect_demo函数,进行人脸识别和标注
    face_detect_demo(frame)
    if ord(' ') == cv2.waitKey(10):
        break

cv2.destroyAllWindows()
cap.release()
print(names)

(6)人脸识别成功的要点

   本次识别我们用两张人像即实现了人脸识别,这有赖于LBPH分类器的局部特征特性,少量图片即可识别。同时在素材选择中刻意选择了差异较大的人物,且目标人像的角度基本一致而检测任务则为其他角度。如果想提升识别准确性目前我所了解的一个是提升训练样本量,更改分类器或者用其他方式进行识别。在实验中我尝试了用130多张图用LBPH分类器,但训练效果不佳。所以目前的成果对于材料的选择有较高的要求。

(7)补充[]和()的区别

  1. 方括号 [] 用于表示列表(list)。列表是一种可变的、有序的数据集合,列表支持元素的添加、删除、修改等操作
  2. 方括号 [] 用于索引和切片操作
my_list = [1, 'apple', True]

my_list = [1, 2, 3, 4, 5]
# 索引操作,获取第一个元素
first_element = my_list[0]

# 切片操作,获取第 2 到第 4 个元素
sub_list = my_list[1:4]
print(sub_list)  # 输出: [2, 3, 4]

my_tuple = (1, 2, 3, 4, 5)
# 元组的索引操作
first_tuple_element = my_tuple[0]
print(first_tuple_element)  # 输出: 1

squares = [i**2 for i in range(1, 6)]
  1. 圆括号 () 用于表示元组(tuple)。元组是一种不可变的、有序的数据集合,一旦创建就不能修改其元素
  2. 圆括号 () 用于函数调用。调用函数时,需要使用圆括号将参数括起来。如果函数不需要参数,也需要使用空的圆括号。
my_tuple = (1, 'apple', True)

def greet(name):

def say_hi():

综上大部分情况都使用圆括号()

(8)总结

  • os.path.join()协调文件路径中/\差异
  • os.listdir()输出某目录下所有文件名
  • os.path.split()将一个文件路径拆分为目录部分和文件名部分
  • split() 将字符串按照指定的分隔符分割成多个子字符串,并返回一个包含这些子字符串的列表
  • append()在列表的末尾添加一个新元素

相关文章:

  • 2526考研资料分享 百度网盘
  • 【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter2-HTML 中的 JavaScript
  • 介绍一下 Octave
  • BGP配置华为——RR反射器配置
  • shell——分支语句
  • Docker安装Kafka(不依赖ZooKeeper)
  • 【第10章:自然语言处理高级应用—10.3 NLP在智能客服、舆情分析与情感倾向判断中的应用案例】
  • 关于前后端分离跨域问题——使用DeepSeek分析查错
  • ChatGPT行业热门应用提示词案例-AI绘画类
  • Spring Web MVC入门
  • 分布式事务
  • 【吾爱出品】 视频批量分段工具
  • 438 找到字符串中所有的字母异位词
  • 04性能监控与调优篇(D1_学习前言)
  • 如何利用OGG WEB页面进行MySQL数据库数据复制的配置
  • HTML之JavaScript常见事件
  • 4.buuctf [SWPU2019]Web1及知识点
  • matlab基于梯度下降和软阈值化的去噪算法
  • 民用无人驾驶航空器操控员考试
  • C#: String s = new String(“Hello“)无法编译?编程语言字符集有两个?为什么这种变量名“\u0061\u0062”都能编译通过?
  • 证监会:坚决拥护党中央对王建军进行纪律审查和监察调查决定
  • 中国科学院院士张泽民已任重庆医科大学校长
  • “铁血防守”制造8年最快丢球,恐惧中的阿森纳什么也做不了
  • 神舟十九号载人飞船因东风着陆场气象原因推迟返回
  • 美航母一战机坠海,美媒:为躲避胡塞武装攻击,损失超六千万美元
  • 西湖大学独家回应本科招生走出浙江:经过三年试点,条件成熟