Rehber Python kullanarak el ile bilgisayar kontrolü

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:

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

Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.

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:
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için çerezleri kabul etmelisiniz. Daha Fazlasını Öğren.…