计算机视觉入门(基础篇:利用mediapipe进行人脸识别)

本代码基于 Advance Computer Vision with Python 进行修改,更加适合中国宝宝体质

我的相关代码及数据集已经上传GitHub仓库,欢迎使用 Advance-Computer-Vision-with-Python

代码1:Basics.py

import cv2
import mediapipe as mp
import time

# 打开视频文件
cap = cv2.VideoCapture(
    "E:\\Advance Computer Vision with Python\\Chapter 3 Face Detection\\Videos\\4.mp4"
)

pTime = 0  # 上一帧的时间

# 初始化MediaPipe的人脸检测模块
mpFaceDetection = mp.solutions.face_detection
mpDraw = mp.solutions.drawing_utils
faceDetection = mpFaceDetection.FaceDetection(0.75)  # 创建一个 MediaPipe 的人脸检测器对象并设置检测置信度阈值为0.75

while True:
    success, img = cap.read()  # 读取视频帧
    if not success:
        print("Failed to read frame")
        break

    # 将图像转换为RGB格式
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = faceDetection.process(imgRGB)  # 处理图像,进行人脸检测

    if results.detections:
        for id, detection in enumerate(results.detections):
            # mpDraw.draw_detection(img, detection) #使用 MediaPipe 提供的工具在图像上绘制检测到的人脸的边界框和关键点
            # print(id, detection)
            # print(detection.score)
            # print(detection.location_data.relative_bounding_box)

            # 获取人脸检测的边界框信息
            bboxC = detection.location_data.relative_bounding_box
            ih, iw, ic = img.shape
            bbox = (
                int(bboxC.xmin * iw),
                int(bboxC.ymin * ih),
                int(bboxC.width * iw),
                int(bboxC.height * ih),
            )

            # 绘制边界框
            cv2.rectangle(img, bbox, (255, 0, 255), 2)

            # 显示检测置信度
            cv2.putText(
                img,
                f"{int(detection.score[0] * 100)}%",
                (bbox[0], bbox[1] - 20),
                cv2.FONT_HERSHEY_PLAIN,
                5,
                (255, 0, 255),
                5,
            )
            # 第一个5为字体大小,第二个5为字体粗细

    # 计算并显示帧率FPS
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(
        img, f"FPS: {int(fps)}", (20, 70), cv2.FONT_HERSHEY_PLAIN, 5, (0, 255, 0), 5
    )

    cv2.namedWindow("Image", cv2.WINDOW_NORMAL)  # 创建可调整大小的窗口

    # 显示图像
    cv2.imshow("Image", img)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

代码2:FaceDetectionModule.py

import cv2
import mediapipe as mp
import time


