人脸识别分类,看了就会

想不到吧,大四下学期还有课。/(ㄒoㄒ)/~~

课程中有个大作业研讨弄一个跟人工智能相关的东西,想来想去决定做一个人脸识别相关的东西。由于是第一次弄这一方面的,还有很多都不太会,结合了c站里各位大佬的成果,最后弄了个自己想要的样子,废话不多说,开整!

在我的理解中人脸识别分为三个步骤,第一个是获取人脸信息,第二个是训练自己的模型,第三个是识别分类。那么文章也就从这三个方面来一一介绍。

首先是获取人脸信息,我这里提供获取人脸信息的方式是直接从视频中获取,当然你也可以从照片中弄出来(用循环的方法一张一张从文件夹中获取图片取获取人脸信息)。人脸的获取用的是opencv官方的人脸识别分类器:haarcascade_frontalface_default.xml

下载地址:opencv/data/haarcascades at 4.x · opencv/opencv · GitHub

如果进去去的话文章末尾也有我的qq,可以找我发给你。

之后从视屏中获取的代码如下:

import os
import cv2


def load_img(path, trainpath,vedioname,name, mun=30, add_with=0, num_id=0,time=0):
    if not os.path.exists(path):
        os.mkdir(path)
    # 获取人脸识别模型
    classfier = cv2.CascadeClassifier('opencv-4.x/data/haarcascades/haarcascade_frontalface_default.xml')
    # 创建一个窗口
    cv2.namedWindow('face')
    # 打开第一个个摄像头
    # cap = cv2.VideoCapture(0)
    # 输入视频
    # cap = cv2.VideoCapture('trainvedio/zeliansiji/zeliansiji1.mp4')
    cap = cv2.VideoCapture(trainpath+vedioname)
    # 根据摄像头设置IP及rtsp端口
    # url='rtsp://admin:admin@192.168.0.104:8554/live'
    # cap = cv2.VideoCapture(url)
    i = 0  # 计数
    if cap.isOpened():
        while i < mun:
            ok, frame = cap.read()  # 读取一帧图片
            if not ok:
                continue

            faces = classfier.detectMultiScale(frame, 1.2, 3, minSize=(32, 32))

            if len(faces) > 0:
                for face in faces:
                    x, y, w, h = face

                    img = frame[y - add_with:y + h + add_with,
                          x - add_with:x + w + add_with]
                    # 显示人脸框
                    # cv2.rectangle(frame, (x-add_with, y-add_with),
                    #               (x+w+add_with, y+h+add_with), (0, 255, 0), 2)
                    # save_path = path + '/' + name + '_' + str(i) + '.jpg'
                    # save_path = path + '/'  + str(i) + '.jpg'
                    save_path = path + '/'+name+'.'+str(num_id) +'.'+ str(i+time*mun) + '.jpg'
                    print(save_path)
                    img2 = cv2.resize(img, (112, 112))
                    cv2.imwrite(save_path, img2)
                    i += 1

            cv2.imshow('face', frame)
            c = cv2.waitKey(10)
            if c & 0xFF == ord('q'):
                break

        cap.release()
        cv2.destroyAllWindows()


if __name__ == '__main__':
    # 第一个参数为保存图片的路径
    # 第二个参数为保存图片名字的开头
    # 第三个参数为图片的数量
    # 第四个参数可以调节图片的大小
    # 第五个参数表示人脸id
    # 第六个参数表示 (当前视频数-1)
    # load_img('data/zeliansiji', 'zeliansiji', 300, 0, 1)
    # load_img('data/zeliansiji', 'trainvedio/zeliansiji/','zeliansiji1.mp4','zeliansiji', 300, 0, 1,0)
    trainpath='trainvedio/pujing/'
    time=0
    for vedioname in os.listdir(trainpath):
        load_img('data/pujing', trainpath, vedioname, 'pujing', 900, 1, 0,time)
        time+=1


第二步就是训练自己的模型,还是用上面的那个人脸分类器。

# -----建立模型、创建数据集-----#-----建立模型、创建数据集-----

