视觉检测【MdeiaPipe】

mediapipe.solutions.face_mesh  # 人脸网状检测
mediapipe.solutions.face_detection  # 人脸识别
mediapipe.solutions.hands  # 手部关键点检测
mediapipe.solutions.pose   # 人体姿态检测

mediapipe.solutions.face_detection.FaceDetection()   人脸检测函数
参数:

min_detection_confidence: 默认为 0.5。人脸检测模型的最小置信值 (0-1之间),高于该置信度则将检测视为成功。

返回值:

detections:检测到的人脸的集合,其中每个人脸都表示为一个检测原始消息,其中包含 人脸的概率、1 个边界框、6 个关键点(右眼、左眼、鼻尖、嘴巴中心、右耳、左耳)。边界框由 xmin 和 width (由图像宽度归一化为 [0, 1])以及 ymin 和 height (由图像高度归一化为 [0, 1])组成。每个关键点由 x 和 y 组成,分别通过图像宽度和高度归一化为 [0, 1]。

detections.score: 获取图像是人脸的概率

detections.location_data: 获取识别框的 x, y, w, h 和 6个关键点的 x, y

detections.location_data.relative_bounding_box: 获取识别框的 x, y, w, h

detections.location_data.relative_keypoints: 6个关键点的 x, y 组成的列表

mediapipe.solutions.hands.Hands()  手部关键点检测方法
参数:

static_image_mode: 默认为 False,将输入图像视为视频流。它将尝试在第一个输入图像中检测手,并在成功检测后进一步定位手的坐标。在随后的图像中,一旦检测到所有 max_num_hands 手并定位了相应的手的坐标,它就会跟踪这些坐标,而不会调用另一个检测,直到它失去对任何一只手的跟踪。这减少了延迟,非常适合处理视频帧。如果设置为 True,则在每个输入图像上运行手部检测,用于处理一批静态的、可能不相关的图像。

max_num_hands: 最多检测几只手,默认为2

min_detection_confidence: 手部检测模型的最小置信值(0-1之间),超过阈值则检测成功。默认为 0.5

min_tracking_confidence: 坐标跟踪模型的最小置信值 (0-1之间),用于将手部坐标视为成功跟踪,不成功则在下一个输入图像上自动调用手部检测。将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果 static_image_mode 为真,则忽略这个参数,手部检测将在每个图像上运行。默认为 0.5

返回值:

MULTI_HAND_LANDMARKS: 被检测/跟踪的手的集合,其中每只手被表示为21个手部地标的列表,每个地标由x, y, z组成。x和y分别由图像的宽度和高度归一化为[0,1]。Z表示地标深度。

MULTI_HANDEDNESS: 被检测/追踪的手是左手还是右手的集合。每只手由label(标签)和score(分数)组成。 label 是 'Left' 或 'Right' 值的字符串。 score 是预测左右手的估计概率。

mediapipe.solutions.pose.Pose()  姿态关键点检测函数
参数:

static_image_mode: 默认为 False,将输入图像视为视频流。它将尝试在第一张图像中检测最突出的人,并在成功检测后进一步定位姿势地标。在随后的图像中,它只是简单地跟踪那些地标,而不会调用另一个检测,直到失去对目标的跟踪,可以减少计算和延迟。若为 True,则会对每张输入图像执行人体检测方法,非常适合处理一批静态的、可能不相关的图像。

model_complexity: 默认为 1,姿势地标模型的复杂度:0、1 、2。地标准确度和推理延迟通常随着模型复杂度的增加而增加。

smooth_landmarks: 默认为 True,平滑图像,过滤不同的输入图像上的姿势地标以减少抖动,但如果static_image_mode也设置为 True 则忽略。

upper_body_only: 默认为 False,是否只检测上半身的地标。人体姿势共有33个地标,上半身的姿势地标有25个。

enable_segmentation: 默认为False。如果设置为 true,除了姿势地标之外,该解决方案还会生成分割掩码。

smooth_segmentation:默认为 True,过滤不同的输入图像上的分割掩码以减少抖动,但如果 enable_segmentation 设置为 False,或者 static_image_mode 设置为 True 则忽略。

min_detection_confidence: 默认为 0.5,来自人员检测模型的最小置信值 (0-1之间),高于该阈值则认为检测视为成功。

min_tracking_confidence:默认为 0.5。来自地标跟踪模型的最小置信值 (0-1之间),用于将被视为成功跟踪的姿势地标,否则将在下一个输入图像上自动调用人物检测。将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果 static_image_mode 为 True,则人员检测将在每帧图像上运行。

返回值:

具有 "pose_landmarks" 字段的 NamedTuple 对象,其中包含检测到的最突出人物的姿势坐标。

mediapipe.solutions.drawing_utils.draw_landmarks() # 可视化函数

image: 需要画图的原始图片

landmark_list: 检测到的关键点坐标

connections: 连接线,需要把那些坐标连接起来

landmark_drawing_spec: 坐标的颜色,粗细

connection_drawing_spec: 连接线的粗细,颜色等

在这里插入图片描述

import time
import cv2
import mediapipe as mp
# (1)视频捕获
cap = cv2.VideoCapture(0)  # 0代表电脑自带的摄像头

# (2)创建检测关键点的方法
Models = mp.solutions.hands  # 检测方法
Model = Models.Hands(static_image_mode=False,  # 静态追踪,低于0.5置信度会再一次跟踪
                      max_num_hands=2,  # 最多有2只手
                      min_detection_confidence=0.5,  # 最小检测置信度
                      min_tracking_confidence=0.5)  # 最小跟踪置信度

# 创建检测手部关键点和关键点之间连线的方法
mpDraw = mp.solutions.drawing_utils

# 查看时间
pTime = 0  # 处理一张图像前的时间
cTime = 0  # 一张图处理完的时间

# (3)处理视频图像
while True:  # 对每一帧视频图像处理

    # 返回是否读取成功和读取的图像
    success, img = cap.read()

    # 在循环中发送rgb图像到hands中,opencv中图像默认是BGR格式
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # 把图像传入检测模型,提取信息
    results = Model.process(imgRGB)

    # 检查是否检测到什么东西了,没有检测到手就返回None
    # print(results.multi_hand_landmarks)

    # 检查每帧图像是否有多只手,一一提取它们
    if results.multi_hand_landmarks:  # 如果没有手就是None
        for handlms in results.multi_hand_landmarks:
            
            # (4)获取每个关键点的索引和坐标
            for index, lm in enumerate(handlms.landmark):
                
                # 索引为0代表手底部中间部位,为4代表手指关键或指尖
                # 输出21个手部关键点的xyz坐标(0-1之间),是相对于图像的长宽比例
                # print(index, lm)  
                # 只需使用x和y查找位置信息
                # 将xy的比例坐标转换成像素坐标
                h, w, c = img.shape # 分别存放图像长\宽\通道数
                
                # 中心坐标(小数),必须转换成整数(像素坐标)
                cx ,cy =  int(lm.x * w), int(lm.y * h) #比例坐标x乘以宽度得像素坐标
                
                # 打印显示21个关键点的像素坐标
                print(index, cx, cy)
                
                # 存储坐标信息
                lmList.append([index, cx, cy])
                    
                # 在21个关键点上换个圈,img画板,坐标(cx,cy),半径5,蓝色填充
                cv2.circle(img, (cx,cy), 12, (0,0,255), cv2.FILLED)

            # 绘制每只手的关键点
            mpDraw.draw_landmarks(img, handlms, Models.HAND_CONNECTIONS)  
            # 传入想要绘图画板img,单只手的信息handlms
            # mpHands.HAND_CONNECTIONS绘制手部关键点之间的连线

    # 记录执行时间
    cTime = time.time()
    # 计算fps
    fps = 1 / (cTime - pTime)
    # 重置起始时间
    pTime = cTime

    # 把fps显示在窗口上;img画板;取整的fps值;显示位置的坐标;设置字体;字体比例;颜色;厚度
    cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)

    # 显示图像
    cv2.imshow('Image', img)  # 窗口名,图像变量
    if cv2.waitKey(1) & 0xFF == 27:  # 每帧滞留1毫秒后消失;ESC键退出
        break

# 释放视频资源
cap.release()
cv2.destroyAllWindows()

你可能感兴趣的:(计算机视觉,人工智能)