# 定义一个人脸检测类
class FaceDetector:
    def __init__(self, minDetectionCon=0.5):
        # 初始化检测置信度
        self.minDetectionCon = minDetectionCon

        # 初始化MediaPipe的人脸检测模块
        self.mpFaceDetection = mp.solutions.face_detection
        self.mpDraw = mp.solutions.drawing_utils
        self.faceDetection = self.mpFaceDetection.FaceDetection(self.minDetectionCon)

    def findFaces(self, img, draw=True):
        # 将图像转换为RGB格式
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.faceDetection.process(imgRGB)  # 进行人脸检测
        bboxs = []  # 存储检测到的边界框

        if self.results.detections:
            for id, detection in enumerate(self.results.detections):
                # 获取人脸检测的边界框信息
                bboxC = detection.location_data.relative_bounding_box
                ih, iw, ic = img.shape
                bbox = (
                    int(bboxC.xmin * iw),
                    int(bboxC.ymin * ih),
                    int(bboxC.width * iw),
                    int(bboxC.height * ih),
                )
                bboxs.append([id, bbox, detection.score])  # 添加到边界框列表

                if draw:
                    img = self.fancyDraw(img, bbox)  # 绘制边界框
                    # 显示检测置信度
                    cv2.putText(
                        img,
                        f"{int(detection.score[0] * 100)}%",
                        (bbox[0], bbox[1] - 20),
                        cv2.FONT_HERSHEY_PLAIN,
                        5,
                        (255, 0, 255),
                        5,
                    )
        return img, bboxs

    def fancyDraw(self, img, bbox, l=30, t=5, rt=1):
        # 这个 fancyDraw 函数通过在矩形框的四个角上绘制短线来实现自定义样式,与普通的矩形框相比,增加了视觉上的变化
        # 1、矩形框:使用 cv2.rectangle 绘制标准矩形框
        # 2、角线:在矩形的四个角上绘制短线段,使边框看起来更有设计感
        # l 角线的长度,t 角线的粗细,rt 矩形框的粗细(length 长度,thickness 厚度)

        # 自定义绘制边框的样式
        x, y, w, h = bbox
        x1, y1 = x + w, y + h

        cv2.rectangle(img, bbox, (255, 0, 255), rt)  # 绘制矩形框
        # 绘制四个角的线条
        # 左上角
        cv2.line(img, (x, y), (x + l, y), (255, 0, 255), t)
        cv2.line(img, (x, y), (x, y + l), (255, 0, 255), t)
        # 右上角
        cv2.line(img, (x1, y), (x1 - l, y), (255, 0, 255), t)
        cv2.line(img, (x1, y), (x1, y + l), (255, 0, 255), t)
        # 左下角
        cv2.line(img, (x, y1), (x + l, y1), (255, 0, 255), t)
        cv2.line(img, (x, y1), (x, y1 - l), (255, 0, 255), t)
        # 右下角
        cv2.line(img, (x1, y1), (x1 - l, y1), (255, 0, 255), t)
        cv2.line(img, (x1, y1), (x1, y1 - l), (255, 0, 255), t)
        
        return img


def main():
    # 打开视频文件
    cap = cv2.VideoCapture(
        "E:\\Advance Computer Vision with Python\\Chapter 3 Face Detection\\Videos\\4.mp4"
    )
    pTime = 0  # 上一帧时间
    detector = FaceDetector()  # 创建人脸检测器对象

    while True:
        success, img = cap.read()  # 读取视频帧
        img, bboxs = detector.findFaces(img)  # 检测人脸并获取边界框
        print(bboxs)  # 打印边界框信息

        # 计算并显示帧率FPS
        cTime = time.time()
        fps = 1 / (cTime - pTime)
        pTime = cTime
        cv2.putText(
            img, f"FPS: {int(fps)}", (20, 70), cv2.FONT_HERSHEY_PLAIN, 5, (0, 255, 0), 5
        )

        cv2.namedWindow("Image", cv2.WINDOW_NORMAL)  # 创建可调整大小的窗口

        # 显示图像
        cv2.imshow("Image", img)
        cv2.waitKey(1)


if __name__ == "__main__":
    main()

mp.solutions.face_detection

mpFaceDetection = mp.solutions.face_detection 初始化MediaPipe的人脸检测模块

faceDetection = mpFaceDetection.FaceDetection(0.75) 创建一个 MediaPipe 的人脸检测器对象,并设置检测置信度阈值为0.75

results = faceDetection.process(imgRGB) 处理图像,进行人脸检测

mpFaceDetection.FaceDetection() 的参数主要有:

min_detection_confidence 用于设置检测置信度阈值,默认值通常是 0.5

边框信息

获取人脸检测的边界框信息:

bboxC = detection.location_data.relative_bounding_box
ih, iw, ic = img.shape
bbox = (
    int(bboxC.xmin * iw),
    int(bboxC.ymin * ih),
    int(bboxC.width * iw),
    int(bboxC.height * ih),
)

原版:

原版

自定义:

自定义

矩形框看起来不完整且不断变化,可能是因为:

  • 视频帧更新:每帧都会重新绘制,可能导致视觉上有闪烁或变化

  • 检测结果不稳定:人脸检测结果在不同帧之间不稳定,边框可能会跳动

源代码的一个小问题

如果你去网站上看代码,会发现一个错误:

website

你直接复制代码到vscode里面会出错:

vscode

翻了一下视频,才发现:

youtube

有个换行的反斜杠,在网站上没显示出来,原本这里应该是逗号连接的元组,结果现在好了,如果直接复制进vscode,它自动识别,帮你把前两个装在一起了,后两个落下了,好在也不难发现

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值