Загрузка данных


import cv2
import numpy as np
import mediapipe as mp

# Инициализация MediaPipe Hands
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.7
)

# Загрузка изображения для наложения
overlay_img = cv2.imread('meme.png', cv2.IMREAD_UNCHANGED)

if overlay_img is None:
    raise FileNotFoundError("Файл meme.png не найден в текущей папке!")

if overlay_img.shape[2] == 3:
    b, g, r = cv2.split(overlay_img)
    alpha = np.ones(b.shape, dtype=b.dtype) * 255
    overlay_img = cv2.merge((b, g, r, alpha))

h_overlay, w_overlay = overlay_img.shape[:2]
src_pts = np.float32([
    [0, 0],
    [w_overlay, 0],
    [w_overlay, h_overlay],
    [0, h_overlay]
])

cap = cv2.VideoCapture(0, cv2.CAP_V4L2)

def overlay_transparent(background, overlay_warped):
    alpha_mask = (overlay_warped[:, :, 3] / 255.0) * 0.7
    alpha_mask = alpha_mask[:, :, np.newaxis]
    
    overlay_colors = overlay_warped[:, :, :3]
    background_colors = background[:, :, :3]
    
    return (overlay_colors * alpha_mask + background_colors * (1.0 - alpha_mask)).astype(np.uint8)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Не удалось получить кадр с веб-камеры.")
        break

    frame = cv2.flip(frame, 1)
    h_frame, w_frame, _ = frame.shape
    
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    hands_results = hands.process(rgb_frame)

    if hands_results.multi_hand_landmarks and len(hands_results.multi_hand_landmarks) == 2:
        landmarks_list = []
        
        for hand_landmarks in hands_results.multi_hand_landmarks:
            index_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
            thumb_tip = hand_landmarks.landmark[mp_hands.HandLandmark.THUMB_TIP]
            
            landmarks_list.append((int(index_tip.x * w_frame), int(index_tip.y * h_frame)))
            landmarks_list.append((int(thumb_tip.x * w_frame), int(thumb_tip.y * h_frame)))

        landmarks_list.sort(key=lambda pt: pt[0])
        
        left_pair = sorted(landmarks_list[:2], key=lambda pt: pt[1])
        right_pair = sorted(landmarks_list[2:], key=lambda pt: pt[1])

        dst_pts = np.float32([
            left_pair[0],
            right_pair[0],
            right_pair[1],
            left_pair[1]
        ])

        matrix = cv2.getPerspectiveTransform(src_pts, dst_pts)
        warped_overlay = cv2.warpPerspective(overlay_img, matrix, (w_frame, h_frame))

        frame = overlay_transparent(frame, warped_overlay)

        pts = dst_pts.astype(np.int32).reshape((-1, 1, 2))
        cv2.polylines(frame, [pts], isClosed=True, color=(255, 0, 180), thickness=3)

    cv2.imshow("TikTok Filter", frame)

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

cap.release()
cv2.destroyAllWindows()