import os
import cv2
import numpy as np
from PIL import Image

# 导入pillow库,用于处理图像
# 设置之前收集好的数据文件路径
path = 'data/class14'

# 初始化识别的方法
recog = cv2.face.LBPHFaceRecognizer_create()

# 调用熟悉的人脸分类器
detector = cv2.CascadeClassifier('opencv-4.x/data/haarcascades/haarcascade_frontalface_default.xml')


# 创建一个函数,用于从数据集文件夹中获取训练图片,并获取id
# 注意图片的命名格式为User.id.sampleNum
def get_images_and_labels(path):
    image_paths = [os.path.join(path, f) for f in os.listdir(path)]
    # 新建连个list用于存放
    face_samples = []
    ids = []

    # 遍历图片路径,导入图片和id添加到list中
    for image_path in image_paths:

        # 通过图片路径将其转换为灰度图片
        img = Image.open(image_path).convert('L')

        # 将图片转化为数组
        img_np = np.array(img, 'uint8')

        if os.path.split(image_path)[-1].split(".")[-1] != 'jpg':
            continue

        # 为了获取id,将图片和路径分裂并获取
        id = int(os.path.split(image_path)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_np)

        # 将获取的图片和id添加到list中
        for (x, y, w, h) in faces:
            face_samples.append(img_np[y:y + h, x:x + w])
            ids.append(id)
    return face_samples, ids


# 调用函数并将数据喂给识别器训练
print('Training...')
faces, ids = get_images_and_labels(path)
# 训练模型
recog.train(faces, np.array(ids))
# 保存模型
recog.save('trainer/class14.yml')

最后就是检验自己成果的时候了!检测识别。检测的视频流有很多种,可以是摄像头也可以是自己的视频。

# -----检测、校验并输出结果-----
import cv2
import time
# 准备好识别方法
recognizer = cv2.face.LBPHFaceRecognizer_create()

# 使用之前训练好的模型
print('loading moudle......')
recognizer.read('trainer/class14.yml')

# 再次调用人脸分类器
print('loading classifier......')
cascade_path = "opencv-4.x/data/haarcascades/haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)

# 加载一个字体,用于识别后,在图片上标注出对象的名字
font = cv2.FONT_HERSHEY_SIMPLEX

idnum = 0
# 设置好与ID号码对应的用户名,如下,如0对应的就是初始

names = ['shuaige','sb','xuzuowei','weiaojie','zhangyuan']

# 调用视频
print('loadin vedio......')
cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)

while True:
    start = time.time()  # 开始计时
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 识别人脸
    faces = face_cascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        flags=5,
        minSize=(int(minW), int(minH))
    )
    # 进行校验
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])

        # 计算出一个检验结果
        if confidence < 100:
            idum = names[idnum]
            confidence = "{0}%", format(round(100 - confidence))
        else:
            idum = "unknown"
            confidence = "{0}%", format(round(100 - confidence))

        # 输出检验结果以及用户名
        end = time.time()  # 结束计时
        seconds = end - start
        fps = 1 / seconds  # 计算帧率
        cv2.putText(img,  # 图像
                    "FPS: {0}".format(float('%.1f' % fps)),  # fps数值
                    (50,  # x坐标
                     50),  # y坐标
                    cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                    1,  # 字体大小
                    (0, 0, 255),  # 颜色
                    1)  # 粗细
        cv2.putText(img, str(idum), (x + 5, y - 5), font, 1, (0, 255, 0), 2)
        # cv2.putText(img, str('made by jhw'), (x + 5, y + h -5), font, 1, (255, 255, 255), 1)

        # 展示结果
        cv2.imshow('press q to exit', img)
        k = cv2.waitKey(1)
        if k == 27:
            break
    # c = cv2.waitKey(10)
    # if c & 0xFF == ord('q'):
    #     break

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

这样就大功告成啦,来看看效果吧!看看我们的普京大帝!

 

喜欢的就点个赞收藏一下吧

Q我 1609373452

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值