# data[].attributes.headline
미디어 파이프 솔루션 사이트

# data[].attributes.subject
미디어 파이프 솔루션 사이트

# data[].attributes.attachment_link.readable_text
MediaPipe 솔루션은 애플리케이션에 인공지능 (AI) 및 머신러닝 (ML) 기법을 빠르게 적용할 수 있는 라이브러리와 도구 모음을 제공합니다. 이러한 솔루션을 애플리케이션에 즉시 연결하고 니즈에 맞게 맞춤설정한 후 여러 개발 플랫폼에서 사용할 수 있습니다. MediaPipe Solutions는 MediaPipe 오픈소스 프로젝트 에 포함되므로 애플리케이션 요구사항에 맞게 솔루션 코드를 추가로 맞춤설정할 수 있습니다. MediaPipe 솔루션 모음에는 다음이 포함됩니다.

다음 라이브러리 및 리소스는 각 MediaPipe 솔루션의 핵심 기능을 제공합니다.

MediaPipe 태스크: 솔루션 배포를 위한 교차 플랫폼 API 및 라이브러리입니다. 자세히 알아보기

MediaPipe 모델: 각 솔루션에 사용할 수 있도록 선행 학습된 즉시 실행 가능한 모델입니다.

이러한 도구를 사용하면 솔루션을 맞춤설정하고 평가할 수 있습니다.

MediaPipe Model Maker: 데이터로 솔루션의 모델을 맞춤설정합니다. 자세히 알아보기

MediaPipe Studio: 브라우저에서 솔루션을 시각화, 평가 및 벤치마킹합니다. 자세히 알아보기

사용 가능한 솔루션

MediaPipe 솔루션은 여러 플랫폼에서 사용할 수 있습니다. 각 솔루션에는 하나 이상의 모델이 포함되어 있으며 일부 솔루션의 모델도 맞춤설정할 수 있습니다. 다음 목록은 지원되는 각 플랫폼에서 사용할 수 있는 솔루션과 Model Maker를 사용하여 모델을 맞춤설정할 수 있는지 여부를 보여줍니다.

사용해 보기

vision, 텍스트, 오디오 작업을 포함하여 왼쪽 탐색 트리에 나열된 작업을 선택하여 MediaPipe 솔루션을 시작할 수 있습니다. MediaPipe 태스크와 함께 사용할 개발 환경을 설정하는 데 도움이 필요하면 Android, 웹 앱, Python 의 설정 가이드를 확인하세요.

기존 솔루션

2023년 3월 1일부터 아래 나열된 MediaPipe 기존 솔루션에 대한 지원이 종료되었습니다. 다른 모든 MediaPipe 기존 솔루션은 새 MediaPipe 솔루션으로 업그레이드됩니다. 자세한 내용은 아래 목록을 참고하세요. 모든 MediaPipe 기존 솔루션을 위해 코드 저장소 와 사전 빌드된 바이너리는 계속 그대로 제공됩니다.

# data[].attributes.attachment_link.title
MediaPipe 솔루션 가이드 | Edge | Google for Developers

# data[].attributes.attachment_link.description
MediaPipe 솔루션은 애플리케이션에 인공지능 (AI) 및 머신러닝 (ML) 기법을 빠르게 적용할 수 있는 라이브러리와 도구 모음을 제공합니다. 이러한 솔루션을 애플리케이션에 즉시 연결하고 니즈에 맞게 맞춤설정한 후 여러 개발 플랫폼에서 사용할 수 있습니다. MediaPipe Solutions는 MediaPipe 오픈소스 프로젝트 에 포함되므로 애플리케이션 요구사항에 맞게 솔루션 코드를 추가로 맞춤설정할 수 있습니다.

# data[].attributes.body
기본 핸드랜드마크 인식

# data[].attributes.attachment_link.title
미디어 파이프 실습1 (1)

# data[].attributes.body
1. 비주얼 스튜디오 실행

2. 에러나는 코드 수정해보기

3. 추가 코드( 반복 while True: ,종료키 수정, 좌우반전, 여러개 손인식?,...)

4. 과제 셀프체크 💎

5. 오늘의 코드 설문 https://forms.gle/SRXxN4mfABeRngaU8

# data[].attributes.body
왼손오른손 구분-> 손가락 카운팅까지

# data[].attributes.attachment_link.title
미디어 파이프 실습2 (3)

# data[].attributes.headline
프로젝트 학생 제출용 공유 양식

# data[].attributes.subject
프로젝트 학생 제출용 공유 양식

# data[].attributes.body
사본으로 저장 후 사용

# data[].attributes.attachment_link.title
손 제스쳐 인식 제작2

# data[].attributes.body
import cv2

import mediapipe as mp

import math

# Mediapipe 초기화

mp_hands = mp.solutions.hands

mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands(

max_num_hands=1,

min_detection_confidence=0.7,

min_tracking_confidence=0.5

)

# 실험 상태 변수

experiment_started = False

selected_variable = None

adjusting = False

current_gesture = "None"

# 각도 계산 함수 (사용 안 하지만 참고용)

def calculate_angle(a, b, c):

ab = [a[0] - b[0], a[1] - b[1]]

bc = [c[0] - b[0], c[1] - b[1]]

dot = ab[0] bc[0] + ab[1] bc[1]

det = ab[0] bc[1] - ab[1] bc[0]

angle = math.atan2(det, dot) * 180.0 / math.pi

return abs(angle)

# 손가락 열림 감지

def detect_finger_open(landmarks, width, height):

finger_tips = [4, 8, 12, 16, 20]

finger_ips = [3, 7, 11, 15, 19]

finger_names = ["Thumb", "Index", "Middle", "Ring", "Pinky"]

open_fingers = []

open_threshold = 160 # 각도 기준 (180에 가까울수록 더 곧게 펴짐)

wrist = (landmarks[0].x width, landmarks[0].y height)

for tip_idx, ip_idx, name in zip(finger_tips, finger_ips, finger_names):

tip = (landmarks[tip_idx].x width, landmarks[tip_idx].y height)

ip = (landmarks[ip_idx].x width, landmarks[ip_idx].y height)

angle = calculate_angle(tip, ip, wrist)

if angle > open_threshold:

open_fingers.append(name)

return open_fingers

# 제스처 인식

def recognize_gesture(open_fingers, landmarks, width, height):

if len(open_fingers) == 5:

return "Start_Experiment"

elif len(open_fingers) == 0:

return "Stop_Experiment"

elif len(open_fingers) == 1 and "Index" in open_fingers:

return "Select"

# 엄지와 검지의 거리로 Pinch 감지

thumb_tip = landmarks[4]

index_tip = landmarks[8]

distance = math.hypot((thumb_tip.x - index_tip.x) * width,

(thumb_tip.y - index_tip.y) * height)

if distance < 40:

return "Pinch"

return "None"

# 제스처에 따른 동작 수행

def perform_action(gesture):

global experiment_started, selected_variable, adjusting

if gesture == "Start_Experiment":

if not experiment_started:

print("🧪 실험 시작!")

experiment_started = True

selected_variable = None

adjusting = False

elif gesture == "Stop_Experiment":

if experiment_started:

print("🛑 실험 종료! 데이터 저장 완료.")

experiment_started = False

selected_variable = None

adjusting = False

elif gesture == "Select" and experiment_started:

print("👉 변수 선택: 온도")

selected_variable = "온도"

adjusting = False

elif gesture == "Pinch" and selected_variable:

if not adjusting:

print(f"🤏 {selected_variable} 조절 시작")

adjusting = True

else:

print(f"⚙️ {selected_variable} 값 조정 중...")

elif gesture == "None":

if adjusting:

print("🔓 조절 종료")

adjusting = False

# 웹캠 실행

cap = cv2.VideoCapture(0)

while True:

success, frame = cap.read()

if not success:

break

frame = cv2.flip(frame, 1)

h, w, _ = frame.shape

image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

result = hands.process(image_rgb)

if result.multi_hand_landmarks:

for hand_landmarks, handedness in zip(result.multi_hand_landmarks, result.multi_handedness):

mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

open_fingers = detect_finger_open(hand_landmarks.landmark, w, h)

gesture = recognize_gesture(open_fingers, hand_landmarks.landmark, w, h)

if gesture != current_gesture:

current_gesture = gesture

perform_action(gesture)

# 화면에 현재 상태 시각화

cv2.putText(frame, f"Gesture: {gesture}", (10, 40),

cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 3)

cv2.putText(frame, f"Experiment: {'ON' if experiment_started else 'OFF'}", (10, 80),

cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 100, 0), 3)

if selected_variable:

cv2.putText(frame, f"Variable: {selected_variable}", (10, 120),

cv2.FONT_HERSHEY_SIMPLEX, 1.2, (100, 255, 255), 3)

if adjusting:

cv2.putText(frame, f"Adjusting: YES", (10, 160),

cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 100, 255), 3)

else:

current_gesture = "None"

cv2.imshow("Smart Lab Assistant - Gesture Control", frame)

if cv2.waitKey(1) & 0xFF == 27: # ESC 키

break

cap.release()

cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.headline
김민준- 마우스 대신 손가락 클릭!

# data[].attributes.subject
김민준- 마우스 대신 손가락 클릭!

# data[].attributes.body
import cv2
import mediapipe as mp
import pyautogui

# 초기 설정
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1, min_detection_confidence=0.7)
mp_draw = mp.solutions.drawing_utils

# 화면 크기 (모니터 해상도)
screen_w, screen_h = pyautogui.size()

# 손가락 끝 인덱스
finger_tips = [4, 8, 12, 16, 20]

cap = cv2.VideoCapture(0)

while True:
    success, img = cap.read()
    img = cv2.flip(img, 1)
    h, w, _ = img.shape
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    result = hands.process(img_rgb)

    if result.multi_hand_landmarks:
        for handLms in result.multi_hand_landmarks:
            # 손 landmark 그리기
            mp_draw.draw_landmarks(img, handLms, mp_hands.HAND_CONNECTIONS)

            # 랜드마크 위치 가져오기
            landmarks = handLms.landmark

            # 손목 위치로 마우스 이동
            wrist = landmarks[0]
            x = int(wrist.x * w)
            y = int(wrist.y * h)

            screen_x = int(wrist.x * screen_w)
            screen_y = int(wrist.y * screen_h)
            pyautogui.moveTo(screen_x, screen_y)

            # 손가락 접힘 여부 판단
            fingers = []
            # 엄지
            fingers.append(landmarks[4].x < landmarks[3].x)
            # 나머지 손가락
            for tip_id in [8, 12, 16, 20]:
                fingers.append(landmarks[tip_id].y > landmarks[tip_id - 2].y)

            # 모든 손가락이 접혔으면 클릭
            if fingers.count(True) == 5:
                pyautogui.click()
                cv2.putText(img, "Click!", (x, y - 20),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)

    cv2.imshow("Virtual Mouse", img)
    if cv2.waitKey(5) & 0xFF == 27:  # ESC
        break

cap.release()
cv2.destroyAllWindows()

import cv2
import mediapipe as mp
import pyautogui

# 화면 해상도
screen_w, screen_h = pyautogui.size()

# MediaPipe 세팅
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1, min_detection_confidence=0.7)
mp_draw = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)
cap.set(3, 640)  # 너비
cap.set(4, 480)  # 높이

# 손가락 끝 인덱스
finger_tips = [4, 8, 12, 16, 20]

while True:
    success, img = cap.read()
    img = cv2.flip(img, 1)
    h, w, _ = img.shape
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    result = hands.process(img_rgb)

    if result.multi_hand_landmarks:
        for handLms in result.multi_hand_landmarks:
            mp_draw.draw_landmarks(img, handLms, mp_hands.HAND_CONNECTIONS)

            landmarks = handLms.landmark

            # 손가락 접힘 확인
            fingers = []
            fingers.append(landmarks[4].x < landmarks[3].x)  # 엄지
            for tip in [8, 12, 16, 20]:
                fingers.append(landmarks[tip].y > landmarks[tip - 2].y)

            # 손목 위치 → 마우스 커서 이동
            wrist = landmarks[0]
            cam_x = wrist.x
            cam_y = wrist.y

            # 🔧 손의 움직임이 좁은 범위에만 있는 걸 보정
            # (중앙 기준으로 좌우 50%, 상하 50%로 확대)
            # 즉, 손이 화면 중앙 근처에서만 움직여도 화면 전체 커버하게
            screen_x = int(screen_w * cam_x * 1.8)  # 확대 배율
            screen_y = int(screen_h * cam_y * 1.8)

            # 화면 밖으로 나가는 거 방지
            screen_x = min(screen_w - 1, max(0, screen_x))
            screen_y = min(screen_h - 1, max(0, screen_y))

            pyautogui.moveTo(screen_x, screen_y)

            # 손가락 5개 모두 접으면 클릭
            if fingers.count(True) == 5:
                pyautogui.click()
                cv2.putText(img, "Click!", (int(wrist.x * w), int(wrist.y * h) - 20),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)

    cv2.imshow("Virtual Mouse", img)
    if cv2.waitKey(5) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import numpy as np
import random

# MediaPipe 설정
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1)
mp_draw = mp.solutions.drawing_utils

# 화면 설정
WIDTH, HEIGHT = 800, 600
brick_rows, brick_cols = 5, 8
brick_width = WIDTH // brick_cols
brick_height = 30
bar_width = 120
bar_height = 15
bar_y = HEIGHT - 50

# 게임 상태
game_started = False
game_over = False

