📜  在Python中使用 OpenCV 进行手部检测的亮度控制

📅  最后修改于: 2022-05-13 01:54:58.070000             🧑  作者: Mango

在Python中使用 OpenCV 进行手部检测的亮度控制

在本文中,我们将制作一个Python项目,使用 OpenCV 和 Mediapipe 来查看手势,并相应地将系统的亮度设置为 0-100 的范围。

我们使用了一个 HandTracking 模块,该模块跟踪手上的所有点并检测手部标志,计算拇指尖和食指尖之间的距离,并根据亮度范围映射拇指尖和食指尖之间的距离。

所需的库

  • Mediapipe:它是 Google 的开源框架,用于媒体处理。它是跨平台的,或者我们可以说它是平台友好的。它可以在 Android、iOS 和 Web 上运行,这就是跨平台的意思,可以在任何地方运行。
pip install mediapipe  
  • OpenCV 它是一个Python库,旨在解决计算机视觉问题。 OpenCV 支持多种编程语言,如 C++、 Python、 Java等。支持多种平台,包括 Windows、Linux 和 MacOS。
pip install opencv-python
  • 屏幕亮度控制: 是一个用于控制显示器亮度的Python工具。支持 Windows 和大多数版本的 Linux。
pip install screen-brightness-control
  • 麻木 是一个通用的数组处理包。它提供了一个高性能的多维数组对象,以及用于处理这些数组的工具。它是使用Python进行科学计算的基础包。
pip install numpy

逐步实施

第 1 步:导入所有必需的库

Python3
# Importing Libraries
import cv2
import mediapipe as mp
from math import hypot
import screen_brightness_control as sbc
import numpy as np


Python3
# Initializing the Model
mpHands = mp.solutions.hands
hands = mpHands.Hands(
    static_image_mode=False,
    model_complexity=1,
    min_detection_confidence=0.75,
    min_tracking_confidence=0.75,
    max_num_hands=2)
 
Draw = mp.solutions.drawing_utils


Python3
# Start capturing video from webcam
cap = cv2.VideoCapture(0)
 
while True:
    # Read video frame by frame
    _,frame = cap.read()
     
    #Flip image
    frame=cv2.flip(frame,1)
     
    # Convert BGR image to RGB image
    frameRGB = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
     
    # Process the RGB image
    Process = hands.process(frameRGB)
     
    landmarkList = []
    # if hands are present in image(frame)
    if Process.multi_hand_landmarks:
        # detect handmarks
        for handlm in Process.multi_hand_landmarks:
            for _id,landmarks in enumerate(handlm.landmark):
                # store height and width of image
                height,width,color_channels = frame.shape
                 
                # calculate and append x, y coordinates
                # of handmarks from image(frame) to lmList
                x,y = int(landmarks.x*width),int(landmarks.y*height)             
                landmarkList.append([_id,x,y])
             
            # draw Landmarks
            Draw.draw_landmarks(frame,handlm,mpHands.HAND_CONNECTIONS)
     
    # If landmarks list is not empty
    if landmarkList != []:
        # store x,y coordinates of (tip of) thumb 
        x_1,y_1 = landmarkList[4][1],landmarkList[4][2]
         
        # store x,y coordinates of (tip of) index finger
        x_2,y_2 = landmarkList[8][1],landmarkList[8][2]
         
        # draw circle on thumb and index finger tip
        cv2.circle(frame,(x_1,y_1),7,(0,255,0),cv2.FILLED)
        cv2.circle(frame,(x_2,y_2),7,(0,255,0),cv2.FILLED)
         
        # draw line from tip of thumb to tip of index finger
        cv2.line(frame,(x_1,y_1),(x_2,y_2),(0,255,0),3)
         
        # calculate square root of the sum
        # of squares of the specified arguments.
        L = hypot(x_2-x_1,y_2-y_1)
         
        # 1-D linear interpolant to a function
        # with given discrete data points
        # (Hand range 15 - 220, Brightness range 0 - 100),
        # evaluated at length.
        b_level = np.interp(L,[15,220],[0,100])
     
        # set brightness
        sbc.set_brightness(int(b_level))
 
    # Display Video and when 'q' is entered,
    # destroy the window
    cv2.imshow('Image', frame)
    if cv2.waitKey(1) & 0xff == ord('q'):
        break


Python3
# Importing Libraries
import cv2
import mediapipe as mp
from math import hypot
import screen_brightness_control as sbc
import numpy as np
 
