Heim  >  Artikel  >  Backend-Entwicklung  >  So erzielen Sie mit Python+OpenCV den Effekt des Ziehens virtueller Quadrate

So erzielen Sie mit Python+OpenCV den Effekt des Ziehens virtueller Quadrate

WBOY
WBOYnach vorne
2023-05-15 19:22:12962Durchsuche

1. Projekteffekt

2. Kernprozess

1.

2. Verwenden Sie Mediapipe, um Finger-Schlüsselpunktkoordinaten zu erhalten.

3. Bestimmen Sie anhand der Koordinatenposition des Fingers und der Koordinatenposition des Rechtecks, ob sich der Fingerpunkt auf dem Rechteck befindet. Wenn ja, folgt das Rechteck der Fingerbewegung.

3. Codeprozess

Umgebungsvorbereitung:

Python: 3.8.8

opencv: 4.2.0.32# 🎜🎜#

mediapipe: 0.8.10.1

Hinweis:

1. Wenn die OpenCV-Version zu hoch oder zu niedrig ist, können einige Probleme auftreten, z Die Kamera lässt sich nicht öffnen oder stürzt ab. Bei anderen Problemen wirkt sich die Python-Version auf die auswählbare Version von opencv aus.

2. OpenCV kann nach der Installation von pip mediapipe möglicherweise nicht mehr normal verwendet werden.

1. Lesen Sie das Kameravideo und zeichnen Sie ein Rechteck

import cv2
import time
import numpy as np
 
 
# 调用摄像头 0 默认摄像头 
cap = cv2.VideoCapture(0)
 
# 初始方块数据
x = 100
y = 100
w = 100
h = 100
 
# 读取一帧帧照片
while True:
    # 返回frame图片
    rec,frame = cap.read()
    
    # 镜像
    frame = cv2.flip(frame,1)
    
    # 画矩形 
    cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 255), -1)
 
    # 显示画面
    cv2.imshow('frame',frame)
    
    # 退出条件
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    
cap.release()
cv2.destroyAllWindows()

Dies ist ein sehr grundlegender Schritt, wenn wir diesen Code ausführen und die Kamera eingeschaltet ist. Wir werden überrascht sein, wenn wir in Ihrem hübschen Gesicht ein 100*100 großes violettes Rechteck in der oberen linken Ecke sehen.

2. Mediapipe importieren, um Fingerkoordinaten zu verarbeiten

pip install mediapipe

Es kann zu Problemen kommen, wie zum Beispiel, dass openCV plötzlich unbrauchbar wird. Es spielt keine Rolle, es zu deinstallieren Laden Sie es erneut herunter.

mediapipe-Details: Hände – mediapipe (google.github.io)

So erzielen Sie mit Python+OpenCV den Effekt des Ziehens virtueller Quadrate

Einfach ausgedrückt: Es wird zu The zurückkehren Die Koordinaten unserer 21 Finger-Schlüsselpunkte, das heißt ihr Positionsverhältnis auf dem Videobildschirm (0 ~ 1), multiplizieren wir mit der Breite und Höhe des entsprechenden Bildschirms, um die Koordinaten zu erhalten, die den Fingern entsprechen.

Dieses Mal habe ich die Spitzen meines Zeigefingers und Mittelfingers verwendet, also die Nummern 8 und 12.

2.1 Konfigurieren Sie einige grundlegende Informationen

import cv2
import time
import numpy as np
import mediapipe as mp
 
 
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
 
hands =  mp_hands.Hands(
    static_image_mode=True,
    max_num_hands=2,
    min_detection_confidence=0.5)

2.2 Fügen Sie bei der Verarbeitung jedes Bildrahmens #🎜 🎜 hinzu #

    frame.flags.writeable = False
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    # 返回结果
    results = hands.process(frame)
 
    frame.flags.writeable = True
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
Wenn wir jedes Bild im Videostream lesen, konvertieren wir es von BGR in RGB und stellen es dem von mediapipe generierten Handobjekt zum Lesen zur Verfügung. Es werden die Informationen der Schlüsselpunkte der Finger zurückgegeben In diesem Bild müssen wir einfach weiter darauf malen, auf jedem Rahmen.

    # 如果结果不为空
    if results.multi_hand_landmarks:
 
        # 遍历双手(根据读取顺序,一只只手遍历、画画)
        for hand_landmarks in results.multi_hand_landmarks:
            mp_drawing.draw_landmarks(
                frame,
                hand_landmarks,
                mp_hands.HAND_CONNECTIONS,
                mp_drawing_styles.get_default_hand_landmarks_style(),
                mp_drawing_styles.get_default_hand_connections_style())

2.3 Der vollständige Code dieses Schritts

import cv2
import time
import numpy as np
import mediapipe as mp
 
 
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
 
hands =  mp_hands.Hands(
    static_image_mode=True,
    max_num_hands=2,
    min_detection_confidence=0.5)
 
 
# 调用摄像头 0 默认摄像头 
cap = cv2.VideoCapture(0)
 
