欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv + face_recognition —— 人脸识别小案例

程序员文章站 2022-07-12 21:03:13
...

opencv + face_recognition —— 人脸识别小案例

0. 版本信息

  • 版本信息

    产品 版本
    python 3.7
    anaconda 4.8.3
    jupyter 6.0.3
    opencv 3.4.2
    dlib 19.17.99
    face_recognition 1.3.0
  • 安装 face_recognition 的方法

    • 打开Anaconda Prompt,进入命令行
    • pip install cmake -i "https://pypi.doubanio.com/simple/"
    • 度盘下载:dlib , 提取码:84du
    • pip install dlib-19.17.99-cp37-cp37m-win_amd64.whl
    • pip install face_recognition -i "https://pypi.doubanio.com/simple/"

1. 导包

import face_recognition
import cv2
import os

2. 识别图片中的面部

# 读取图片
img = cv2.imread("./peoples.jpg")
# 转换 BGR(opencv使用) 为 RGB(face_recognition使用)
rgb_img = img[:, :, ::-1]

# 识别图片中的脸部(可能存在多个脸)
face_locations = face_recognition.face_locations(rgb_img)

# 遍历人脸位置信息
for top, right, bottom, left in face_locations:
    # 对人脸画框
    cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 2)

# 后面显示还是用img显示(BGR),不要用rgb_img显示,否则你会得到意向不到的“阿凡达”特效,哈哈
# 展示,按q退出
cv2.imshow("img", img)
if cv2.waitKey() == ord("q"):
    cv2.destroyAllWindows()

opencv + face_recognition —— 人脸识别小案例
opencv + face_recognition —— 人脸识别小案例

3. 实现摄像头中的面部追踪

# 捕获0号摄像头
video_capture = cv2.VideoCapture(0)

while True:
    # 读取摄像头信息
    # ret表示是否正常捕获到图像
    # frame表示当前帧,即一张图片
    ret, frame = video_capture.read()
    # 开始处理
    if ret:
        # 转换 BGR(opencv使用) 为 RGB(face_recognition使用)
        rgb_img = frame[:, :, ::-1]
        # 识别图片中的脸部(可能存在多个脸)
        face_locations = face_recognition.face_locations(rgb_img)

        # 遍历人脸位置信息
        for top, right, bottom, left in face_locations:
            # 对人脸画框
            cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)

        cv2.imshow("video", frame)
    if cv2.waitKey(1) == ord("q"):
        break
        
video_capture.release()
cv2.destroyAllWindows()

opencv + face_recognition —— 人脸识别小案例

4. 人脸追踪+识别,分析出不同的人

  • 准备一个文件夹(或者数据库),放入你的人脸图片(一张图片一个脸),例如
    • ./face_images/xiaowang.jpg
    • ./face_images/lilei.jpg
  • 读取已经准备好的人脸图片信息
    # 人姓名
    person_names = []
    # 人面部信息
    person_face_encodings = []
    
    img_dir = "./face_images/"
    files = os.listdir(img_dir)
    for file in files:
        if file.endswith("jpg") or file.endswith("png"):
            # 去除文件后缀类型
            name, _ = os.path.splitext(file)
            person_names.append(name)
            # 拼接图片完整路径
            img_path = os.path.join(img_dir, file)
            # 解析出已有图片的脸部信息
            img_file = face_recognition.load_image_file(img_path)
            face_endocing = face_recognition.face_encodings(img_file)[0]
            person_face_encodings.append(face_endocing)
    
  • 捕获摄像头,并对比已知的人脸信息
    # 捕获摄像头
    video_caputre = cv2.VideoCapture(0)
    
    while True:
        ret, frame = video_caputre.read()
        if ret:
            # 转换 BGR(opencv使用) 为 RGB(face_recognition使用)
            rgb_img = frame[:, :, ::-1]
            # 识别图片中的脸部
            face_locations = face_recognition.face_locations(rgb_img)
            # 对识别出的面部区域编码
            face_encodings = face_recognition.face_encodings(rgb_img, face_locations)
            
            # 遍历人脸,进行识别
            for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
                # 画框
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
                
                # 将图中的面部与已有的面部进行对比,得到姓名
                matches = face_recognition.compare_faces(person_face_encodings, face_encoding)
                name = "Unknown"
                for index, match in enumerate(matches):
                    if match:
                        name = person_names[index]
                        break
                # 写姓名
                cv2.putText(frame, name, (left, top - 10), cv2.FONT_ITALIC, 1, (0, 255, 0), 2)
        
            cv2.imshow("video", frame)
        if cv2.waitKey(1) == ord("q"):
            break
            
    video_caputre.release()
    cv2.destroyAllWindows()
    

opencv + face_recognition —— 人脸识别小案例