# Initializing the Model
mpHands = mp.solutions.hands
hands = mpHands.Hands(
    static_image_mode=False,
    model_complexity=1,
    min_detection_confidence=0.75,
    min_tracking_confidence=0.75,
    max_num_hands=2)
 
Draw = mp.solutions.drawing_utils
 
# Start capturing video from webcam
cap = cv2.VideoCapture(0)
 
while True:
    # Read video frame by frame
    _, frame = cap.read()
 
    # Flip image
    frame = cv2.flip(frame, 1)
 
    # Convert BGR image to RGB image
    frameRGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
    # Process the RGB image
    Process = hands.process(frameRGB)
 
    landmarkList = []
    # if hands are present in image(frame)
    if Process.multi_hand_landmarks:
        # detect handmarks
        for handlm in Process.multi_hand_landmarks:
            for _id, landmarks in enumerate(handlm.landmark):
                # store height and width of image
                height, width, color_channels = frame.shape
 
                # calculate and append x, y coordinates
                # of handmarks from image(frame) to lmList
                x, y = int(landmarks.x*width), int(landmarks.y*height)
                landmarkList.append([_id, x, y])
 
            # draw Landmarks
            Draw.draw_landmarks(frame, handlm,
                                mpHands.HAND_CONNECTIONS)
 
    # If landmarks list is not empty
    if landmarkList != []:
        # store x,y coordinates of (tip of) thumb
        x_1, y_1 = landmarkList[4][1], landmarkList[4][2]
 
        # store x,y coordinates of (tip of) index finger
        x_2, y_2 = landmarkList[8][1], landmarkList[8][2]
 
        # draw circle on thumb and index finger tip
        cv2.circle(frame, (x_1, y_1), 7, (0, 255, 0), cv2.FILLED)
        cv2.circle(frame, (x_2, y_2), 7, (0, 255, 0), cv2.FILLED)
 
        # draw line from tip of thumb to tip of index finger
        cv2.line(frame, (x_1, y_1), (x_2, y_2), (0, 255, 0), 3)
 
        # calculate square root of the sum of
        # squares of the specified arguments.
        L = hypot(x_2-x_1, y_2-y_1)
 
        # 1-D linear interpolant to a function
        # with given discrete data points
        # (Hand range 15 - 220, Brightness
        # range 0 - 100), evaluated at length.
        b_level = np.interp(L, [15, 220], [0, 100])
 
        # set brightness
        sbc.set_brightness(int(b_level))
 
    # Display Video and when 'q' is entered, destroy
    # the window
    cv2.imshow('Image', frame)
    if cv2.waitKey(1) & 0xff == ord('q'):
        break


第 2 步:初始化 Hands 模型

Python3

# Initializing the Model
mpHands = mp.solutions.hands
hands = mpHands.Hands(
    static_image_mode=False,
    model_complexity=1,
    min_detection_confidence=0.75,
    min_tracking_confidence=0.75,
    max_num_hands=2)
 
Draw = mp.solutions.drawing_utils

让我们看看手模型的参数:

步骤 3:处理图像并根据拇指和食指尖之间的距离应用亮度

使用 OpenCV 从相机连续捕获帧并将 BGR 图像转换为 RGB 图像,并使用初始化的手模型进行预测。模型所做的预测保存在 results 变量中,我们可以使用 results.multi_hand_landmarks 从中访问地标,如果帧中存在手,则检测手部地标,然后计算拇指尖和食指尖之间的距离。用亮度范围映射拇指尖和食指尖的距离,即根据它们之间的距离,系统的亮度会改变。

Python3

# Start capturing video from webcam
cap = cv2.VideoCapture(0)
 
