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