>  기사  >  백엔드 개발  >  Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법

Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법

WBOY
WBOY앞으로
2023-05-15 19:22:12963검색

1. 프로젝트 효과

2. 핵심 프로세스

1. openCV는 비디오 스트림을 읽고 그림의 각 프레임에 직사각형을 그립니다.

2. 미디어파이프를 사용하여 손가락 키 포인트 좌표를 얻습니다.

3. 손가락의 좌표 위치와 직사각형의 좌표 위치를 기준으로 손가락 점이 직사각형 위에 있는지 확인합니다. 그렇다면 직사각형이 손가락의 움직임을 따라갑니다.

3. 코드 프로세스

환경 준비:

python: 3.8.8

opencv: 4.2.0.32

mediapipe: 0.8.10.1

참고:

1. 높거나 너무 낮음 예를 들어 카메라를 켤 수 없거나 충돌이 발생하는 경우 Python 버전은 선택 가능한 opencv 버전에 영향을 미칩니다.

2. pip install mediapipe 후에는 OpenCV가 정상적으로 사용되지 않을 수 있습니다. 제거하고 다시 다운로드하세요.

1. 카메라 영상을 읽고 직사각형을 그립니다

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 보라색 직사각형.

2. 손가락 좌표 처리를 위해 미디어 파이프 가져오기

pip install mediapipe

이때 openCV를 갑자기 사용할 수 없게 되는 등의 문제가 발생할 수 있습니다. 문제가 되지 않으니 제거하고 다시 다운로드하세요.

mediapipe 세부정보: Hands - mediapipe (google.github.io)

Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법

간단히 말하면 손가락 키 포인트 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()

3. 위치 계산

우리의 실험에서는 사각형을 드래그해야 하며 드래그되지 않는 경우도 있으므로 검지 손가락( 8) 이전 단계에 따른 가운데 손가락(12)의 손가락 끝 위치가 서로 가까워지면 블록과 일치할 때 손가락의 위치에 따라 블록의 좌표를 변경하게 됩니다.

Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법

전체 코드

Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법

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()

위 내용은 Python+OpenCV를 사용하여 가상 사각형 드래그 효과를 얻는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제