1. openCV는 비디오 스트림을 읽고 그림의 각 프레임에 직사각형을 그립니다.
2. 미디어파이프를 사용하여 손가락 키 포인트 좌표를 얻습니다.
3. 손가락의 좌표 위치와 직사각형의 좌표 위치를 기준으로 손가락 점이 직사각형 위에 있는지 확인합니다. 그렇다면 직사각형이 손가락의 움직임을 따라갑니다.
환경 준비:
python: 3.8.8
opencv: 4.2.0.32
mediapipe: 0.8.10.1
참고:
1. 높거나 너무 낮음 예를 들어 카메라를 켤 수 없거나 충돌이 발생하는 경우 Python 버전은 선택 가능한 opencv 버전에 영향을 미칩니다.
2. pip install mediapipe 후에는 OpenCV가 정상적으로 사용되지 않을 수 있습니다. 제거하고 다시 다운로드하세요.
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()
이제 이 코드를 실행하면 카메라가 켜지고 왼쪽 상단에 100이 표시됩니다. 모서리 *100 보라색 직사각형.
pip install mediapipe
이때 openCV를 갑자기 사용할 수 없게 되는 등의 문제가 발생할 수 있습니다. 문제가 되지 않으니 제거하고 다시 다운로드하세요.
mediapipe 세부정보: Hands - mediapipe (google.github.io)
간단히 말하면 손가락 키 포인트 21개의 좌표, 즉 영상 화면에서의 위치 비율(0~1)을 반환해 줍니다. ), 해당 화면의 너비와 높이를 곱하여 손가락에 해당하는 좌표를 얻습니다.
이번에는 8번과 12번인 검지와 중지 끝부분을 사용했어요.
2.1 몇 가지 기본 정보 구성
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 이미지의 각 프레임을 처리할 때
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)
를 추가합니다. 비디오 스트림에서 이미지의 각 프레임을 읽을 때 BGR에서 RGB로 변환하여 미디어 파이프에 공급합니다. 생성된 손 개체를 읽고 이 그림에서 손가락의 주요 지점에 대한 정보를 반환합니다. 그림의 각 프레임에 계속해서 그리기만 하면 됩니다.
# 如果结果不为空 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 이 단계의 전체 코드
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()
우리의 실험에서는 사각형을 드래그해야 하며 드래그되지 않는 경우도 있으므로 검지 손가락( 8) 이전 단계에 따른 가운데 손가락(12)의 손가락 끝 위치가 서로 가까워지면 블록과 일치할 때 손가락의 위치에 따라 블록의 좌표를 변경하게 됩니다.
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('frame',frame) # 退出条件 if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
위 내용은 Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!