# 方块初始数组
x = 100
y = 100
w = 100
h = 100
 
 
# 读取一帧帧照片
while True:
    # 返回frame图片
    rec,frame = cap.read()
    
    # 镜像
    frame = cv2.flip(frame,1)
    
    
    
    frame.flags.writeable = False
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    # 返回结果
    results = hands.process(frame)
 
    frame.flags.writeable = True
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    
    
    # 如果结果不为空
    if results.multi_hand_landmarks:
 
        # 遍历双手(根据读取顺序,一只只手遍历、画画)
        # results.multi_hand_landmarks n双手
        # hand_landmarks 每只手上21个点信息
        for hand_landmarks in results.multi_hand_landmarks:
            mp_drawing.draw_landmarks(
                frame,
                hand_landmarks,
                mp_hands.HAND_CONNECTIONS,
                mp_drawing_styles.get_default_hand_landmarks_style(),
                mp_drawing_styles.get_default_hand_connections_style())
    
    
    # 画矩形 
    cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 255), -1)
 
    # 显示画面
    cv2.imshow('frame',frame)
    
    # 退出条件
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    
cap.release()
cv2.destroyAllWindows()
3. Positionsberechnung

Unser Experiment erfordert das Ziehen Quadratisch wird es sicherlich Zeiten geben, in denen Sie nicht ziehen möchten, also können Sie genauso gut die Position der Spitzen Ihres Zeigefingers (8) und Ihres Mittelfingers (12) entsprechend dem vorherigen Schritt ermitteln, wenn diese nahe beieinander liegen , wir verwenden die Position der Fingerspitzen, wenn sie mit dem Quadrat übereinstimmen. Position ändert die Koordinaten des Blocks.

So erzielen Sie mit Python+OpenCV den Effekt des Ziehens virtueller QuadrateVollständiger Code

import cv2
import time
import math
import numpy as np
import mediapipe as mp
 
# mediapipe配置
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
hands =  mp_hands.Hands(
    static_image_mode=True,
    max_num_hands=2,
    min_detection_confidence=0.5)
 
 
# 调用摄像头 0 默认摄像头 
cap = cv2.VideoCapture(0)
 
# cv2.namedWindow("frame", 0)
# cv2.resizeWindow("frame", 960, 640)
 
 
# 获取画面宽度、高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
 
 
# 方块初始数组
x = 100
y = 100
w = 100
h = 100
 
L1 = 0
L2 = 0
 
on_square = False
square_color = (0, 255, 0)
 
# 读取一帧帧照片
while True:
    # 返回frame图片
    rec,frame = cap.read()
    
    # 镜像
    frame = cv2.flip(frame,1)
    
    
    
    frame.flags.writeable = False
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    # 返回结果
    results = hands.process(frame)
 
    frame.flags.writeable = True
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    
    
    # 如果结果不为空
    if results.multi_hand_landmarks:
 
 
        # 遍历双手(根据读取顺序,一只只手遍历、画画)
        # results.multi_hand_landmarks n双手
        # hand_landmarks 每只手上21个点信息
        for hand_landmarks in results.multi_hand_landmarks:
            mp_drawing.draw_landmarks(
                frame,
                hand_landmarks,
                mp_hands.HAND_CONNECTIONS,
                mp_drawing_styles.get_default_hand_landmarks_style(),
                mp_drawing_styles.get_default_hand_connections_style())
            
            # 记录手指每个点的x y 坐标
            x_list = []
            y_list = []
            for landmark in hand_landmarks.landmark:
                x_list.append(landmark.x)
                y_list.append(landmark.y)
                
            
            # 获取食指指尖
            index_finger_x, index_finger_y = int(x_list[8] * width),int(y_list[8] * height)
 
            # 获取中指
            middle_finger_x,middle_finger_y = int(x_list[12] * width), int(y_list[12] * height)
 
 
            # 计算两指尖距离
            finger_distance = math.hypot((middle_finger_x - index_finger_x), (middle_finger_y - index_finger_y))
 
            # 如果双指合并(两之间距离近)
            if finger_distance < 60:
 
                # X坐标范围 Y坐标范围
                if (index_finger_x > x and index_finger_x < (x + w)) and (
                        index_finger_y > y and index_finger_y < (y + h)):
 
                    if on_square == False:
                        L1 = index_finger_x - x
                        L2 = index_finger_y - y
                        square_color = (255, 0, 255)
                        on_square = True
 
            else:
                # 双指不合并/分开
                on_square = False
                square_color = (0, 255, 0)
 
            # 更新坐标
            if on_square:
                x = index_finger_x - L1
                y = index_finger_y - L2
            
            
 
    # 图像融合 使方块不遮挡视频图片
    overlay = frame.copy()
    cv2.rectangle(frame, (x, y), (x + w, y + h), square_color, -1)
    frame = cv2.addWeighted(overlay, 0.5, frame, 1 - 0.5, 0)
    
 
    # 显示画面
    cv2.imshow(&#39;frame&#39;,frame)
    
    # 退出条件
    if cv2.waitKey(1) & 0xFF == ord(&#39;q&#39;):
        break
    
cap.release()
cv2.destroyAllWindows()

Das obige ist der detaillierte Inhalt vonSo erzielen Sie mit Python+OpenCV den Effekt des Ziehens virtueller Quadrate. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen