이 Python 프로젝트에서는 간단한 AR 그리기 앱을 만들어 보겠습니다. 웹캠과 손 제스처를 사용하여 화면에 가상으로 그림을 그리고 브러시를 사용자 정의하고 창작물을 저장할 수도 있습니다!
시작하려면 다음을 사용하여 새 폴더를 만들고 새 가상 환경을 초기화하세요.
python -m venv venv
./venv/Scripts/activate
다음으로 원하는 pip 또는 설치 프로그램을 사용하여 필수 라이브러리를 설치합니다.
pip install mediapipe
pip install opencv-python
Python에 최신 버전의 mediapipe를 설치하는 데 문제가 있을 수 있습니다. 나는 이 블로그를 작성하면서 Python 3.11.2를 사용하고 있습니다. 반드시 Python에서 호환되는 버전을 사용하세요.
첫 번째 단계는 웹캠을 설정하고 비디오 피드를 표시하는 것입니다. OpenCV의 VideoCapture를 사용하여 카메라에 액세스하여 프레임을 지속적으로 표시해 보겠습니다.
import cv2 # The argument '0' specifies the default camera (usually the built-in webcam). cap = cv2.VideoCapture(0) # Start an infinite loop to continuously capture video frames from the webcam while True: # Read a single frame from the webcam # `ret` is a boolean indicating success; `frame` is the captured frame. ret, frame = cap.read() # Check if the frame was successfully captured # If not, break the loop and stop the video capture process. if not ret: break # Flip the frame horizontally (like a mirror image) frame = cv2.flip(frame, 1) # Display the current frame in a window named 'Webcam Feed' cv2.imshow('Webcam Feed', frame) # Wait for a key press for 1 millisecond # If the 'q' key is pressed, break the loop to stop the video feed. if cv2.waitKey(1) & 0xFF == ord('q'): break # Release the webcam resource to make it available for other programs cap.release() # Close all OpenCV-created windows cv2.destroyAllWindows()
아시나요?
OpenCV에서 cv2.waitKey()를 사용할 때 반환된 키 코드에는 플랫폼에 따라 추가 비트가 포함될 수 있습니다. 키 누름을 올바르게 감지하려면 결과를 0xFF로 마스크하여 하위 8비트(실제 ASCII 값)를 격리할 수 있습니다. 이것이 없으면 일부 시스템에서 주요 비교가 실패할 수 있으므로 일관된 동작을 위해 항상 & 0xFF를 사용하십시오!
미디어파이프의 Hands 솔루션을 사용하여 손을 감지하고 검지, 중지 등 주요 랜드마크의 위치를 추출해 보겠습니다.
import cv2 import mediapipe as mp # Initialize the MediaPipe Hands module mp_hands = mp.solutions.hands # Load the hand-tracking solution from MediaPipe hands = mp_hands.Hands( min_detection_confidence=0.9, min_tracking_confidence=0.9 ) cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break # Flip the frame horizontally to create a mirror effect frame = cv2.flip(frame, 1) # Convert the frame from BGR (OpenCV default) to RGB (MediaPipe requirement) frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Process the RGB frame to detect and track hands result = hands.process(frame_rgb) # If hands are detected in the frame if result.multi_hand_landmarks: # Iterate through all detected hands for hand_landmarks in result.multi_hand_landmarks: # Get the frame dimensions (height and width) h, w, _ = frame.shape # Calculate the pixel coordinates of the tip of the index finger cx, cy = int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].x * w), \ int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].y * h) # Calculate the pixel coordinates of the tip of the middle finger mx, my = int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].x * w), \ int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].y * h) # Draw a circle at the index finger tip on the original frame cv2.circle(frame, (cx, cy), 10, (0, 255, 0), -1) # Green circle with radius 10 # Display the processed frame in a window named 'Webcam Feed' cv2.imshow('Webcam Feed', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # Exit the loop if 'q' is pressed # Release the webcam resources for other programs cap.release() cv2.destroyAllWindows()
검지 손가락을 추적하여 검지와 중지가 임계 거리만큼 떨어져 있어야만 그리기를 허용합니다.
원래 프레임에 그릴 검지의 좌표 목록을 유지하고 가운데 손가락이 충분히 가까울 때마다 이 좌표 배열에 None을 추가하여 파손을 나타냅니다.
import cv2 import mediapipe as mp import math # Initialize the MediaPipe Hands module mp_hands = mp.solutions.hands hands = mp_hands.Hands( min_detection_confidence=0.9, min_tracking_confidence=0.9 ) # Variables to store drawing points and reset state draw_points = [] # A list to store points where lines should be drawn reset_drawing = False # Flag to indicate when the drawing should reset # Brush settings brush_color = (0, 0, 255) brush_size = 5 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break frame = cv2.flip(frame, 1) frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) result = hands.process(frame_rgb) # If hands are detected if result.multi_hand_landmarks: for hand_landmarks in result.multi_hand_landmarks: h, w, _ = frame.shape # Get the frame dimensions (height and width) # Get the coordinates of the index finger tip cx, cy = int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].x * w), \ int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].y * h) # Get the coordinates of the middle finger tip mx, my = int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].x * w), \ int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].y * h) # Calculate the distance between the index and middle finger tips distance = math.sqrt((mx - cx) ** 2 + (my - cy) ** 2) # Threshold distance to determine if the fingers are close (used to reset drawing) threshold = 40 # If the fingers are far apart if distance > threshold: if reset_drawing: # Check if the drawing was previously reset draw_points.append(None) # None means no line reset_drawing = False draw_points.append((cx, cy)) # Add the current point to the list for drawing else: # If the fingers are close together set the flag to reset drawing reset_drawing = True # # Draw the lines between points in the `draw_points` list for i in range(1, len(draw_points)): if draw_points[i - 1] and draw_points[i]: # Only draw if both points are valid cv2.line(frame, draw_points[i - 1], draw_points[i], brush_color, brush_size) cv2.imshow('Webcam Feed', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # Release the webcam and close all OpenCV windows cap.release() cv2.destroyAllWindows()
위 내용은 초보자 Python 프로젝트: OpenCV 및 Mediapipe를 사용하여 증강 현실 그리기 앱 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!