5. 人脸追踪+识别,分析出不同的人(优化)

  • 准备的人脸信息部分同前面的小节4
  • 优化后的代码,参考自官方示例
    # 优化点
    # 1. 缩小原图,再进行识别,提高了识别的速度
    # 2. 交替,每隔一帧,进行一次识别,降低了识别的频次
    
    video_capture = cv2.VideoCapture(0)
    
    # 初始化变量
    face_locations = [] # 脸部位置列表
    face_encodings = [] # 脸部编码列表
    face_names = [] # 脸的人名列表
    process_this_frame = True # 是否识别当前帧
    
    while True:
        # 读取帧
        ret, frame = video_capture.read()
        # 读取失败,就退出
        if not ret:
            break
        
        # 缩放当前帧为1/4,以提高后面的识别速度
        small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    
        # 转换BGR为RGB,方便face_recognition使用
        rgb_small_frame = small_frame[:, :, ::-1]
    
        # 识别处理
        if process_this_frame:
            # 获取当前帧的人脸位置、编码
            face_locations = face_recognition.face_locations(rgb_small_frame)
            face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
    
            face_names = []
            for face_encoding in face_encodings:
                # 人名、近似度的默认值
                name = "Unknown"
                similarity = 0.0
                
                # 计算当前脸与已知的脸的欧氏距离,越小越相近
                face_distances = face_recognition.face_distance(person_face_encodings, face_encoding)
                # 将当前人脸编码与已知的所有人脸编码进行比对,确定是否匹配
                matches = face_recognition.compare_faces(person_face_encodings, face_encoding)
    
                # 获取第一个匹配的人名
                for index, match in enumerate(matches):
                    if match:
                        name = person_names[index]
                        similarity = face_distances[index]
                        break
    
                face_names.append((name, similarity))
        # 交替 True, False, True, ...
        # 保证每隔一帧进行一次识别,而不是每一帧都识别
        process_this_frame = not process_this_frame
    
        # 显示面部的框、人名
        for (top, right, bottom, left), (name, similarity) in zip(face_locations, face_names):
            # 由于前面是从小图的中识别的脸,因此此处要扩大回原来的比例
            top *= 4
            right *= 4
            bottom *= 4
            left *= 4
    
            # 画脸的框
            cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
            # 画文字
            cv2.putText(frame, "%s, %.2f" % (name, similarity), (left, top - 10), cv2.FONT_HERSHEY_DUPLEX, 1.0, (0, 255, 0), 1)
    
        cv2.imshow('Video', frame)
        if cv2.waitKey(1) == ord('q'):
            break
    
    video_capture.release()
    cv2.destroyAllWindows()
    

opencv + face_recognition —— 人脸识别小案例

6. 人脸追踪,打上马赛克

  • 马赛克处理
    # 方法-为图片某个区域打上马赛克
    def do_mosaic(img, top, right, bottom, left, step):
        for i in range(top, bottom, step):
                for j in range(left, right, step):
                    for y in range(0, step):
                        for x in range(0, step):
                            frame[i + y, j + x] = frame[i, j]
    
  • 为人脸打上马赛克
    # 开始处理
    video_capture = cv2.VideoCapture(0)
    while True:
        ret, frame = video_capture.read()
        if ret:
            # 转换 BGR(opencv使用) 为 RGB(face_recognition使用)
            rgb_img = frame[:, :, ::-1]
            # 识别图片中的脸部
            face_locations = face_recognition.face_locations(rgb_img)
            # 遍历人脸,进行识别
            for (top, right, bottom, left) in face_locations:
                # 打上马赛克
                do_mosaic(frame, top, right, bottom, left, 8)
                # 画框
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
                
            cv2.imshow("video", frame)
        if cv2.waitKey(1) == ord("q"):
            break
            
    video_capture.release()
    cv2.destroyAllWindows()
    

opencv + face_recognition —— 人脸识别小案例

7. 人脸追踪,磨皮美颜

  • 双边滤波-磨皮美颜
    # 方法-图中某个区域磨皮美颜
    def do_beautify(img, top, right, bottom, left):
        # 双边滤波-磨皮美颜
        beautify_img = cv2.bilateralFilter(img[top: bottom, left:right], 10, 20, 20)
        # 修改原图
        height, width, channels = beautify_img.shape
        for i in range(0, height):
            for j in range(0, width):
                img[top + i, left + j] = beautify_img[i, j]
    
  • 为人脸进行磨皮
    # 开始处理
    video_caputre = cv2.VideoCapture(0)
    while True:
        ret, frame = video_caputre.read()
        if ret:
            # 转换 BGR(opencv使用) 为 RGB(face_recognition使用)
            rgb_img = frame[:, :, ::-1]
            # 识别图片中的脸部
            face_locations = face_recognition.face_locations(rgb_img)
            # 遍历人脸,进行识别
            for (top, right, bottom, left) in face_locations:
                # 双边滤波-磨皮美颜
                do_beautify(frame, top, right, bottom, left)
                # 画框
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
                
            cv2.imshow("video", frame)
        if cv2.waitKey(1) == ord("q"):
            break
            
    video_capture.release()
    cv2.destroyAllWindows()
    

opencv + face_recognition —— 人脸识别小案例