# 기본 초기화 함수
def reset_game():
    global bar_x, balls, bricks, score, level, speed_multiplier
    bar_x = WIDTH // 2 - bar_width // 2
    balls = [{'x': WIDTH // 2, 'y': HEIGHT // 2, 'dx': 5, 'dy': -5}]
    score = 0
    level = 1
    speed_multiplier = 1.0
    bricks = []
    for row in range(brick_rows):
        for col in range(brick_cols):
            x = col * brick_width
            y = row * brick_height + 50
            brick_type = "normal"
            rand = random.random()
            if rand < 0.1:
                brick_type = "green"
            elif rand < 0.2:
                brick_type = "red"
            bricks.append({'x': x, 'y': y, 'w': brick_width - 2, 'h': brick_height - 2, 'type': brick_type})

reset_game()

# 카메라 시작
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        print("❗ 카메라를 불러올 수 없습니다.")
        break

    frame = cv2.flip(frame, 1)
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = hands.process(rgb)

    if result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
            x = int(hand_landmarks.landmark[8].x * WIDTH)
            bar_x = max(0, min(WIDTH - bar_width, x - bar_width // 2))

    game_frame = np.zeros((HEIGHT, WIDTH, 3), np.uint8)

    if not game_started:
        # 시작 대기 화면
        cv2.putText(game_frame, "Brick Breaker", (WIDTH//2 - 200, HEIGHT//2 - 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,255,255), 3)
        cv2.putText(game_frame, "Press SPACE to Start", (WIDTH//2 - 220, HEIGHT//2 + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
    elif game_over:
        # 게임 오버 화면
        cv2.putText(game_frame, "Game Over", (WIDTH//2 - 160, HEIGHT//2 - 20), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
        cv2.putText(game_frame, "Press R to Restart or ESC to Exit", (WIDTH//2 - 270, HEIGHT//2 + 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
    else:
        # 게임 진행 중
        for ball in balls:
            ball['x'] += int(ball['dx'] * speed_multiplier)
            ball['y'] += int(ball['dy'] * speed_multiplier)

            if ball['x'] <= 0 or ball['x'] >= WIDTH:
                ball['dx'] *= -1
            if ball['y'] <= 0:
                ball['dy'] *= -1
            if bar_y < ball['y'] + 10 < bar_y + bar_height and bar_x < ball['x'] < bar_x + bar_width:
                ball['dy'] *= -1

        for ball in balls[:]:
            for b in bricks[:]:
                if b['x'] < ball['x'] < b['x'] + b['w'] and b['y'] < ball['y'] < b['y'] + b['h']:
                    bricks.remove(b)
                    ball['dy'] *= -1
                    score += 10
                    if b['type'] == "green" and len(balls) < 5:
                        balls.append({'x': ball['x'], 'y': ball['y'], 'dx': random.choice([-5, 5]), 'dy': -5})
                    elif b['type'] == "red" and len(balls) > 1:
                        balls.remove(ball)
                    break

        level = 1 + score // 100
        speed_multiplier = 1.0 + (level - 1) * 0.2

        balls = [b for b in balls if b['y'] <= HEIGHT]
        if not balls:
            game_over = True

        # 벽돌, 바, 공 그리기
        for b in bricks:
            color = (255, 0, 0)
            if b['type'] == "green":
                color = (0, 255, 0)
            elif b['type'] == "red":
                color = (0, 0, 255)
            cv2.rectangle(game_frame, (b['x'], b['y']), (b['x'] + b['w'], b['y'] + b['h']), color, -1)

        cv2.rectangle(game_frame, (bar_x, bar_y), (bar_x + bar_width, bar_y + bar_height), (0, 255, 255), -1)

        for ball in balls:
            cv2.circle(game_frame, (int(ball['x']), int(ball['y'])), 10, (255, 255, 255), -1)

        # 점수/레벨 출력
        cv2.putText(game_frame, f"Score: {score}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
        cv2.putText(game_frame, f"Level: {level}", (10, 65), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 2)

    # 카메라 화면 삽입
    cam_small = cv2.resize(frame, (200, 150))
    game_frame[0:150, 0:200] = cam_small

    cv2.imshow("Game", game_frame)

    key = cv2.waitKey(10) & 0xFF
    if key == 27:  # ESC
        break
    if key == ord(' '):  # SPACE
        if not game_started:
            game_started = True
            game_over = False
            reset_game()
    if key == ord('r'):  # Restart
        if game_over:
            reset_game()
            game_over = False
            game_started = True

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import pyautogui
import time
import math

# — 설치 필요 —
# pip install opencv-python mediapipe pyautogui

# MediaPipe Hands 초기화
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands(
    max_num_hands=1,
    min_detection_confidence=0.7,
    min_tracking_confidence=0.7
)

# 디바운스 및 매핑 설정
CLICK_THRESHOLD = 0.04      # 핀치 임계값
COOLDOWN = 0.3              # 클릭 디바운스 (초)
last_click = 0
screen_w, screen_h = pyautogui.size()
SMOOTHING = 5               # 마우스 움직임 부드럽게: 이전 위치와 새 위치 평균화 비율

prev_x, prev_y = 0, 0

# 웹캠 열기
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 1) 영상 전처리
    img = cv2.flip(frame, 1)
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    res = hands.process(img_rgb)

    if res.multi_hand_landmarks:
        lm = res.multi_hand_landmarks[0].landmark

        # 2) 화면 좌표로 매핑할 검지 끝 (index finger tip: 8)
        x_norm, y_norm = lm[8].x, lm[8].y
        # MediaPipe 좌표계: (0,0) 왼쪽 위, (1,1) 오른쪽 아래
        x_screen = int(screen_w  * x_norm)
        y_screen = int(screen_h * y_norm)

        # 3) 부드러운 이동
        cur_x = prev_x + (x_screen - prev_x) / SMOOTHING
        cur_y = prev_y + (y_screen - prev_y) / SMOOTHING
        pyautogui.moveTo(cur_x, cur_y)
        prev_x, prev_y = cur_x, cur_y

        # 4) 핀치 감지 (엄지(4) ↔ 검지(8))
        x_thumb, y_thumb = lm[4].x, lm[4].y
        pinch_dist = math.hypot(x_thumb - x_norm, y_thumb - y_norm)
        now = time.time()
        if pinch_dist < CLICK_THRESHOLD and now - last_click > COOLDOWN:
            pyautogui.click()
            last_click = now

        # 5) 디버깅용 화면 표시
        mp_drawing.draw_landmarks(img, res.multi_hand_landmarks[0], mp_hands.HAND_CONNECTIONS)
        cv2.circle(img,
                   (int(lm[8].x * img.shape[1]), int(lm[8].y * img.shape[0])),
                   10, (0,255,0), cv2.FILLED)
        cv2.putText(img, f"PinchDist:{pinch_dist:.3f}", (10,30),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)

    cv2.imshow("Hand Mouse Control", img)
    if cv2.waitKey(1) & 0xFF == 27:  # ESC
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2

import mediapipe as mp

import numpy as np

mp_hands = mp.solutions.hands

mp_face_mesh = mp.solutions.face_mesh

hands = mp_hands.Hands()

face_mesh = mp_face_mesh.FaceMesh()

cap = cv2.VideoCapture(0)

def is_only_thumb_index_pinky_open(hand_landmarks):

lm = hand_landmarks.landmark

def y_open(tip, pip):

return lm[tip].y < lm[pip].y

def y_closed(tip, pip):

return lm[tip].y > lm[pip].y

thumb_open = lm[mp_hands.HandLandmark.THUMB_TIP].x < lm[mp_hands.HandLandmark.THUMB_IP].x

index_open = y_open(mp_hands.HandLandmark.INDEX_FINGER_TIP, mp_hands.HandLandmark.INDEX_FINGER_PIP)

pinky_open = y_open(mp_hands.HandLandmark.PINKY_TIP, mp_hands.HandLandmark.PINKY_PIP)

middle_closed = y_closed(mp_hands.HandLandmark.MIDDLE_FINGER_TIP, mp_hands.HandLandmark.MIDDLE_FINGER_PIP)

ring_closed = y_closed(mp_hands.HandLandmark.RING_FINGER_TIP, mp_hands.HandLandmark.RING_FINGER_PIP)

return thumb_open and index_open and pinky_open and middle_closed and ring_closed

def get_eye_coordinates(face_landmarks, image_width, image_height):

left_eye_idx = [33, 133]

right_eye_idx = [362, 263]

left_eye = []

right_eye = []

for idx in left_eye_idx:

x = int(face_landmarks[idx].x * image_width)

y = int(face_landmarks[idx].y * image_height)

left_eye.append((x, y))

for idx in right_eye_idx:

x = int(face_landmarks[idx].x * image_width)

y = int(face_landmarks[idx].y * image_height)

right_eye.append((x, y))

return left_eye, right_eye

def draw_sunglasses(frame, left_eye, right_eye):

left_center = np.mean(left_eye, axis=0).astype(int)

right_center = np.mean(right_eye, axis=0).astype(int)

eye_distance = int(np.linalg.norm(left_center - right_center))

glass_width = eye_distance * 2

glass_height = eye_distance // 2

mid_x = (left_center[0] + right_center[0]) // 2

mid_y = (left_center[1] + right_center[1]) // 2

left_top = (mid_x - glass_width // 2, mid_y - glass_height // 2)

right_top = (mid_x, mid_y - glass_height // 2)

# 렌즈

cv2.rectangle(frame, left_top, (left_top[0] + glass_width // 2, left_top[1] + glass_height), (0, 0, 0), -1)

cv2.rectangle(frame, right_top, (right_top[0] + glass_width // 2, right_top[1] + glass_height), (0, 0, 0), -1)

# 브릿지

cv2.line(frame, (left_top[0] + glass_width // 2, mid_y), (right_top[0], mid_y), (0, 0, 0), 5)

while cap.isOpened():

ret, frame = cap.read()

if not ret:

break

frame = cv2.flip(frame, 1)

# MediaPipe 처리

frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

results_hands = hands.process(frame_rgb)

results_face = face_mesh.process(frame_rgb)

if results_hands.multi_hand_landmarks:

for hand_landmarks in results_hands.multi_hand_landmarks:

if is_only_thumb_index_pinky_open(hand_landmarks):

if results_face.multi_face_landmarks:

for face_landmarks in results_face.multi_face_landmarks:

left_eye, right_eye = get_eye_coordinates(face_landmarks.landmark, frame.shape[1], frame.shape[0])

draw_sunglasses(frame, left_eye, right_eye)

cv2.imshow('Frame', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):

break

cap.release()

cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.body
import cv2

import mediapipe as mp

import math

from pynput.mouse import Controller, Button

# Mediapipe 초기화

mp_hands = mp.solutions.hands

mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands()

# 마우스 컨트롤 초기화

mouse = Controller()

paper_holding = False  # Paper 유지 상태 변수

scissors_clicked = False

# 웹캠 열기

cap = cv2.VideoCapture(0)

def calculate_angle(a, b, c):

"""세 점을 이용해 각도를 계산하는 함수"""

ab = [a[0] - b[0], a[1] - b[1]]

bc = [c[0] - b[0], c[1] - b[1]]

dot = ab[0] bc[0] + ab[1] bc[1]

det = ab[0] bc[1] - ab[1] bc[0]

angle = math.atan2(det, dot) * 180.0 / math.pi

return abs(angle)

def detect_finger_open(landmarks, width, height):

"""손가락을 핀 상태로 인식하는 함수"""

finger_tips = [4, 8, 12, 16, 20]

finger_ips = [3, 7, 11, 15, 19]

finger_names = ["Thumb", "Index", "Middle", "Ring", "Pinky"]

open_fingers = []

open_threshold = 160  # 각도가 160도 이상이면 핀 상태로 인식

wrist = (landmarks[0].x width, landmarks[0].y height)

for tip_idx, ip_idx, name in zip(finger_tips, finger_ips, finger_names):

tip = (landmarks[tip_idx].x width, landmarks[tip_idx].y height)

ip = (landmarks[ip_idx].x width, landmarks[ip_idx].y height)

angle = calculate_angle(tip, ip, wrist)

if angle > open_threshold:

open_fingers.append(name)

return open_fingers

def recognize_gesture(open_fingers):

"""가위, 바위, 보 제스처를 인식하는 함수"""

if len(open_fingers) == 5:

return "Paper"

elif len(open_fingers) == 2 and "Index" in open_fingers and "Middle" in open_fingers:

return "Scissors"

elif len(open_fingers) == 0:

return "Rock"

return "just hand"

def perform_action(gesture):

"""제스처에 따른 마우스 동작 수행"""

global paper_holding, scissors_clicked

if gesture == "Paper":

if not paper_holding:

print("Paper 감지 → 더블클릭 + 눌림 유지")

mouse.click(Button.left, 2)

mouse.press(Button.left)

paper_holding = True

scissors_clicked = False

else:

if paper_holding:

print("Paper 해제 → 버튼 놓기")

mouse.release(Button.left)

paper_holding = False

if gesture == "Scissors":

if not scissors_clicked:

mouse.click(Button.left)

scissors_clicked = True

else:

scissors_clicked = False

while True:

success, frame = cap.read()

if not success:

break

frame = cv2.flip(frame, 1)

image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

result = hands.process(image_rgb)

if result.multi_hand_landmarks:

for hand_landmarks, handedness in zip(result.multi_hand_landmarks, result.multi_handedness):

h, w, _ = frame.shape

hand_label = handedness.classification[0].label

open_fingers = detect_finger_open(hand_landmarks.landmark, w, h)

gesture = recognize_gesture(open_fingers)

perform_action(gesture)

# 디버깅 텍스트만 표시 (랜드마크 표시 제거됨)

color = (0, 255, 0) if hand_label == "Left" else (0, 0, 255)

position = (50, 50) if hand_label == "Left" else (50, 100)

cv2.putText(frame, f"{hand_label} Hand: {gesture}", position,

cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)

cv2.imshow("Rock Paper Scissors Gesture Recognition", frame)

if cv2.waitKey(1) & 0xFF == 27:  # ESC 키로 종료

break

cap.release()

cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp

# MediaPipe 초기화
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
    static_image_mode=False,
    max_num_hands=1,  # 한 손만 인식
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
)
mp_drawing = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)

def count_fingers(hand_landmarks, handedness):
    lm = hand_landmarks.landmark
    count = 0

    # 엄지
    if handedness == 'Right':
        if lm[4].x < lm[3].x:
            count += 1
    else:
        if lm[4].x > lm[3].x:
            count += 1

    # 나머지 손가락
    finger_tips = [8, 12, 16, 20]
    finger_pips = [6, 10, 14, 18]

    for tip, pip in zip(finger_tips, finger_pips):
        if lm[tip].y < lm[pip].y:
            count += 1

    return count

def get_gesture(finger_count):
    if finger_count == 2:
        return "Scissors"
    elif finger_count >= 4:
        return "Paper"
    else:
        return "Rock"

while cap.isOpened():
    success, image = cap.read()
    if not success:
        print("카메라를 찾을 수 없습니다.")
        break

    # 좌우반전
    image = cv2.flip(image, 1)

    # RGB 변환 및 손 인식
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image_rgb.flags.writeable = False
    results = hands.process(image_rgb)
    image_rgb.flags.writeable = True

    # 손 인식된 경우
    if results.multi_hand_landmarks and results.multi_handedness:
        for hand_landmarks, handedness_info in zip(results.multi_hand_landmarks, results.multi_handedness):
            label = handedness_info.classification[0].label  # 'Left' or 'Right'
            fingers = count_fingers(hand_landmarks, label)
            gesture = get_gesture(fingers)

            # 손목 위치 가져오기
            h, w, _ = image.shape
            wrist = hand_landmarks.landmark[0]
            cx, cy = int(wrist.x * w), int(wrist.y * h)
            text_x = max(cx - 50, 10)
            text_y = max(cy - 30, 30)

            # 결과 표시
            mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
            cv2.putText(image, f"{gesture} ({fingers})", (text_x, text_y),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_AA)

    cv2.imshow('Rock Scissors Paper Detection', image)

    if cv2.waitKey(5) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.headline
코드와 실행화면 캡쳐올려주세요

# data[].attributes.subject
코드와 실행화면 캡쳐올려주세요

# data[].attributes.body
import cv2
import mediapipe as mp
import random
import math
import time

mp_hands = mp.solutions.hands
hands = mp_hands.Hands()

cap = cv2.VideoCapture(0)

finger_radius = 15
obstacle_radius = 12

directions = [
    (1, 0), (-1, 0), (0, 1), (0, -1),
    (1, 1), (1, -1), (-1, 1), (-1, -1)
]

font = cv2.FONT_HERSHEY_SIMPLEX

frame_count = 0
spawn_interval = 15
start_time = time.time()

game_over = False
survived_time = 0

obstacles = []

def normalize_vector(x, y):
    length = math.hypot(x, y)
    if length == 0:
        return 0, 0
    return x / length, y / length

def reset_game():
    global obstacles, frame_count, start_time, game_over, survived_time
    obstacles = []
    frame_count = 0
    start_time = time.time()
    game_over = False
    survived_time = 0

while True:
    success, frame = cap.read()
    if not success:
        break

    frame = cv2.flip(frame, 1)
    h, w, _ = frame.shape

    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    current_time = time.time()
    elapsed_time = current_time - start_time

    if not game_over:
        result = hands.process(image_rgb)
    else:
        result = None

    cx8, cy8 = None, None

    if result and result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            lm8 = hand_landmarks.landmark[8]
            cx8, cy8 = int(lm8.x * w), int(lm8.y * h)
            cv2.circle(frame, (cx8, cy8), finger_radius, (0, 255, 0), 3)

    max_spawn_per_frame = 1 + int(elapsed_time * 0.1)

    min_speed = 10
    max_speed = 16

    if not game_over:
        # 10초마다 일렬 패턴 출현, 간격 84픽셀
        if int(elapsed_time) % 10 == 0 and frame_count % spawn_interval == 0:
            pattern_count = 5
            spacing = int(obstacle_radius * 7)  # 84px
            base_x = -obstacle_radius * 2
            base_y = h // 2 - (pattern_count // 2) * spacing
            speed_x, speed_y = 12, 0

            for i in range(pattern_count):
                y_pos = base_y + i * spacing
                obstacles.append([base_x, y_pos, speed_x, speed_y])

        for _ in range(max_spawn_per_frame):
            if frame_count % spawn_interval == 0:
                dir_x, dir_y = random.choice(directions)
                speed = random.uniform(min_speed, max_speed)
                norm_x, norm_y = normalize_vector(dir_x, dir_y)
                speed_x = norm_x * speed
                speed_y = norm_y * speed

                if dir_x > 0:
                    x = -obstacle_radius * 2
                elif dir_x < 0:
                    x = w + obstacle_radius * 2
                else:
                    x = random.randint(0, w)

                if dir_y > 0:
                    y = -obstacle_radius * 2
                elif dir_y < 0:
                    y = h + obstacle_radius * 2
                else:
                    y = random.randint(0, h)

                obstacles.append([x, y, speed_x, speed_y])

        frame_count += 1

        obstacles_to_remove = []
        for i, (x, y, speed_x, speed_y) in enumerate(obstacles):
            x += speed_x
            y += speed_y

            if x < -obstacle_radius*2 or x > w + obstacle_radius*2 or y < -obstacle_radius*2 or y > h + obstacle_radius*2:
                obstacles_to_remove.append(i)
            else:
                obstacles[i] = [x, y, speed_x, speed_y]
                cv2.circle(frame, (int(x), int(y)), obstacle_radius, (0, 0, 255), -1)

        for idx in reversed(obstacles_to_remove):
            obstacles.pop(idx)

        if cx8 is not None and cy8 is not None:
            for x, y, _, _ in obstacles:
                dist = math.hypot(cx8 - x, cy8 - y)
                if dist < finger_radius + obstacle_radius:
                    game_over = True
                    survived_time = elapsed_time
                    break

    if game_over:
        frame[:] = (0, 0, 0)
        cv2.putText(frame, "LOSE", (w // 4, h // 3),
                    cv2.FONT_HERSHEY_SIMPLEX, 5, (0, 0, 255), 10)
        cv2.putText(frame, f"TIME SURVIVED: {survived_time:.2f} s", (50, h // 2),
                    cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 4)
        cv2.putText(frame, "Press SPACE to Restart", (50, int(h * 0.7)),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
    else:
        cv2.putText(frame, f"TIME: {elapsed_time:.2f} s", (10, 40),
                    font, 1, (255, 255, 255), 2)

    cv2.imshow("장애물 게임", frame)

    key = cv2.waitKey(1) & 0xFF
    if key == 27:  # ESC 누르면 종료
        break
    elif key == 32 and game_over:  # 스페이스바 누르면 다시 시작
        reset_game()

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2

import mediapipe as mp

import time

import random

mp_hands = mp.solutions.hands

mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands(max_num_hands=1, min_detection_confidence=0.7)

def is_finger_open(lm, tip, pip):

return lm[tip].y < lm[pip].y

def is_back_of_hand(lm):

# 손바닥/손등 판별: 엄지와 검지 중간 마디 z 좌표 평균

thumb_mcp_z = lm[2].z

index_mcp_z = lm[5].z

avg_z = (thumb_mcp_z + index_mcp_z) / 2

return avg_z > 0 # 양수면 손등, 음수면 손바닥

def is_thumb_open(lm, handedness):

back_of_hand = is_back_of_hand(lm)

if back_of_hand:

# 손등 방향일 때 엄지 인식 반전

if handedness == "Right":

return lm[4].x > lm[3].x

else:

return lm[4].x < lm[3].x

else:

# 손바닥 방향일 때 기존 로직

if handedness == "Right":

return lm[4].x < lm[3].x

else:

return lm[4].x > lm[3].x

def detect_gesture(hand_landmarks, handedness):

lm = hand_landmarks.landmark

thumb = is_thumb_open(lm, handedness)

index = is_finger_open(lm, 8, 6)

middle = is_finger_open(lm, 12, 10)

ring = is_finger_open(lm, 16, 14)

pinky = is_finger_open(lm, 20, 18)

# 바위: 모두 접음

if not thumb and not index and not middle and not ring and not pinky:

return "Rock"

# 보: 모두 핌

elif thumb and index and middle and ring and pinky:

return "Paper"

# 가위: 검지+중지 또는 엄지+검지 핌 (가위손)

elif (index and middle and not ring and not pinky) or (thumb and index and not middle and not ring and not pinky):

return "Scissors"

else:

return "Unknown"

def decide_winner(player, computer):

if player == computer:

return "Draw"

elif (player "Rock" and computer "Scissors") or \

(player "Scissors" and computer "Paper") or \

(player "Paper" and computer "Rock"):

return "You Win!"

else:

return "You Lose!"

cap = cv2.VideoCapture(0)

game_state = "ready"

count_start_time = 0

player_choice = ""

computer_choice = ""

result_text = ""

while True:

ret, frame = cap.read()

if not ret:

break

frame = cv2.flip(frame, 1) # 좌우 반전

image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

result = hands.process(image_rgb)

h, w, _ = frame.shape

if game_state == "ready":

cv2.putText(frame, "Press 'Space' to Start", (50, 50),

cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 200, 200), 2)

elif game_state == "countdown":

elapsed = time.time() - count_start_time

remaining = max(0, 3 - int(elapsed))

if remaining > 0:

cv2.putText(frame, f"{remaining}", (w // 2 - 20, h // 2),

cv2.FONT_HERSHEY_DUPLEX, 3, (255, 0, 0), 5)

else:

game_state = "result"

if result.multi_hand_landmarks and result.multi_handedness:

hand = result.multi_hand_landmarks[0]

handedness_label = result.multi_handedness[0].classification[0].label

player_choice = detect_gesture(hand, handedness_label)

else:

player_choice = "Unknown"

computer_choice = random.choice(["Rock", "Paper", "Scissors"])

result_text = decide_winner(player_choice, computer_choice)

result_time = time.time()

elif game_state == "result":

cv2.putText(frame, f"You: {player_choice}", (50, 80),

cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 255), 2)

cv2.putText(frame, f"Computer: {computer_choice}", (50, 130),

cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 255), 2)

cv2.putText(frame, result_text, (50, 200),

cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 128, 255), 4)

if time.time() - result_time > 3:

game_state = "ready"

if result.multi_hand_landmarks:

for hand_landmarks in result.multi_hand_landmarks:

mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

cv2.imshow("Rock Paper Scissors", frame)

key = cv2.waitKey(1) & 0xFF

if key == 27: # ESC

break

elif key 32 and game_state "ready": # Space

count_start_time = time.time()

game_state = "countdown"

player_choice = ""

computer_choice = ""

result_text = ""

cap.release()

cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.headline
코드와 실행화면 캡쳐올려주세요

# data[].attributes.subject
코드와 실행화면 캡쳐올려주세요

# data[].attributes.body
import cv2
import mediapipe as mp
import random
import time

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=1, min_detection_confidence=0.7)
mp_drawing = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)

# 결과 출력 타이머
last_time = 0
delay = 2  # 초
result = ""
computer_choice = ""

def get_finger_status(hand_landmarks):
    finger_tips = [8, 12, 16, 20]  # 검지, 중지, 약지, 새끼
    finger_mcp = [5, 9, 13, 17]
    status = []

    for tip, mcp in zip(finger_tips, finger_mcp):
        status.append(hand_landmarks.landmark[tip].y < hand_landmarks.landmark[mcp].y)

    # 엄지는 x축 기준
    status.insert(0, hand_landmarks.landmark[4].x > hand_landmarks.landmark[3].x)

    return status

def recognize_gesture(finger_status):
    if all(not finger for finger in finger_status):  # 모두 접힘
        return "Rock"
    elif finger_status[1] and finger_status[2] and not finger_status[3] and not finger_status[4]:  # 검지, 중지만 펴짐
        return "Scissors"
    elif all(finger for finger in finger_status):  # 모두 펴짐
        return "Paper"
    else:
        return "Unknown"

def get_winner(user, computer):
    if user == computer:
        return "Draw"
    elif (user == "Rock" and computer == "Scissors") or \
         (user == "Scissors" and computer == "Paper") or \
         (user == "Paper" and computer == "Rock"):
        return "You Win!"
    else:
        return "You Lose!"

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.flip(frame, 1)
    h, w, _ = frame.shape
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result_hands = hands.process(rgb)

    if result_hands.multi_hand_landmarks:
        hand_landmarks = result_hands.multi_hand_landmarks[0]
        finger_status = get_finger_status(hand_landmarks)
        user_gesture = recognize_gesture(finger_status)

        current_time = time.time()
        if current_time - last_time > delay and user_gesture in ["Rock", "Paper", "Scissors"]:
            computer_choice = random.choice(["Rock", "Paper", "Scissors"])
            result = get_winner(user_gesture, computer_choice)
            last_time = current_time

        mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

        cv2.putText(frame, f'Your move: {user_gesture}', (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2)
        cv2.putText(frame, f'Computer: {computer_choice}', (10, 70),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2)
        cv2.putText(frame, f'Result: {result}', (10, 110),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 200, 0), 2)
    else:
        cv2.putText(frame, 'Show your hand!', (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)

    cv2.imshow('Rock Paper Scissors Game', frame)
    if cv2.waitKey(1) & 0xFF == 27:  # ESC
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.headline
미디어 파이프 비전 실습 소감 작성 설문입니다. (최종)

# data[].attributes.subject
미디어 파이프 비전 실습 소감 작성 설문입니다. (최종)

# data[].attributes.attachment_link.title
비전 기술 활용 프로젝트 소감작성(미디어 파이프)

# data[].attributes.headline
코드와 실행화면 캡쳐올려주세요

# data[].attributes.subject
코드와 실행화면 캡쳐올려주세요

# data[].attributes.body
import cv2
import mediapipe as mp

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1)
mp_draw = mp.solutions.drawing_utils

tip_ids = [4, 8, 12, 16, 20]  # 손가락 끝 인덱스

colors = {
    1: (0, 0, 255),    # 빨강
    2: (0, 255, 0),    # 초록
    3: (255, 0, 0),    # 파랑
    4: (255, 0, 255),  # 보라
}
eraser_color = (0, 0, 0)
brush_thickness = 5
eraser_thickness = 50

cap = cv2.VideoCapture(0)
canvas = None
prev_x, prev_y = 0, 0

def count_fingers(hand_landmarks):
    fingers = []

    # 엄지: x좌표 비교
    if hand_landmarks.landmark[tip_ids[0]].x < hand_landmarks.landmark[tip_ids[0] - 1].x:
        fingers.append(1)
    else:
        fingers.append(0)

    # 나머지: y좌표 비교
    for i in range(1, 5):
        if hand_landmarks.landmark[tip_ids[i]].y < hand_landmarks.landmark[tip_ids[i] - 2].y:
            fingers.append(1)
        else:
            fingers.append(0)

    return sum(fingers)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.flip(frame, 1)
    h, w, _ = frame.shape

    if canvas is None:
        canvas = frame.copy() * 0

    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = hands.process(rgb)

    draw = False
    color = colors.get(1)

    if result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

            fingers_up = count_fingers(hand_landmarks)

            # 손가락 5개 → 지우개 모드
            if fingers_up == 5:
                color = eraser_color
                thickness = eraser_thickness
            else:
                color = colors.get(fingers_up, (0, 0, 255))
                thickness = brush_thickness

            # ✊ 주먹일 때는 그리기 금지
            if fingers_up == 0:
                prev_x, prev_y = 0, 0  # 그리기 시작점도 초기화
                continue  # 아래 코드 실행 안 함

            # 검지 위치
            index_finger = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
            x, y = int(index_finger.x * w), int(index_finger.y * h)

            if 0 <= x < w and 0 <= y < h:
                draw = True
                if prev_x == 0 and prev_y == 0:
                    prev_x, prev_y = x, y

                if draw:
                    cv2.line(canvas, (prev_x, prev_y), (x, y), color, thickness)
                    prev_x, prev_y = x, y
            else:
                prev_x, prev_y = 0, 0
    else:
        prev_x, prev_y = 0, 0

    combined = cv2.addWeighted(frame, 0.7, canvas, 0.3, 0)
    cv2.imshow("Air Drawing with Fist Block", combined)

    key = cv2.waitKey(1) & 0xFF
    if key == 27:
        break
    elif key == ord('c'):
        canvas = frame.copy() * 0

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
이 기능은 재난 상황이나 긴급한 도움이 필요한 사람들에게 매우 유용합니다. 인터넷 방송이나 화상 회의가 활발한 지금, 화면을 통한 비언어적 신호로 위급 상황을 신속하게 알릴 수 있어 더욱 중요하다고 생각하여 만들어봤습니다.

# data[].attributes.attachment_link.title
손 제스쳐 인식 제작(학생용)의 사본

# data[].attributes.headline
31003 김준호 울트라 볼(유도 미사일 피하기 얼굴 상호작용)

# data[].attributes.subject
31003 김준호 울트라 볼(유도 미사일 피하기 얼굴 상호작용)

# data[].attributes.body
import cv2
import mediapipe as mp
import time
import random
import math
import numpy as np

# MediaPipe 초기화
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(refine_landmarks=True)
cap = cv2.VideoCapture(0)

# 캐릭터 설정
player_radius = 20
player_color = (255, 255, 255)
player_pos = [320, 240]

# 스킬 관련 설정
invincible_duration = 3.0   # 무적 지속 시간 (초)
skill_cooldown = 10.0       # 쿨타임 (초)
is_invincible = False
invincible_start_time = 0
last_skill_time = -skill_cooldown  # 초기엔 바로 쓸 수 있음

# 미사일 클래스
class Missile:
    def __init__(self, x, y, vx, vy, color, homing=False):
        self.x = x
        self.y = y
        self.color = color
        self.homing = homing
        base_speed = 5
        self.speed = base_speed * (0.5 if homing else 1.0)
        self.vx = vx
        self.vy = vy

    def update(self, target_x=None, target_y=None):
        if self.homing and target_x is not None:
            dx = target_x - self.x
            dy = target_y - self.y
            dist = math.sqrt(dx ** 2 + dy ** 2) + 1e-6
            self.vx = self.speed * dx / dist
            self.vy = self.speed * dy / dist
        self.x += self.vx
        self.y += self.vy

    def draw(self, frame):
        cv2.circle(frame, (int(self.x), int(self.y)), 8, self.color, -1)

# 미사일 생성 함수
def add_missile(w, h, homing=False):
    edge = random.choice(['top', 'bottom', 'left', 'right'])
    speed = 5
    color = (0, 0, 255) if not homing else (0, 255, 255)
    if edge == 'top':
        x, y = random.randint(0, w), 0
        vx, vy = 0, speed
    elif edge == 'bottom':
        x, y = random.randint(0, w), h
        vx, vy = 0, -speed
    elif edge == 'left':
        x, y = 0, random.randint(0, h)
        vx, vy = speed, 0
    else:
        x, y = w, random.randint(0, h)
        vx, vy = -speed, 0
    missiles.append(Missile(x, y, vx, vy, color, homing))

# 게임 상태
STATE_START = 0
STATE_PLAYING = 1
STATE_GAME_OVER = 2
state = STATE_START

missiles = []
score = 0
start_time = 0
last_missile_time = 0

def reset_game():
    global missiles, score, start_time, last_missile_time, is_invincible, last_skill_time
    missiles.clear()
    score = 0
    start_time = time.time()
    last_missile_time = 0
    is_invincible = False
    last_skill_time = -skill_cooldown

while True:
    ret, frame = cap.read()
    if not ret:
        break

    h, w, _ = frame.shape

    # 검은 배경 생성
    black_bg = np.zeros((h, w, 3), dtype=np.uint8)

    # Mediapipe 얼굴 추적
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = face_mesh.process(rgb)

    current_time = time.time()

    if state == STATE_START:
        cv2.putText(black_bg, "Face Missile Dodge Game", (80, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 3)
        cv2.putText(black_bg, "Press SPACE to Start", (130, 280), cv2.FONT_HERSHEY_SIMPLEX, 1, (200, 200, 200), 2)
        key = cv2.waitKey(1)
        if key == 32:
            state = STATE_PLAYING
            reset_game()

    elif state == STATE_PLAYING:
        # 얼굴 위치 업데이트
        if results.multi_face_landmarks:
            landmarks = results.multi_face_landmarks[0].landmark
            nose = landmarks[1]
            top_lip = landmarks[13]   # 윗입술 중앙
            bottom_lip = landmarks[14] # 아랫입술 중앙

            x, y = int(nose.x * w), int(nose.y * h)
            player_pos = [x, y]

            # 입 벌림 감지
            mouth_open = abs(top_lip.y - bottom_lip.y) > 0.05

            if mouth_open and not is_invincible and (current_time - last_skill_time) >= skill_cooldown:
                is_invincible = True
                invincible_start_time = current_time
                last_skill_time = current_time

        # 무적 상태 관리
        if is_invincible and (current_time - invincible_start_time > invincible_duration):
            is_invincible = False

        # 미사일 생성
        if current_time - last_missile_time > 1:
            add_missile(w, h, homing=random.random() < 0.3)
            last_missile_time = current_time

        # 미사일 처리
        for m in missiles[:]:
            m.update(player_pos[0], player_pos[1])
            m.draw(black_bg)

            dist = math.hypot(m.x - player_pos[0], m.y - player_pos[1])
            if dist < player_radius + 8 and not is_invincible:
                state = STATE_GAME_OVER
                break

        # 캐릭터 그리기
        if is_invincible:
            # 오라 그리기 (무적 상태)
            cv2.circle(black_bg, tuple(player_pos), player_radius + 15, (255, 255, 0), 3)
        cv2.circle(black_bg, tuple(player_pos), player_radius, player_color, -1)

        # 스코어 및 쿨타임 표시
        score = int(current_time - start_time)
        cv2.putText(black_bg, f"Score: {score}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

        time_since_last = current_time - last_skill_time
        cooldown_remaining = max(0, int(skill_cooldown - time_since_last))
        cv2.putText(black_bg, f"Skill Cooldown: {cooldown_remaining}s", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2)

    elif state == STATE_GAME_OVER:
        cv2.putText(black_bg, "GAME OVER", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 4)
        cv2.putText(black_bg, f"Score: {score}", (220, 260), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 255, 255), 2)
        cv2.putText(black_bg, "Press R to Restart or ESC to Exit", (80, 320), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (180, 180, 180), 2)
        key = cv2.waitKey(1)
        if key == ord('r') or key == ord('R'):
            state = STATE_START
        elif key == 27:
            break

    cv2.imshow('Game', black_bg)

    if state != STATE_GAME_OVER:
        if cv2.waitKey(1) & 0xFF == 27:
            break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import random
import time

# 초기 설정
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1)
mp_draw = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)
w, h = 640, 480
cap.set(3, w)
cap.set(4, h)

# 사과 객체 정의
class Apple:
    def __init__(self):
        self.x = random.randint(50, w - 50)
        self.y = 0
        self.speed = random.randint(3, 6)
        self.size = 30

    def fall(self):
        self.y += self.speed

    def draw(self, img):
        cv2.circle(img, (self.x, self.y), self.size, (0, 0, 255), -1)

    def is_hit(self, bullet_x, bullet_y):
        return abs(self.x - bullet_x) < self.size and abs(self.y - bullet_y) < self.size

# 총알 객체 정의
class Bullet:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.speed = 10

    def move(self):
        self.y -= self.speed

    def draw(self, img):
        cv2.circle(img, (self.x, self.y), 5, (255, 255, 0), -1)

apples = []
bullets = []
score = 0
last_apple_time = time.time()
cooldown = 0.4
last_shot_time = 0

while True:
    success, img = cap.read()
    if not success:
        break
    img = cv2.flip(img, 1)
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    results = hands.process(img_rgb)
    h, w, _ = img.shape
    index_tip = thumb_tip = None
    shoot_ready = False
    gun_x = gun_y = -100

    # 손 인식 및 사격 조건 체크
    if results.multi_hand_landmarks:
        for handLms in results.multi_hand_landmarks:
            mp_draw.draw_landmarks(img, handLms, mp_hands.HAND_CONNECTIONS)

            # 검지끝 (8), 엄지끝 (4)
            index_tip = handLms.landmark[8]
            thumb_tip = handLms.landmark[4]
            gun_x = int(index_tip.x * w)
            gun_y = int(index_tip.y * h)

            # 사격 조건: 검지가 엄지보다 위
            if index_tip.y < thumb_tip.y and time.time() - last_shot_time > cooldown:
                bullets.append(Bullet(gun_x, gun_y))
                last_shot_time = time.time()

            # 총 그리기
            cv2.circle(img, (gun_x, gun_y), 15, (255, 0, 0), -1)
            cv2.putText(img, "FIRE" if index_tip.y < thumb_tip.y else "AIM",
                        (gun_x - 20, gun_y - 25), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                        (0, 255, 0) if index_tip.y < thumb_tip.y else (0, 0, 255), 2)

    # 사과 생성
    if time.time() - last_apple_time > 1.0:
        apples.append(Apple())
        last_apple_time = time.time()

    # 사과 그리기 및 충돌 확인
    for apple in apples[:]:
        apple.fall()
        apple.draw(img)
        for bullet in bullets[:]:
            if apple.is_hit(bullet.x, bullet.y):
                apples.remove(apple)
                bullets.remove(bullet)
                score += 1
                break
        if apple.y > h:
            apples.remove(apple)

    # 총알 이동
    for bullet in bullets[:]:
        bullet.move()
        bullet.draw(img)
        if bullet.y < 0:
            bullets.remove(bullet)

    # 점수 표시
    cv2.putText(img, f"Score: {score}", (10, 40),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

    cv2.imshow("Apple Shooter", img)

    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
기능 : 붉은색 및 검은색 기준을 통해 상처감지

코드 :

import cv2
import numpy as np

# 웹캠 열기
cap = cv2.VideoCapture(0)

# 해상도 설정 (1920x1080)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)

cv2.namedWindow("Wound Detection", cv2.WINDOW_NORMAL)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # HSV 변환
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # 붉은색 범위 조정 (더 진한 색만 탐지)
    lower_red1 = np.array([0, 100, 100])
    upper_red1 = np.array([5, 255, 255])
    lower_red2 = np.array([170, 100, 100])
    upper_red2 = np.array([180, 255, 255])

    mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
    mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
    mask = mask1 + mask2

    # 노이즈 제거
    kernel = np.ones((5, 5), np.uint8)
    mask_clean = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    mask_clean = cv2.morphologyEx(mask_clean, cv2.MORPH_CLOSE, kernel)

    # 윤곽선 검출
    contours, _ = cv2.findContours(mask_clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 800:  # 작은 노이즈 제거
            x, y, w, h = cv2.boundingRect(cnt)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
            cv2.putText(frame, "Possible Wound", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

    # 화면 출력
    cv2.imshow("Wound Detection", frame)
    cv2.imshow("Red Area Mask", mask_clean)

    # ESC 키로 종료
    if cv2.waitKey(1) & 0xFF == 27:
        break

# 종료 처리
cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import pygame
import sys
import math
import numpy as np

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.7)
mp_draw = mp.solutions.drawing_utils

pygame.init()
WIDTH, HEIGHT = 640, 480
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

board_width, board_height = 300, 20
board_center = np.array([WIDTH//2, HEIGHT//2 + 100], dtype=float)
board_angle = 0
max_angle = 20

ball_radius = 15
ball_pos = np.array([WIDTH/2, HEIGHT/2], dtype=float)
ball_vel = np.array([0.0, 0.0], dtype=float)
gravity = 0.8

def draw_rotated_rect(surface, color, center, width, height, angle):
    rect = pygame.Surface((width, height), pygame.SRCALPHA)
    rect.fill(color)
    rotated = pygame.transform.rotate(rect, angle)
    rect_pos = rotated.get_rect(center=center)
    surface.blit(rotated, rect_pos)

def is_hand_closed(hand_landmarks):
    thumb_tip = hand_landmarks.landmark[4]
    index_tip = hand_landmarks.landmark[8]
    dist = math.sqrt((thumb_tip.x - index_tip.x)**2 + (thumb_tip.y - index_tip.y)**2)
    return dist < 0.05

def get_hand_label(hand_landmark, handedness):
    return handedness.classification[0].label

def point_on_board(point, center, width, height, angle_deg):
    angle_rad = math.radians(-angle_deg)
    s = math.sin(angle_rad)
    c = math.cos(angle_rad)
    p = point - center
    x_new = p[0]*c - p[1]*s
    y_new = p[0]*s + p[1]*c
    return (-width/2 <= x_new <= width/2) and (-height/2 <= y_new <= height/2)

cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("카메라가 열리지 않습니다.")
    sys.exit()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            cap.release()
            pygame.quit()
            sys.exit()

    ret, frame = cap.read()
    if not ret:
        print("프레임을 가져오지 못했습니다.")
        break

    frame = cv2.flip(frame, 1)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = hands.process(rgb_frame)

    left_closed = False
    right_closed = False

    if results.multi_hand_landmarks and results.multi_handedness:
        for hand_landmarks, handedness in zip(results.multi_hand_landmarks, results.multi_handedness):
            label = get_hand_label(hand_landmarks, handedness)
            closed = is_hand_closed(hand_landmarks)
            if label == 'Left' and closed:
                left_closed = True
            if label == 'Right' and closed:
                right_closed = True
            mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

    # 판 각도 업데이트
    if left_closed and not right_closed:
        board_angle = max(board_angle - 1, -max_angle)
    elif right_closed and not left_closed:
        board_angle = min(board_angle + 1, max_angle)
    # else:
    #     if board_angle > 0:
    #         board_angle -= 1
    #     elif board_angle < 0:
    #         board_angle += 1

    # 공 물리 업데이트
    ball_vel[1] += gravity
    ball_pos += ball_vel

    if point_on_board(ball_pos, board_center, board_width, board_height, board_angle):
        angle_rad = math.radians(board_angle)
        dx = ball_pos[0] - board_center[0]
        board_y_at_ball_x = board_center[1] - dx * math.tan(angle_rad)

        ball_pos[1] = min(ball_pos[1], board_y_at_ball_x - ball_radius)

        if ball_vel[1] > 0:
            ball_vel[1] = -ball_vel[1] * 0.3

        ball_vel[0] += gravity * math.sin(angle_rad)
        ball_vel[0] *= 1
    else:
        if ball_pos[1] > HEIGHT:
            ball_pos = np.array([WIDTH / 2, HEIGHT / 2], dtype=float)
            ball_vel = np.array([0.0, 0.0], dtype=float)
            board_angle = 0

    screen.fill((30, 30, 30))
    draw_rotated_rect(screen, (200, 200, 200), board_center, board_width, board_height, board_angle)
    pygame.draw.circle(screen, (255, 50, 50), ball_pos.astype(int), ball_radius)

    pygame.display.flip()
    clock.tick(60)

    cv2.imshow("Hand Tracking", frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()
pygame.quit()

# data[].attributes.headline
30803 김대현 플래피버드(입 벌리면 나는 게임)

# data[].attributes.subject
30803 김대현 플래피버드(입 벌리면 나는 게임)

# data[].attributes.body
import cv2
import mediapipe as mp
import numpy as np
import random

mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(static_image_mode=False,
                                  max_num_faces=1,
                                  min_detection_confidence=0.5,
                                  min_tracking_confidence=0.5,
                                  refine_landmarks=True)

cap = cv2.VideoCapture(0)

bird_x = 100
bird_y = 300
bird_velocity = 0
gravity = 0.7
jump_strength = -10

obstacles = []
obstacle_width = 60
gap_height = 230
frame_count = 0
score = 0
high_score = 0
game_over = False

prev_mouth_open = False

bird_radius = 18  # 공 크기 (반지름)

def calculate_mouth_opening(landmarks, image_width, image_height):
    top_lip = landmarks[13]
    bottom_lip = landmarks[14]
    top_lip_y = int(top_lip.y * image_height)
    bottom_lip_y = int(bottom_lip.y * image_height)
    return bottom_lip_y - top_lip_y

while True:
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.flip(frame, 1)
    h, w, _ = frame.shape
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = face_mesh.process(rgb_frame)

    mouth_open = 0
    if results.multi_face_landmarks:
        for face_landmarks in results.multi_face_landmarks:
            landmarks = face_landmarks.landmark
            mouth_open = calculate_mouth_opening(landmarks, w, h)

    is_mouth_open = mouth_open > 15

    if not game_over:
        if prev_mouth_open and not is_mouth_open:
            bird_velocity = jump_strength

        prev_mouth_open = is_mouth_open

        bird_velocity += gravity
        bird_y += bird_velocity

        # 바닥 닿으면 게임 오버
        if bird_y > h - bird_radius:
            bird_y = h - bird_radius
            bird_velocity = 0
            game_over = True

        # 천장 닿으면 게임 오버
        if bird_y < bird_radius:
            bird_y = bird_radius
            bird_velocity = 0
            game_over = True

        if frame_count % 90 == 0:
            hole_y = random.randint(100, h - 100 - gap_height)
            obstacles.append([w, hole_y, hole_y + gap_height])

        # 점수가 올라갈수록 장애물 속도 증가
        base_speed = 3
        speed_increase = score * 0.1
        obstacle_speed = base_speed + speed_increase

        for obs in obstacles:
            obs[0] -= obstacle_speed

        if obstacles and obstacles[0][0] < -obstacle_width:
            obstacles.pop(0)
            score += 1

        bird_rect = (bird_x - bird_radius, int(bird_y) - bird_radius, bird_radius * 2, bird_radius * 2)

        def rect_collision(r1, r2):
            x1, y1, w1, h1 = r1
            x2, y2, w2, h2 = r2
            return not (x1 + w1 < x2 or x1 > x2 + w2 or y1 + h1 < y2 or y1 > y2 + h2)

        for obs in obstacles:
            x, hole_top, hole_bottom = obs
            top_rect = (x, 0, obstacle_width, hole_top)
            bottom_rect = (x, hole_bottom, obstacle_width, h - hole_bottom)
            if rect_collision(bird_rect, top_rect) or rect_collision(bird_rect, bottom_rect):
                game_over = True

        if game_over and score > high_score:
            high_score = score

    frame[:] = (0, 0, 0)

    cv2.circle(frame, (bird_x, int(bird_y)), bird_radius, (0, 255, 255), -1)

    for obs in obstacles:
        x, hole_top, hole_bottom = obs
        cv2.rectangle(frame, (int(x), 0), (int(x) + obstacle_width, hole_top), (0, 255, 0), -1)
        cv2.rectangle(frame, (int(x), hole_bottom), (int(x) + obstacle_width, h), (0, 255, 0), -1)

    cv2.putText(frame, f'Score: {score}', (10, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 3)
    cv2.putText(frame, f'High Score: {high_score}', (10, 100),
                cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 255), 2)

    if game_over:
        cv2.putText(frame, "Game Over! Press R to Restart", (50, h // 2),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)

    cv2.imshow('Flappy Bird Mouth Control', frame)

    key = cv2.waitKey(1) & 0xFF
    if key == 27:
        break
    if game_over and (key == ord('r') or key == ord('R')):
        bird_y = 300
        bird_velocity = 0
        obstacles.clear()
        score = 0
        game_over = False
        frame_count = 0
        prev_mouth_open = False

    frame_count += 1

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
기능 : 이 코드는 웹캠으로 실시간 영상을 받아옴.
Mediapipe 포즈 추적 기능을 사용해 사람의 어깨, 엉덩이, 무릎 위치를 인식함.
엉덩이 각도를 계산해 허리가 구부정한지 판단함.
양쪽 어깨의 수평·수직 위치 차이를 측정해 어깨가 불균형한지 확인함.
허리가 구부정하거나 어깨가 비대칭이면 화면에 경고 메시지를 띄움.
포즈 랜드마크와 각도, 어깨 위치 차이를 실시간으로 화면에 표시함.
ESC 키 입력 시 프로그램을 종료함.

코드 :

import cv2
import mediapipe as mp
import math

mp_pose = mp.solutions.pose
pose = mp_pose.Pose(min_detection_confidence=0.7, min_tracking_confidence=0.7)
mp_drawing = mp.solutions.drawing_utils

WIDTH, HEIGHT = 640, 480

cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT)

def calculate_angle(a, b, c):
    ang = math.degrees(
        math.atan2(c[1] - b[1], c[0] - b[0]) -
        math.atan2(a[1] - b[1], a[0] - b[0])
    )
    ang = abs(ang)
    if ang > 180:
        ang = 360 - ang
    return ang

while True:
    ret, frame = cap.read()
    if not ret:
        break
    frame = cv2.flip(frame, 1)
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    results = pose.process(image_rgb)

    if results.pose_landmarks:
        mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        landmarks = results.pose_landmarks.landmark

        def get_coord(idx):
            return int(landmarks[idx].x * WIDTH), int(landmarks[idx].y * HEIGHT)

        left_shoulder = get_coord(mp_pose.PoseLandmark.LEFT_SHOULDER.value)
        right_shoulder = get_coord(mp_pose.PoseLandmark.RIGHT_SHOULDER.value)
        left_hip = get_coord(mp_pose.PoseLandmark.LEFT_HIP.value)
        left_knee = get_coord(mp_pose.PoseLandmark.LEFT_KNEE.value)

        hip_angle = calculate_angle(left_shoulder, left_hip, left_knee)

        messages = []
        if hip_angle < 160:
            messages.append("Your back is slouched!")

        # 어깨 불균형 강화 기준
        shoulder_y_diff = abs(left_shoulder[1] - right_shoulder[1])  # 수직 차이
        shoulder_x_diff = abs(left_shoulder[0] - right_shoulder[0])  # 수평 차이

        vertical_threshold = 15  # 수직 차이 임계값 (픽셀)
        horizontal_threshold = 100  # 수평 차이 임계값 (픽셀)

        if shoulder_y_diff > vertical_threshold or shoulder_x_diff > horizontal_threshold:
            messages.append("Your shoulders are uneven!")

        y0 = 50
        for i, msg in enumerate(messages):
            cv2.putText(frame, msg, (30, y0 + i*40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 3)

        cv2.putText(frame, f"Hip angle: {int(hip_angle)}", (30, HEIGHT - 90), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)
        cv2.putText(frame, f"Shoulder Y diff: {int(shoulder_y_diff)} px", (30, HEIGHT - 60), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)
        cv2.putText(frame, f"Shoulder X diff: {int(shoulder_x_diff)} px", (30, HEIGHT - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)

    cv2.imshow("Posture Correction", frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2

import mediapipe as mp

import random

import math

# MediaPipe 설정

mp_face = mp.solutions.face_mesh

face_mesh = mp_face.FaceMesh(max_num_faces=1)

# 초기화

width, height = 640, 480

score = 0

target_score = 15

# 아이템 리스트 (사과 + 함정)

objects = [

{"type": "apple", "pos": [random.randint(100, 500), 0], "speed": 5},

{"type": "bad", "pos": [random.randint(100, 500), -200], "speed": 5}

]

apple_radius = 20

# 충돌 판정

def is_collision(obj_pos, mouth_pos):

ox, oy = obj_pos

mx, my = mouth_pos

distance = math.hypot(ox - mx, oy - my)

return distance < apple_radius + 20

# 웹캠

cap = cv2.VideoCapture(0)

while True:

ret, frame = cap.read()

if not ret:

break

frame = cv2.flip(frame, 1)

h, w, _ = frame.shape

rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

result = face_mesh.process(rgb)

mouth_pos = None

if result.multi_face_landmarks:

for face_landmarks in result.multi_face_landmarks:

lm = face_landmarks.landmark[13]

mx, my = int(lm.x w), int(lm.y h)

mouth_pos = (mx, my)

cv2.circle(frame, mouth_pos, 8, (255, 0, 0), -1)

# 오브젝트 이동 및 처리

for obj in objects:

obj["pos"][1] += int(obj["speed"])

# 충돌 감지

if mouth_pos and is_collision(obj["pos"], mouth_pos):

if obj["type"] == "apple":

score += 1

else:

score -= 1

# 오브젝트 초기화

obj["pos"] = [random.randint(50, w - 50), 0]

obj["speed"] += 0.2

# 바닥까지 떨어진 경우: 위치만 초기화

if obj["pos"][1] > h:

obj["pos"] = [random.randint(50, w - 50), 0]

obj["speed"] += 0.1

# 그리기

color = (0, 0, 255) if obj["type"] == "apple" else (0, 255, 255)

cv2.circle(frame, tuple(obj["pos"]), apple_radius, color, -1)

# 점수 표시

cv2.putText(frame, f'Score: {score}', (10, 30),

cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

# 승리 조건

if score >= target_score:

cv2.putText(frame, 'You Win! 🎉', (150, 250),

cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 255, 0), 4)

cv2.imshow("Catch Game", frame)

cv2.waitKey(2000)

break

# 화면 출력

cv2.imshow("Catch Game", frame)

if cv2.waitKey(1) & 0xFF == 27:

break

cap.release()

cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp

# MediaPipe 초기화
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands(
    static_image_mode=False,
    max_num_hands=4,
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
)

# 손가락 개수 세는 함수 (손등/손바닥 인식 개선)
def count_fingers(lm, handedness):
    fingers = []

    # 손가락 끝과 중간 마디 비교
    tips_ids = [8, 12, 16, 20]
    for tip in tips_ids:
        if lm.landmark[tip].y < lm.landmark[tip - 2].y:
            fingers.append(1)
        else:
            fingers.append(0)

    # 엄지는 x 좌표 기준으로 방향 감안
    if handedness == 'Right':
        fingers.insert(0, int(lm.landmark[4].x > lm.landmark[3].x))
    else:
        fingers.insert(0, int(lm.landmark[4].x < lm.landmark[3].x))

    return sum(fingers)

# 플레이어 상태 초기화
players = {
    'Player1': {'left': 1, 'right': 1},
    'Player2': {'left': 1, 'right': 1}
}
turn = 'Player1'

# 손 좌우로 플레이어 식별
def identify_player(x_norm):
    return 'Player1' if x_norm < 0.5 else 'Player2'

# 공격 감지용 상태
attack_done = False

# 웹캠 시작
cap = cv2.VideoCapture(0)

while cap.isOpened():
    success, frame = cap.read()
    if not success:
        break

    frame = cv2.flip(frame, 1)
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = hands.process(rgb)

    h, w, _ = frame.shape
    hand_data = {
        'Player1': {},
        'Player2': {}
    }

    if results.multi_hand_landmarks and results.multi_handedness:
        for lm, handedness_data in zip(results.multi_hand_landmarks, results.multi_handedness):
            handedness = handedness_data.classification[0].label  # 'Left' or 'Right'
            player = identify_player(lm.landmark[0].x)
            fingers = count_fingers(lm, handedness)

            hand_data[player][handedness] = fingers

            mp_drawing.draw_landmarks(frame, lm, mp_hands.HAND_CONNECTIONS)

            # 디버깅용 손가락 수 표시
            cx, cy = int(lm.landmark[0].x * w), int(lm.landmark[0].y * h)
            cv2.putText(frame, f'{player} {handedness}: {fingers}', (cx - 50, cy - 30),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)

    # 공격 로직 (Left가 공격한다고 가정)
    if not attack_done:
        attacker = turn
        defender = 'Player2' if attacker == 'Player1' else 'Player1'

        if 'Left' in hand_data[attacker] and 'Left' in hand_data[defender]:
            attack_val = hand_data[attacker]['Left']
            defend_val = players[defender]['left']

            result_val = (attack_val + defend_val) % 5
            players[defender]['left'] = result_val

            print(f"{attacker} attacks {defender}'s LEFT: {attack_val} + {defend_val} = {result_val}")
            attack_done = True
            turn = defender  # 턴 전환

    # 공격 후 손 내려야 다시 공격 가능
    if not any(hand_data[turn].values()):
        attack_done = False  # 손 다 내리면 초기화

    # 점수 표시
    cv2.putText(frame, f"{turn}'s Turn", (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (100, 255, 255), 2)
    cv2.putText(frame, f"P1 L:{players['Player1']['left']} R:{players['Player1']['right']}", (10, h - 60),
                cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 150, 150), 2)
    cv2.putText(frame, f"P2 L:{players['Player2']['left']} R:{players['Player2']['right']}", (10, h - 30),
                cv2.FONT_HERSHEY_SIMPLEX, 0.9, (150, 255, 150), 2)

    cv2.imshow("Chopstick Game", frame)

    if cv2.waitKey(5) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import random
import time

# Mediapipe 초기화
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands(
    static_image_mode=False,
    max_num_hands=1,
    min_detection_confidence=0.7,
    min_tracking_confidence=0.5
)

cap = cv2.VideoCapture(0)

# 게임 타이머 설정
GAME_TIME = 30  # 30초 제한
start_time = time.time()

# 초기 타겟 설정
target_radius = 40
target_x, target_y = random.randint(100, 500), random.randint(100, 400)
score = 0
last_target_time = time.time()
target_interval = 2  # 초

game_over = False

# 손가락 위치 스무딩 관련 변수
prev_cx, prev_cy = None, None
smooth_factor = 0.7  # 부드럽게 만들기 위한 가중치

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    current_time = time.time()
    elapsed_time = current_time - start_time
    remaining_time = max(0, int(GAME_TIME - elapsed_time))

    if remaining_time == 0:
        game_over = True

    frame = cv2.flip(frame, 1)
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = hands.process(image_rgb)

    h, w, _ = frame.shape

    if not game_over:
        # 타겟 위치 갱신
        if time.time() - last_target_time > target_interval:
            target_x, target_y = random.randint(100, w - 100), random.randint(100, h - 100)
            last_target_time = time.time()

        # 타겟 그리기
        cv2.circle(frame, (target_x, target_y), target_radius, (0, 255, 0), -1)
        cv2.putText(frame, "Touch!", (target_x - 20, target_y - 50),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 200, 0), 2)

        if result.multi_hand_landmarks:
            for hand_landmarks in result.multi_hand_landmarks:
                index_finger = hand_landmarks.landmark[8]  # 검지 끝
                raw_cx, raw_cy = int(index_finger.x * w), int(index_finger.y * h)

                # 스무딩 적용
                if prev_cx is not None and prev_cy is not None:
                    cx = int(prev_cx * smooth_factor + raw_cx * (1 - smooth_factor))
                    cy = int(prev_cy * smooth_factor + raw_cy * (1 - smooth_factor))
                else:
                    cx, cy = raw_cx, raw_cy

                prev_cx, prev_cy = cx, cy

                # 검지 위치 시각화
                cv2.circle(frame, (cx, cy), 10, (255, 0, 0), -1)

                # 타겟과 거리 계산
                distance = ((cx - target_x) ** 2 + (cy - target_y) ** 2) ** 0.5
                if distance < target_radius:
                    score += 1
                    target_x, target_y = random.randint(100, w - 100), random.randint(100, h - 100)
                    last_target_time = time.time()
                    prev_cx, prev_cy = None, None  # 타겟 갱신 시 초기화

    # 시간 및 점수 표시
    cv2.putText(frame, f"Time: {remaining_time}", (10, 40),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 3)
    cv2.putText(frame, f"Score: {score}", (10, 90),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)

    if game_over:
        cv2.putText(frame, "Game Over!", (w // 2 - 150, h // 2),
                    cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)

    cv2.imshow("30-Second Touch Game", frame)
    if cv2.waitKey(1) & 0xFF == 27:  # ESC
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import math

# MediaPipe Hands 초기화
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils

# 손의 마디 번호를 화면에 표시하는 함수
def draw_landmark_numbers(frame, hand_landmarks):
    h, w, _ = frame.shape
    for idx, landmark in enumerate(hand_landmarks.landmark):
        cx, cy = int(landmark.x * w), int(landmark.y * h)
        cv2.putText(frame, str(idx), (cx - 10, cy + 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)

# 손가락 간 거리 계산 함수
def distance(point1, point2):
    return math.sqrt((point1.x - point2.x)**2 + (point1.y - point2.y)**2)

# 'OK' 제스처 판별 함수
def is_ok_gesture(hand_landmarks):
    thumb_tip = hand_landmarks.landmark[4]
    index_tip = hand_landmarks.landmark[8]
    dist_thumb_index = distance(thumb_tip, index_tip)

    if dist_thumb_index > 0.05:
        return False

    wrist = hand_landmarks.landmark[0]
    middle_tip = hand_landmarks.landmark[12]
    ring_tip = hand_landmarks.landmark[16]
    pinky_tip = hand_landmarks.landmark[20]

    dist_wrist_middle = distance(wrist, middle_tip)
    dist_wrist_ring = distance(wrist, ring_tip)
    dist_wrist_pinky = distance(wrist, pinky_tip)

    if dist_wrist_middle < 0.3 or dist_wrist_ring < 0.3 or dist_wrist_pinky < 0.3:
        return False

    return True

# 웹캠 열기
cap = cv2.VideoCapture(0)

with mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.7, min_tracking_confidence=0.7) as hands:
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        frame = cv2.flip(frame, 1)
        img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        results = hands.process(img_rgb)

        ok_gesture_count = 0

        # 기존의 'OK!!' 문구를 지우기 위해 배경을 덮어씌움
        frame[:] = (0, 0, 0)

        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                if is_ok_gesture(hand_landmarks):
                    ok_gesture_count += 1

                # 손의 마디 번호 표시
                draw_landmark_numbers(frame, hand_landmarks)

                # 손 랜드마크 그리기
                mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

        # 두 손 모두 'OK' 제스처를 하면 'Super OK!!'로 변경
        if ok_gesture_count == 2:
            cv2.putText(frame, 'Super OK!!', (50, 200),
                        cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 255, 255), 5)
        elif ok_gesture_count == 1:
            cv2.putText(frame, 'OK!!', (50, 100),
                        cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 255, 0), 5)

        cv2.imshow('Hand Gesture Recognition', frame)

        if cv2.waitKey(1) & 0xFF == 27:
            break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2

import mediapipe as mp

import math

mp_hands = mp.solutions.hands

mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands(

static_image_mode=False,

max_num_hands=2,

min_detection_confidence=0.7,

min_tracking_confidence=0.5

)

def calculate_angle(a, b, c):

ba = (a[0]-b[0], a[1]-b[1])

bc = (c[0]-b[0], c[1]-b[1])

dot_product = ba[0]*bc[0] + ba[1]*bc[1]

mag_ba = math.sqrt(ba[0]**2 + ba[1]**2)

mag_bc = math.sqrt(bc[0]**2 + bc[1]**2)

if mag_ba * mag_bc == 0:

return 0

cos_angle = dot_product / (mag_ba * mag_bc)

cos_angle = max(min(cos_angle, 1), -1)

angle = math.acos(cos_angle)

return math.degrees(angle)

is_back_of_hand_facing(hand_landmarks, h):

thumb_mcp_y = hand_landmarks.landmark[2].y * h

pinky_mcp_y = hand_landmarks.landmark[17].y * h

return pinky_mcp_y < thumb_mcp_y

def is_finger_open_angle(hand_landmarks, tip_id, pip_id, mcp_id, w, h):

tip = hand_landmarks.landmark[tip_id]

pip = hand_landmarks.landmark[pip_id]

mcp = hand_landmarks.landmark[mcp_id]

tip_c = (tip.x w, tip.y h)

pip_c = (pip.x w, pip.y h)

mcp_c = (mcp.x w, mcp.y h)

angle = calculate_angle(tip_c, pip_c, mcp_c)

return angle > 160

def get_finger_states(hand_landmarks, w, h):

back_of_hand_facing = is_back_of_hand_facing(hand_landmarks, h)

if not back_of_hand_facing:

return None

fingers = []

fingers.append(is_finger_open_angle(hand_landmarks, 4, 3, 2, w, h)) # 엄지

fingers.append(is_finger_open_angle(hand_landmarks, 8, 6, 5, w, h)) # 검지

fingers.append(is_finger_open_angle(hand_landmarks, 12, 10, 9, w, h)) # 중지

fingers.append(is_finger_open_angle(hand_landmarks, 16, 14, 13, w, h))# 약지

fingers.append(is_finger_open_angle(hand_landmarks, 20, 18, 17, w, h))# 새끼

return fingers

def detect_hand_gesture(fingers):

if fingers == [False, False, False, False, False]:

return "Rock"

elif fingers == [False, True, True, False, False]:

return "Scissors"

elif all(fingers):

return "Paper"

else:

return "Unknown"

def main():

cap = cv2.VideoCapture(0)

while True:

success, frame = cap.read()

if not success:

break

frame = cv2.flip(frame, 1)

h, w, _ = frame.shape

image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

result = hands.process(image_rgb)

if result.multi_hand_landmarks:

for hand_landmarks in result.multi_hand_landmarks:

mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

fingers = get_finger_states(hand_landmarks, w, h)

if fingers is not None:

gesture = detect_hand_gesture(fingers)

cv2.putText(frame, f"Gesture: {gesture}", (10, 50),

cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

cv2.imshow("Rock Paper Scissors Gesture (Back of Hand)", frame)

if cv2.waitKey(1) & 0xFF == 27:

break

cap.release()

cv2.destroyAllWindows()

if name == "__main__":

main()

# data[].attributes.body
import tkinter as tk
from PIL import Image, ImageTk
import cv2
import mediapipe as mp
import time

class MouthBubbleApp:
    def __init__(self, root):
        self.root = root
        self.root.title("입 벌림 감지 비눗방울")

        self.width, self.height = 640, 480

        # 캔버스 생성
        self.canvas = tk.Canvas(root, width=self.width, height=self.height)
        self.canvas.pack()

        # 카메라 초기화
        self.cap = cv2.VideoCapture(0)
        if not self.cap.isOpened():
            raise RuntimeError("웹캠을 열 수 없습니다.")
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.width)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.height)

        # Mediapipe 얼굴 인식 초기화
        self.mp_face_mesh = mp.solutions.face_mesh
        self.face_mesh = self.mp_face_mesh.FaceMesh(static_image_mode=False,
                                                    max_num_faces=1,
                                                    refine_landmarks=True,
                                                    min_detection_confidence=0.5,
                                                    min_tracking_confidence=0.5)

        self.drawing_spec = mp.solutions.drawing_utils.DrawingSpec(thickness=1, circle_radius=1)

        # 비눗방울 리스트
        self.bubbles = []

        # 입 상태 추적
        self.mouth_open = False

        # 이전 입 벌림 시간 체크 (버튼 누름처럼 입 벌리고 닫힌 순간 체크)
        self.last_mouth_open_time = 0

        # 업데이트 시작
        self.update_frame()

        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

    def update_frame(self):
        ret, frame = self.cap.read()
        if not ret:
            self.root.after(10, self.update_frame)
            return

        frame = cv2.flip(frame, 1)  # 좌우 반전 (셀카 모드)
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        results = self.face_mesh.process(rgb_frame)

        mouth_open_now = False

        if results.multi_face_landmarks:
            face_landmarks = results.multi_face_landmarks[0]

            # 입 랜드마크 좌표 (mediapipe face_mesh 입 주변 점)
            # 윗입술: 13 (13번), 아랫입술: 14 (14번)
            # mediapipe face mesh 참고 https://github.com/google/mediapipe/blob/master/docs/solutions/face_mesh.md
            # 정확히는 13과 14번은 inner lips vertical middle landmarks

            h, w, _ = frame.shape

            top_lip = face_landmarks.landmark[13]
            bottom_lip = face_landmarks.landmark[14]

            top_lip_y = top_lip.y * h
            bottom_lip_y = bottom_lip.y * h

            mouth_distance = bottom_lip_y - top_lip_y

            # print("mouth_distance:", mouth_distance)  # 참고용

            # 임계값 (입 벌렸다고 판단할 기준, 카메라 환경마다 조절 가능)
            MOUTH_OPEN_THRESHOLD = 15

            if mouth_distance > MOUTH_OPEN_THRESHOLD:
                mouth_open_now = True

        # 입 벌림 상태가 이전과 달라졌을 때 이벤트 발생
        current_time = time.time()
        if mouth_open_now and not self.mouth_open:
            # 입 벌림 시작
            self.mouth_open = True

        elif not mouth_open_now and self.mouth_open:
            # 입 닫힘 감지 → 비눗방울 생성
            self.mouth_open = False
            # 비눗방울을 입 위치 근처에 생성
            if results.multi_face_landmarks:
                # 입 위치 (중앙)
                cx = int((face_landmarks.landmark[13].x + face_landmarks.landmark[14].x) / 2 * w)
                cy = int((face_landmarks.landmark[13].y + face_landmarks.landmark[14].y) / 2 * h)
                self.create_bubble(cx, cy)

        # 이미지 변환 및 Tkinter에 출력
        img = Image.fromarray(rgb_frame)
        self.photo = ImageTk.PhotoImage(image=img)

        if hasattr(self, 'image_on_canvas'):
            self.canvas.itemconfig(self.image_on_canvas, image=self.photo)
        else:
            self.image_on_canvas = self.canvas.create_image(0, 0, image=self.photo, anchor=tk.NW)

        self.update_bubbles()

        self.root.after(15, self.update_frame)

    def create_bubble(self, x, y):
        r = 20
        bubble = self.canvas.create_oval(x - r, y - r, x + r, y + r,
                                         fill='lightblue', outline='white', width=2)
        self.bubbles.append([bubble, 0])

    def update_bubbles(self):
        remove_list = []
        for bubble_info in self.bubbles:
            bubble_id, step = bubble_info
            if step > 20:
                self.canvas.delete(bubble_id)
                remove_list.append(bubble_info)
                continue

            self.canvas.move(bubble_id, 0, -5)
            bubble_info[1] += 1

        for bubble_info in remove_list:
            self.bubbles.remove(bubble_info)

    def on_closing(self):
        if self.cap.isOpened():
            self.cap.release()
        self.root.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    app = MouthBubbleApp(root)
    root.mainloop()

# data[].attributes.attachment_caption
import cv2
import mediapipe as mp
import random
import math
import time

# Mediapipe 초기화
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands()

# 웹캠 열기
cap = cv2.VideoCapture(0)

# 타겟 초기 위치 및 점수
target_x = random.randint(100, 500)
target_y = random.randint(100, 400)
target_radius = 30
score = 0
last_shot_time = 0
shot_cooldown = 0.5  # 발사 간격 제한

# 거리 계산 함수
def calc_distance(x1, y1, x2, y2):
    return math.hypot(x2 - x1, y2 - y1)

while True:
    success, frame = cap.read()
    if not success:
        break

    frame = cv2.flip(frame, 1)
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = hands.process(image_rgb)

    h, w, _ = frame.shape
    index_finger = None
    thumb = None

    if result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            # 랜드마크 좌표 추출
            lm_list = hand_landmarks.landmark
            index_finger = lm_list[8]
            thumb = lm_list[4]

            # 좌표 변환
            ix, iy = int(index_finger.x * w), int(index_finger.y * h)
            tx, ty = int(thumb.x * w), int(thumb.y * h)

            # 거리 계산
            distance = calc_distance(ix, iy, tx, ty)

            # 손가락 좌표 표시
            cv2.circle(frame, (ix, iy), 10, (0, 255, 255), -1)
            cv2.circle(frame, (tx, ty), 10, (255, 0, 255), -1)

            # 발사 조건 (엄지와 검지가 가까워짐 + 쿨타임)
            if distance < 40 and time.time() - last_shot_time > shot_cooldown:
                last_shot_time = time.time()

                # 발사 시 총알 그리기
                cv2.line(frame, (tx, ty), (ix, iy), (0, 0, 255), 4)

                # 타겟 맞췄는지 확인
                if calc_distance(ix, iy, target_x, target_y) < target_radius:
                    score += 1
                    target_x = random.randint(100, w - 100)
                    target_y = random.randint(100, h - 100)

            mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

    # 타겟 그리기
    cv2.circle(frame, (target_x, target_y), target_radius, (0, 255, 0), -1)
    cv2.putText(frame, f"Score: {score}", (10, 40),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)

    cv2.imshow("Finger Shooter Game", frame)

    if cv2.waitKey(1) & 0xFF == 27:  # ESC 키
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import mediapipe as mp
import numpy as np

mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils

def get_gesture(hand_landmarks):
    fingers = []

    if hand_landmarks.landmark[4].x > hand_landmarks.landmark[3].x:
        fingers.append(1)
    else:
        fingers.append(0)

    for tip_id in [8, 12, 16, 20]:
        tip_y = hand_landmarks.landmark[tip_id].y
        pip_y = hand_landmarks.landmark[tip_id - 2].y
        if tip_y < pip_y:
            fingers.append(1)
        else:
            fingers.append(0)

    if sum(fingers) == 0:
        return "rock"
    elif sum(fingers) == 5:
        return "paper"
    elif fingers[1] == 1 and fingers[2] == 1 and fingers[0] == 0 and fingers[3] == 0 and fingers[4] == 0:
        return "scissors"
    else:
        return "unknown"

def decide_winner(gesture_left, gesture_right):
    if gesture_left == gesture_right:
        return "Draw!"
    if (gesture_left == "rock" and gesture_right == "scissors") or \
       (gesture_left == "scissors" and gesture_right == "paper") or \
       (gesture_left == "paper" and gesture_right == "rock"):
        return "Left"
    elif gesture_right in ["rock", "paper", "scissors"]:
        return "Right"
    else:
        return None

def draw_star(img, center, size=40, color=(0, 255, 255), thickness=2):
    """
    중심점(center)에 별을 그립니다.
    size는 별 크기 조절
    """
    pts = []
    for i in range(5):
        angle = i * 72 * np.pi / 180 - np.pi / 2  # 5각 별 각도
        x_outer = int(center[0] + size * np.cos(angle))
        y_outer = int(center[1] + size * np.sin(angle))
        pts.append((x_outer, y_outer))

        angle_inner = angle + 36 * np.pi / 180
        x_inner = int(center[0] + size / 2 * np.cos(angle_inner))
        y_inner = int(center[1] + size / 2 * np.sin(angle_inner))
        pts.append((x_inner, y_inner))

    pts = np.array(pts, np.int32).reshape((-1,1,2))
    cv2.polylines(img, [pts], isClosed=True, color=color, thickness=thickness)

cap = cv2.VideoCapture(0)

with mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.7) as hands:
    while True:
        ret, frame = cap.read()
        if not ret:
            break

        frame = cv2.flip(frame, 1)
        img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        results = hands.process(img_rgb)

        gesture_left = None
        gesture_right = None
        left_hand_landmarks = None
        right_hand_landmarks = None

        if results.multi_hand_landmarks and results.multi_handedness:
            for hand_landmarks, handedness in zip(results.multi_hand_landmarks, results.multi_handedness):
                label = handedness.classification[0].label
                gesture = get_gesture(hand_landmarks)

                if label == "Left":
                    gesture_left = gesture
                    left_hand_landmarks = hand_landmarks
                elif label == "Right":
                    gesture_right = gesture
                    right_hand_landmarks = hand_landmarks

                mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
                x0 = int(hand_landmarks.landmark[0].x * frame.shape[1])
                y0 = int(hand_landmarks.landmark[0].y * frame.shape[0])
                cv2.putText(frame, f"{label}: {gesture}", (x0, y0 - 20),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,0), 2)

            winner = decide_winner(gesture_left, gesture_right)
            if winner == "Left" and left_hand_landmarks is not None:
                x = int(left_hand_landmarks.landmark[0].x * frame.shape[1])
                y = int(left_hand_landmarks.landmark[0].y * frame.shape[0])
                draw_star(frame, (x, y))
                cv2.putText(frame, "Left hand wins!", (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 255, 0), 3)
            elif winner == "Right" and right_hand_landmarks is not None:
                x = int(right_hand_landmarks.landmark[0].x * frame.shape[1])
                y = int(right_hand_landmarks.landmark[0].y * frame.shape[0])
                draw_star(frame, (x, y))
                cv2.putText(frame, "Right hand wins!", (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 255, 0), 3)
            elif winner is None:
                cv2.putText(frame, "Cannot decide winner", (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
            else:
                cv2.putText(frame, "Draw!", (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 2)
        else:
            cv2.putText(frame, "No hands detected", (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

        cv2.imshow("Rock-Paper-Scissors with MediaPipe", frame)

        if cv2.waitKey(1) & 0xFF == 27:
            break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.headline
코드와 실행화면 캡쳐올려주세요

# data[].attributes.subject
코드와 실행화면 캡쳐올려주세요

# data[].attributes.body
import cv2
import mediapipe as mp

# 초기화
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)

# 웹캠
cap = cv2.VideoCapture(0)

# 상태 변수
count = 0
hands_up = False  # 현재 손이 올라간 상태인지

while cap.isOpened():
    success, frame = cap.read()
    if not success:
        break

    # 이미지 전처리
    frame = cv2.flip(frame, 1)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = pose.process(rgb_frame)

    if results.pose_landmarks:
        landmarks = results.pose_landmarks.landmark

        # 필요한 키포인트
        left_wrist = landmarks[mp_pose.PoseLandmark.LEFT_WRIST]
        right_wrist = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST]
        left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER]
        right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER]

        h, w, _ = frame.shape

        # y좌표 추출 (작을수록 위쪽)
        lw_y = left_wrist.y
        rw_y = right_wrist.y
        ls_y = left_shoulder.y
        rs_y = right_shoulder.y

        # 둘 중 한 손이라도 어깨보다 위로 올라갔는지 확인
        is_hand_up = lw_y < ls_y or rw_y < rs_y

        # 상태 변화 감지 → 손을 내렸다가 다시 들었을 때만 카운트 증가
        if is_hand_up and not hands_up:
            count += 1
            hands_up = True
        elif not is_hand_up and hands_up:
            hands_up = False

        # 포즈 시각화
        mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)

    # 카운트 표시
    cv2.putText(frame, f'Count: {count}', (50, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 5)

    # 창 표시
    cv2.imshow('Hand Raise Game', frame)
    if cv2.waitKey(5) & 0xFF == 27:  # ESC 키
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2

import mediapipe as mp

import time

import numpy as np

import random

mp_hands = mp.solutions.hands

mp_drawing = mp.solutions.drawing_utils

hands = mp_hands.Hands(

max_num_hands=2,

min_detection_confidence=0.7,

min_tracking_confidence=0.7

)

cap = cv2.VideoCapture(0)

# 원 크기와 상태 변수

circle_radius = 10

circle_growing = False

start_time = None

exploded = False

shake_offset = (0, 0)

def is_hands_facing_each_other(hand1, hand2, img_width, threshold=100):

# 손바닥 중심으로 x좌표 계산 (landmark 0이 손목, 9, 5 등 손바닥 위치 고려 가능)

def palm_center(hand):

x_vals = [lm.x for lm in hand.landmark]

cx = int(np.mean(x_vals) * img_width)

return cx

cx1 = palm_center(hand1)

cx2 = palm_center(hand2)

# 두 손이 서로 마주보고 있는 조건:

# 손 위치가 서로 가까이(x축 차이가 threshold 이하), 그리고 x 좌표가 서로 반대쪽(한쪽은 왼쪽, 다른쪽은 오른쪽)

distance = abs(cx1 - cx2)

facing = (distance < threshold) and (cx1 < cx2)

return facing, (cx1 + cx2)//2

def apply_shake(frame, intensity=10):

h, w = frame.shape[:2]

dx = random.randint(-intensity, intensity)

dy = random.randint(-intensity, intensity)

M = np.float32([[1, 0, dx], [0, 1, dy]])

shaken = cv2.warpAffine(frame, M, (w, h))

return shaken, (dx, dy)

while True:

success, frame = cap.read()

if not success:

break

frame = cv2.flip(frame, 1)

img_h, img_w = frame.shape[:2]

image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

result = hands.process(image_rgb)

if result.multi_hand_landmarks and len(result.multi_hand_landmarks) == 2:

hand1, hand2 = result.multi_hand_landmarks

facing, center_x = is_hands_facing_each_other(hand1, hand2, img_w)

# 손 랜드마크 그리기

for hand_landmarks in result.multi_hand_landmarks:

mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

if facing:

if not circle_growing:

start_time = time.time()

circle_growing = True

circle_radius = 10

exploded = False

else:

circle_growing = False

start_time = None

circle_radius = 10

exploded = False

else:

circle_growing = False

start_time = None

circle_radius = 10

exploded = False

# 원 크기 점진적 증가 처리 (0.5초마다 1.5배씩 증가)

if circle_growing and start_time:

elapsed = time.time() - start_time

if elapsed > 0.5:

factor = 1.5 ** int((elapsed - 0.5) // 0.5)

circle_radius = int(10 * factor)

# 원 크기가 너무 커지면 폭발 효과 + 화면 흔들림

if circle_radius > 150 and not exploded:

exploded = True

explosion_start = time.time()

# 화면 흔들림과 폭발 이펙트

if exploded:

frame, shake_offset = apply_shake(frame, intensity=20)

# 폭발 이펙트 - 랜덤 위치에 작은 원 그리기

for _ in range(50):

x = random.randint(0, img_w)

y = random.randint(0, img_h)

r = random.randint(5, 15)

color = (random.randint(150, 255), random.randint(0, 50), random.randint(0, 50))

cv2.circle(frame, (x, y), r, color, -1)

# 폭발 지속시간 1.5초

if time.time() - explosion_start > 1.5:

circle_growing = False

start_time = None

circle_radius = 10

exploded = False

shake_offset = (0, 0)

else:

# 원 그리기 (두 손이 마주보고 있을 때만)

if circle_growing and start_time:

center_y = img_h // 2

cv2.circle(frame, (center_x + shake_offset[0], center_y + shake_offset[1]), circle_radius, (255, 0, 0), -1)

cv2.imshow("Hand Interaction", frame)

if cv2.waitKey(1) & 0xFF == 27:  # ESC

break

cap.release()

cv2.destroyAllWindows()

# data[].attributes.headline
코드와 실행화면 캡쳐올려주세요

# data[].attributes.subject
코드와 실행화면 캡쳐올려주세요

# data[].attributes.headline
코드와 실행화면 캡쳐올려주세요

# data[].attributes.subject
코드와 실행화면 캡쳐올려주세요

# data[].attributes.body
import cv2
import mediapipe as mp
import random

# Mediapipe 초기화
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
    static_image_mode=False,
    max_num_hands=2,
    min_detection_confidence=0.7,
    min_tracking_confidence=0.5
)

FINGER_TIPS = [8, 12, 16, 20]  # 손가락 끝 인덱스
FINGER_PIPS = [6, 10, 14, 18]  # 손가락 중간 관절 인덱스

# 아이템 클래스 정의
class Item:
    def __init__(self, width, height, speed):
        self.x = random.randint(50, width - 50)
        self.y = 0
        self.speed = speed
        self.radius = 30
        self.type = "fruit" if random.random() < 0.8 else "bomb"
        self.caught = False

    def fall(self):
        self.y += self.speed

    def draw(self, frame):
        color = (0, 255, 0) if self.type == "fruit" else (0, 0, 255)
        if not self.caught:
            cv2.circle(frame, (int(self.x), int(self.y)), self.radius, color, -1)

    def check_collision(self, hand_x, hand_y):
        dx = self.x - hand_x
        dy = self.y - hand_y
        return (dx**2 + dy**2) ** 0.5 < self.radius + 20

# 주먹 인식 함수
def is_fist(hand_landmarks):
    count_folded = 0
    for tip, pip in zip(FINGER_TIPS, FINGER_PIPS):
        if hand_landmarks.landmark[tip].y > hand_landmarks.landmark[pip].y:
            count_folded += 1
    return count_folded == 4  # 네 손가락이 다 접혔을 때

# 기본 설정
cap = cv2.VideoCapture(0)
score = 0
item = None
base_speed = 5

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.flip(frame, 1)
    h, w, _ = frame.shape
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = hands.process(rgb)

    if item is None or item.caught or item.y > h:
        item = Item(w, h, base_speed + score * 0.3)

    item.fall()

    if result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            lm = hand_landmarks.landmark[9]
            hand_x, hand_y = int(lm.x * w), int(lm.y * h)
            cv2.circle(frame, (hand_x, hand_y), 15, (255, 255, 0), -1)

            if is_fist(hand_landmarks):  # 주먹인 경우에만 체크
                if item.check_collision(hand_x, hand_y):
                    item.caught = True
                    if item.type == "fruit":
                        score += 1
                    elif item.type == "bomb":
                        score -= 2
                    break  # 한 번만 판정

    item.draw(frame)

    cv2.putText(frame, f"Score: {score}", (30, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 255, 255), 3)

    cv2.imshow("Fruit & Bomb Catch (Fist Only)", frame)
    if cv2.waitKey(1) & 0xFF == 27:  # ESC
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.attachment_link.readable_text
import cv2
import mediapipe as mp
import pyautogui
import time

# ������ ������
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(refine_landmarks=True)
cap = cv2.VideoCapture(0)

# ������������ ���������
LEFT_EYE = [33, 133]
RIGHT_EYE = [362, 263]
LEFT_IRIS = 468
RIGHT_IRIS = 473
LEFT_EYELID = [159, 145]
RIGHT_EYELID = [386, 374]

# ���������
move_step = 30
eye_close_thresh = 0.015
blink_cooldown = 1
last_click_time = 0

# ���������
center_horizontal = None
center_vertical = None

# ������ ������ ������
def get_distance(p1, p2):
    return ((p1.x - p2.x)**2 + (p1.y - p2.y)**2)**0.5

# ���� ������ ������
print("���� ������ ���: ��������� 2������ ���������������...")
time.sleep(2)
print("���� ������ ������ ���...")

while center_horizontal is None:
    ret, frame = cap.read()
    if not ret:
        continue
    h, w, _ = frame.shape
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = face_mesh.process(rgb)
    if results.multi_face_landmarks:
        lm = results.multi_face_landmarks[0].landmark
        eye_left = lm[LEFT_EYE[0]]
        eye_right = lm[LEFT_EYE[1]]
        eye_top = lm[159]
        eye_bottom = lm[145]
        iris = lm[LEFT_IRIS]

        # ������ / ������ ������ ������ ������
        center_horizontal = (iris.x - eye_left.x) / (eye_right.x - eye_left.x)
        center_vertical = (iris.y - eye_top.y) / (eye_bottom.y - eye_top.y)
        print("��� ������ ������!")
        break

# ���� ������ ������
while True:
    ret, frame = cap.read()
    if not ret:
        break
    h, w, _ = frame.shape
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = face_mesh.process(rgb)

    if results.multi_face_landmarks:
        lm = results.multi_face_landmarks[0].landmark

        # ��� ������ ������
        left_eye_h = get_distance(lm[LEFT_EYELID[0]], lm[LEFT_EYELID[1]])
        right_eye_h = get_distance(lm[RIGHT_EYELID[0]], lm[RIGHT_EYELID[1]])
        eyes_closed = left_eye_h < eye_close_thresh and right_eye_h < eye_close_thresh

        if eyes_closed and (time.time() - last_click_time > blink_cooldown):
            pyautogui.click()
            print("������� ������!")
            last_click_time = time.time()

        # ������ ������ ������
        iris = lm[LEFT_IRIS]
        eye_left = lm[LEFT_EYE[0]]
        eye_right = lm[LEFT_EYE[1]]
        eye_top = lm[159]
        eye_bottom = lm[145]

        horizontal_ratio = (iris.x - eye_left.x) / (eye_right.x - eye_left.x)
        vertical_ratio = (iris.y - eye_top.y) / (eye_bottom.y - eye_top.y)

        # ��������������� ������
        dx = horizontal_ratio - center_horizontal
        dy = vertical_ratio - center_vertical

        # ��������� ������ (������ ������ ������)
        tolerance = 0.04

        if dx < -tolerance:
            pyautogui.moveRel(-move_step, 0)  # ������
        elif dx > tolerance:
            pyautogui.moveRel(move_step, 0)   # ���������

        if dy < -tolerance:
            pyautogui.moveRel(0, -move_step)  # ���
        elif dy > tolerance:
            pyautogui.moveRel(0, move_step)   # ������

    # ��������� ������
    cv2.imshow("Eye Tracker (Calibrated)", frame)
    if cv2.waitKey(1) & 0xFF == 27:  # ESC ������
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.headline
무조건 지는 가위바위보 30421 임현우

# data[].attributes.subject
무조건 지는 가위바위보 30421 임현우

# data[].attributes.body
말도 하는 가위바위보

# data[].attributes.attachment_link.readable_text
import cv2
import mediapipe as mp
import pyttsx3
import time

# TTS ������ ���������
engine = pyttsx3.init()
engine.setProperty('rate', 150)

mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands(max_num_hands=1, min_detection_confidence=0.7)

def get_hand_shape(landmarks):
    finger_tips = [8, 12, 16, 20]
    finger_open = []

    for tip in finger_tips:
        finger_open.append(landmarks[tip].y < landmarks[tip - 2].y)

    if finger_open == [False, False, False, False]:
        return "rock"
    elif finger_open == [True, True, True, True]:
        return "paper"
    elif finger_open == [True, True, False, False]:
        return "scissors"
    else:
        return "unknown"

def counter_hand(hand):
    if hand == "rock":
        return "paper"
    elif hand == "paper":
        return "scissors"
    elif hand == "scissors":
        return "rock"
    else:
        return "..."

cap = cv2.VideoCapture(0)

prev_counter = None
last_speak_time = 0
speak_delay = 2  # 2��� ������

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.flip(frame, 1)
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = hands.process(rgb)

    current_time = time.time()

    if result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
            shape = get_hand_shape(hand_landmarks.landmark)
            counter = counter_hand(shape)

            cv2.putText(frame, f"You: {shape}", (30, 60),
                        cv2.FONT_HERSHEY_SIMPLEX, 1.8, (255, 255, 255), 4)
            cv2.putText(frame, f"I play: {counter}!", (30, 120),
                        cv2.FONT_HERSHEY_SIMPLEX, 2.2, (0, 255, 0), 5)
            cv2.putText(frame, "I win!", (30, 200),
                        cv2.FONT_HERSHEY_DUPLEX, 3.0, (0, 0, 255), 6)

            # ������ ������ ��������� ��� ������ ������
            if counter != "..." and counter != prev_counter:
                prev_counter = counter
                last_speak_time = current_time

            elif counter != "..." and current_time - last_speak_time >= speak_delay:
                sentence = f"I play {counter}. I win!"
                engine.say(sentence)
                engine.runAndWait()
                last_speak_time = current_time + 100  # 100��� ��������� ������ ������ ������

    else:
        prev_counter = None

    cv2.imshow("Rock Paper Scissors - I Always Win!", frame)
    if cv2.waitKey(1) & 0xFF == 27:  # ESC ������
        break

cap.release()
cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
미디어 파이프 실습3의 사본

# data[].attributes.headline
1. hand 랜드마크 그리고 좌우반전까지

# data[].attributes.subject
1. hand 랜드마크 그리고 좌우반전까지

# data[].attributes.body
import cv2
import mediapipe as mp

mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_draw = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)

while True:
    success, img = cap.read()
    #img = cv2.flip(img,1)
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    result = hands.process(img_rgb)
    if result.multi_hand_landmarks:
        for handLms in result.multi_hand_landmarks:
            mp_draw.draw_landmarks(img,handLms,mp_hands.HAND_CONNECTIONS)

    cv2.imshow("Hand Tracking", img)

    if cv2.waitKey(5) & 0xFF == 27:
        cap.release()
        cv2.destroyAllWindows()

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용(국빈)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용 30211 박주환

# data[].attributes.attachment_link.title
30402 권일철 손 제스쳐 설계용

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본 30418 이승환

# data[].attributes.body
30621 이하율

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본

# data[].attributes.attachment_link.title
손 제스쳐 설계용(학생)의 사본