while True:
    # Read video frame by frame
    _,frame = cap.read()
     
    #Flip image
    frame=cv2.flip(frame,1)
     
    # Convert BGR image to RGB image
    frameRGB = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
     
    # Process the RGB image
    Process = hands.process(frameRGB)
     
    landmarkList = []
    # if hands are present in image(frame)
    if Process.multi_hand_landmarks:
        # detect handmarks
        for handlm in Process.multi_hand_landmarks:
            for _id,landmarks in enumerate(handlm.landmark):
                # store height and width of image
                height,width,color_channels = frame.shape
                 
                # calculate and append x, y coordinates
                # of handmarks from image(frame) to lmList
                x,y = int(landmarks.x*width),int(landmarks.y*height)             
                landmarkList.append([_id,x,y])
             
            # draw Landmarks
            Draw.draw_landmarks(frame,handlm,mpHands.HAND_CONNECTIONS)
     
    # If landmarks list is not empty
    if landmarkList != []:
        # store x,y coordinates of (tip of) thumb 
        x_1,y_1 = landmarkList[4][1],landmarkList[4][2]
         
        # store x,y coordinates of (tip of) index finger
        x_2,y_2 = landmarkList[8][1],landmarkList[8][2]
         
        # draw circle on thumb and index finger tip
        cv2.circle(frame,(x_1,y_1),7,(0,255,0),cv2.FILLED)
        cv2.circle(frame,(x_2,y_2),7,(0,255,0),cv2.FILLED)
         
        # draw line from tip of thumb to tip of index finger
        cv2.line(frame,(x_1,y_1),(x_2,y_2),(0,255,0),3)
         
        # calculate square root of the sum
        # of squares of the specified arguments.
        L = hypot(x_2-x_1,y_2-y_1)
         
        # 1-D linear interpolant to a function
        # with given discrete data points
        # (Hand range 15 - 220, Brightness range 0 - 100),
        # evaluated at length.
        b_level = np.interp(L,[15,220],[0,100])
     
        # set brightness
        sbc.set_brightness(int(b_level))
 
    # Display Video and when 'q' is entered,
    # destroy the window
    cv2.imshow('Image', frame)
    if cv2.waitKey(1) & 0xff == ord('q'):
        break

下面是完整的实现:

Python3

# Importing Libraries
import cv2
import mediapipe as mp
from math import hypot
import screen_brightness_control as sbc
import numpy as np
 
# Initializing the Model
mpHands = mp.solutions.hands
hands = mpHands.Hands(
    static_image_mode=False,
    model_complexity=1,
    min_detection_confidence=0.75,
    min_tracking_confidence=0.75,
    max_num_hands=2)
 
Draw = mp.solutions.drawing_utils
 
# Start capturing video from webcam
cap = cv2.VideoCapture(0)
 
while True:
    # Read video frame by frame
    _, frame = cap.read()
 
    # Flip image
    frame = cv2.flip(frame, 1)
 
    # Convert BGR image to RGB image
    frameRGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
    # Process the RGB image
    Process = hands.process(frameRGB)
 
    landmarkList = []
    # if hands are present in image(frame)
    if Process.multi_hand_landmarks:
        # detect handmarks
        for handlm in Process.multi_hand_landmarks:
            for _id, landmarks in enumerate(handlm.landmark):
                # store height and width of image
                height, width, color_channels = frame.shape
 
                # calculate and append x, y coordinates
                # of handmarks from image(frame) to lmList
                x, y = int(landmarks.x*width), int(landmarks.y*height)
                landmarkList.append([_id, x, y])
 
            # draw Landmarks
            Draw.draw_landmarks(frame, handlm,
                                mpHands.HAND_CONNECTIONS)
 
    # If landmarks list is not empty
    if landmarkList != []:
        # store x,y coordinates of (tip of) thumb
        x_1, y_1 = landmarkList[4][1], landmarkList[4][2]
 
        # store x,y coordinates of (tip of) index finger
        x_2, y_2 = landmarkList[8][1], landmarkList[8][2]
 
        # draw circle on thumb and index finger tip
        cv2.circle(frame, (x_1, y_1), 7, (0, 255, 0), cv2.FILLED)
        cv2.circle(frame, (x_2, y_2), 7, (0, 255, 0), cv2.FILLED)
 
        # draw line from tip of thumb to tip of index finger
        cv2.line(frame, (x_1, y_1), (x_2, y_2), (0, 255, 0), 3)
 
        # calculate square root of the sum of
        # squares of the specified arguments.
        L = hypot(x_2-x_1, y_2-y_1)
 
        # 1-D linear interpolant to a function
        # with given discrete data points
        # (Hand range 15 - 220, Brightness
        # range 0 - 100), evaluated at length.
        b_level = np.interp(L, [15, 220], [0, 100])
 
        # set brightness
        sbc.set_brightness(int(b_level))
 
    # Display Video and when 'q' is entered, destroy
    # the window
    cv2.imshow('Image', frame)
    if cv2.waitKey(1) & 0xff == ord('q'):
        break

输出: