merhaba arkadaşlar,
Kız arkadaşımın isteği üzerine, el hareketleriyle kitap sayfası çevirme programı yapmakla uğraşıyordum. Forumdaki arkadaşların da ilgisini çekeceğini ve kendi projelerini yapmak isteyebileceğini düşündüm. Denemek isteyen arkadaşlar için küçük bir rehber hazırlamak istedim.
1-Kullanılan Kütüphaneler
Mediapipe, OpenCV, Pynput.
MediaPipe: El iskeletini algılayıp parmakların açık/kapalı durumlarını analiz etmek için kullanıldı.
OpenCV: Gerçek zamanlı video akışını işlemek ve kullanıcı arayüzünü oluşturmak için kullanıldı.
Pynput: Klavye ve fare kontrollerini gerçekleştirmek için kullanıldı.
Kütüphaneleri yüklemek için terminalde şu komutu çalıştırın:
2- Kodun Yazımı
Adım 1: Kütüphanelerinin içe aktarımı
Bu kütüphaneler, el hareketlerini algılamak, klavye girdileri ve görüntü işlemek için gereklidir.
Adım 2: Mediapipe ve klavye kontrolleri
Mediapipe, el hareketlerini algılamak için pynput ise klavye kontrolleri için kullanılacak.
static_image_mode = false -> Hareketli bir görüntü akışı
Min_dedection_confidence=0.7 -> Düşük değerler gereksiz el algılaması yüksek değer ile bazı değerlerde algılamayı zorlaştırır bu nedenle %70 en dengeli seçenek oluyor.
Adım 3: Kamera Ayarları
Düşük çözünürlük kullanmamızın sebebi ne kadar yüksek çözünürlük o kadar yüksek işlemci kullanımı. Performansı düşürüyor.
Adım 4: Değişkenler
debounce_time = 0.5 -> Tuşların tekrarı için gerekli süre. Kısa süre istenmeyen tekrarları artırır, uzun süre ise geç algılanmasına sebep olur
Movement_threshold = 15 -> 15px Elin hareket ettiğini anlamak için gerekli minimum mesafe.
Required_stable_frames = 3 -> 3 ardışık çerçevede aynı hareketin algılanması gerekir.
Center_x_history = deque(maxlen = 5) -> El hareketini yumuşatarak daha stabil bir algılama sağlar
Adım 5: Görüntü işleme
cap.read() -> Kameradan bir görüntü alır
CV2.cvtColor -> OpenCV'nin BGR formatını MediaPipe için RGB formatına çevirir
Hands. Process -> Görüntüde el hareketleri tespiti yapar.
Adım 6: İşlemler
mp_draw. Draw_landmarks -> Algılanan elin iskeletini gösterir.
X_coords ve y_coords -> Elin yatay ve dikey sınırlarını bulmak için
Center_x -> Elin merkezini hesaplar
Center_x_history -> Hareketleri stabil hale getirmek için son birkaç çerçevenin ortalamasını alır.
Adım 7: Hareket yönü belirleme
if average_center_x > prev_center_x + movement_treshold:
Eğer elin yatay merkezi önceki merkeze göre "movement_treshold" (15 piksel) kadar sağa kaymışsa, bu hareket sağa doğru algılanır.
Stable_frame_count += 1
Eğer hareket algılanırsa bir artırılır. Hareketin birkaç çerçevede tutarlı şekilde algılanmasını sağlar.
İf stable_frame_count >= required_stable_frames
Eğer 3 ardıkış çerçevede hareket algılanırsa hareket stabil kabul edilir
Current_time - last_press_time > debounce_time:
Hareketin tekrar algılanmasını önlemek için kullanılır. İki hareket arasınad "debounce_time" (0.5 sec) kadar süre geçmeli.
Adım 8: Çıkış
3- Kapanış
Genel oluşturmayı açıkladığıma inanıyorum. Paylaşacağım kod daha kapsamlı ve stabilize, rehberde paylaştığım kod daha sade bir versiyon üzerinden oluşturuldu, Dikey hareketleri ihmal etmek için mekanizma vs. bulunmakta. İncelemek isteyen arkadaşlar için paylaştım.
Rehber kod:
Örnek kod:
Karanlık tema kullandığımdan dolayı bazı yazıların renklerini beyaz yapmıştım, açık temada gözükmüyor karanlık tema kullanmanız önerilir.
Kız arkadaşımın isteği üzerine, el hareketleriyle kitap sayfası çevirme programı yapmakla uğraşıyordum. Forumdaki arkadaşların da ilgisini çekeceğini ve kendi projelerini yapmak isteyebileceğini düşündüm. Denemek isteyen arkadaşlar için küçük bir rehber hazırlamak istedim.
1-Kullanılan Kütüphaneler
Mediapipe, OpenCV, Pynput.
MediaPipe: El iskeletini algılayıp parmakların açık/kapalı durumlarını analiz etmek için kullanıldı.
OpenCV: Gerçek zamanlı video akışını işlemek ve kullanıcı arayüzünü oluşturmak için kullanıldı.
Pynput: Klavye ve fare kontrollerini gerçekleştirmek için kullanıldı.
Kütüphaneleri yüklemek için terminalde şu komutu çalıştırın:
Kod:
pip install opencv-python mediapipe pynput
2- Kodun Yazımı
Adım 1: Kütüphanelerinin içe aktarımı
Python:
import cv2
import mediapipe as mp
from pynput.keyboard import Key, Controller
import time
from collections import deque
Bu kütüphaneler, el hareketlerini algılamak, klavye girdileri ve görüntü işlemek için gereklidir.
Adım 2: Mediapipe ve klavye kontrolleri
Mediapipe, el hareketlerini algılamak için pynput ise klavye kontrolleri için kullanılacak.
Python:
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
)
mp_draw = mp.solutions.drawing_utils
keyboard = Controller()
static_image_mode = false -> Hareketli bir görüntü akışı
Min_dedection_confidence=0.7 -> Düşük değerler gereksiz el algılaması yüksek değer ile bazı değerlerde algılamayı zorlaştırır bu nedenle %70 en dengeli seçenek oluyor.
Adım 3: Kamera Ayarları
Python:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
Düşük çözünürlük kullanmamızın sebebi ne kadar yüksek çözünürlük o kadar yüksek işlemci kullanımı. Performansı düşürüyor.
Adım 4: Değişkenler
Python:
debounce_time = 0.5
movement_threshold = 15
stable_frame_count = 0
required_stable_frames = 3
center_x_history = deque(maxlen=5)
debounce_time = 0.5 -> Tuşların tekrarı için gerekli süre. Kısa süre istenmeyen tekrarları artırır, uzun süre ise geç algılanmasına sebep olur
Movement_threshold = 15 -> 15px Elin hareket ettiğini anlamak için gerekli minimum mesafe.
Required_stable_frames = 3 -> 3 ardışık çerçevede aynı hareketin algılanması gerekir.
Center_x_history = deque(maxlen = 5) -> El hareketini yumuşatarak daha stabil bir algılama sağlar
Adım 5: Görüntü işleme
Python:
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Kamera çerçevesi yok!")
break
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(rgb_frame)
cap.read() -> Kameradan bir görüntü alır
CV2.cvtColor -> OpenCV'nin BGR formatını MediaPipe için RGB formatına çevirir
Hands. Process -> Görüntüde el hareketleri tespiti yapar.
Adım 6: İşlemler
Python:
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
x_coords = [lm.x for lm in hand_landmarks.landmark]
y_coords = [lm.y for lm in hand_landmarks.landmark]
h, w, _ = frame.shape
min_x = int(min(x_coords) * w)
max_x = int(max(x_coords) * w)
center_x = (min_x + max_x) // 2
center_x_history.append(center_x)
mp_draw. Draw_landmarks -> Algılanan elin iskeletini gösterir.
X_coords ve y_coords -> Elin yatay ve dikey sınırlarını bulmak için
Center_x -> Elin merkezini hesaplar
Center_x_history -> Hareketleri stabil hale getirmek için son birkaç çerçevenin ortalamasını alır.
Adım 7: Hareket yönü belirleme
Python:
if average_center_x > prev_center_x + movement_threshold:
stable_frame_count += 1
if stable_frame_count >= required_stable_frames and current_time - last_press_time > debounce_time:
keyboard.press(Key.right)
keyboard.release(Key.right)
last_press_time = current_time
stable_frame_count = 0
if average_center_x > prev_center_x + movement_treshold:
Eğer elin yatay merkezi önceki merkeze göre "movement_treshold" (15 piksel) kadar sağa kaymışsa, bu hareket sağa doğru algılanır.
Stable_frame_count += 1
Eğer hareket algılanırsa bir artırılır. Hareketin birkaç çerçevede tutarlı şekilde algılanmasını sağlar.
İf stable_frame_count >= required_stable_frames
Eğer 3 ardıkış çerçevede hareket algılanırsa hareket stabil kabul edilir
Current_time - last_press_time > debounce_time:
Hareketin tekrar algılanmasını önlemek için kullanılır. İki hareket arasınad "debounce_time" (0.5 sec) kadar süre geçmeli.
Adım 8: Çıkış
Python:
cv2.imshow("El Hareketleri Algilama", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
hands.close()
3- Kapanış
Genel oluşturmayı açıkladığıma inanıyorum. Paylaşacağım kod daha kapsamlı ve stabilize, rehberde paylaştığım kod daha sade bir versiyon üzerinden oluşturuldu, Dikey hareketleri ihmal etmek için mekanizma vs. bulunmakta. İncelemek isteyen arkadaşlar için paylaştım.
Rehber kod:
Python:
import cv2
import mediapipe as mp
from pynput.keyboard import Key, Controller
import time
from collections import deque
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
)
mp_draw = mp.solutions.drawing_utils
keyboard = Controller()
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
prev_center_x = None
last_press_time = 0
debounce_time = 0.5
movement_threshold = 15
stable_frame_count = 0
required_stable_frames = 3
center_x_history = deque(maxlen=5)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(rgb_frame)
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
x_coords = [lm.x for lm in hand_landmarks.landmark]
h, w, _ = frame.shape
min_x = int(min(x_coords) * w)
max_x = int(max(x_coords) * w)
center_x = (min_x + max_x) // 2
center_x_history.append(center_x)
average_center_x = sum(center_x_history) / len(center_x_history)
if prev_center_x is not None:
current_time = time.time()
if average_center_x > prev_center_x + movement_threshold:
stable_frame_count += 1
if stable_frame_count >= required_stable_frames and current_time - last_press_time > debounce_time:
keyboard.press(Key.right)
keyboard.release(Key.right)
last_press_time = current_time
stable_frame_count = 0
elif average_center_x < prev_center_x - movement_threshold:
stable_frame_count += 1
if stable_frame_count >= required_stable_frames and current_time - last_press_time > debounce_time:
keyboard.press(Key.left)
keyboard.release(Key.left)
last_press_time = current_time
stable_frame_count = 0
else:
stable_frame_count = 0
prev_center_x = average_center_x
cv2.imshow("Hand Tracking", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
hands.close()
Örnek kod:
Python:
import cv2
import mediapipe as mp
from pynput.keyboard import Key, Controller
import time
from collections import deque
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
)
mp_draw = mp.solutions.drawing_utils
keyboard = Controller()
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
prev_center_x = None
last_press_time = 0
debounce_time = 0.5
movement_threshold = 15
stable_frame_count = 0
required_stable_frames = 3
center_x_history = deque(maxlen=5)
prev_center_y = None
hand_detected = False
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(rgb_frame)
if results.multi_hand_landmarks:
hand_detected = True
for idx, hand_landmarks in enumerate(results.multi_hand_landmarks):
mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
x_coords = [lm.x for lm in hand_landmarks.landmark]
y_coords = [lm.y for lm in hand_landmarks.landmark]
h, w, _ = frame.shape
min_x = int(min(x_coords) * w)
max_x = int(max(x_coords) * w)
min_y = int(min(y_coords) * h)
max_y = int(max(y_coords) * h)
cv2.rectangle(frame, (min_x, min_y), (max_x, max_y), (255, 0, 0), 2)
center_x = (min_x + max_x) // 2
center_y = (min_y + max_y) // 2
if prev_center_y is not None and abs(center_y - prev_center_y) > 20:
prev_center_y = center_y
continue
cv2.circle(frame, (center_x, center_y), 5, (0, 255, 0), -1)
center_x_history.append(center_x)
average_center_x = sum(center_x_history) / len(center_x_history)
if prev_center_x is not None:
current_time = time.time()
if average_center_x > prev_center_x + movement_threshold:
stable_frame_count += 1
if stable_frame_count >= required_stable_frames and current_time - last_press_time > debounce_time:
cv2.putText(frame, "Saga hareket", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
keyboard.press(Key.right)
keyboard.release(Key.right)
last_press_time = current_time
stable_frame_count = 0
elif average_center_x < prev_center_x - movement_threshold:
stable_frame_count += 1
if stable_frame_count >= required_stable_frames and current_time - last_press_time > debounce_time:
cv2.putText(frame, "Sola hareket", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
keyboard.press(Key.left)
keyboard.release(Key.left)
last_press_time = current_time
stable_frame_count = 0
else:
stable_frame_count = 0
prev_center_x = average_center_x
prev_center_y = center_y
else:
if hand_detected:
prev_center_x = None
prev_center_y = None
center_x_history.clear()
stable_frame_count = 0
hand_detected = False
cv2.imshow("El Hareketleri Algilama", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
hands.close()
Karanlık tema kullandığımdan dolayı bazı yazıların renklerini beyaz yapmıştım, açık temada gözükmüyor karanlık tema kullanmanız önerilir.
Son düzenleme: