File: mp.py

package info (click to toggle)
kuttypy 2.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 37,896 kB
  • sloc: python: 58,651; javascript: 14,686; xml: 5,767; ansic: 2,716; makefile: 453; asm: 254; sh: 48
file content (102 lines) | stat: -rw-r--r-- 4,079 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from typing import List

import cv2
import mediapipe as mp
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QLabel, QDialog, QVBoxLayout
from PyQt5.QtGui import QImage, QPixmap
import sys,time

# Initialize MediaPipe
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands


class HandLandmarkThread(QThread):
    change_pixmap_signal = pyqtSignal(QImage)
    coordinates_signal = pyqtSignal(list)  # Signal to emit coordinates
    cameraReadySignal = None
    dead_signal = pyqtSignal()  # Signal to emit coordinates
    running = True
    last_query_time = time.time()

    def __init__(self, parent = None):
        super().__init__(parent)

    def setCameraReadySignal(self,sig):
        self.cameraReadySignal = sig

    def stopRunning(self):
        self.running = False
    def run(self):
        # Start video capture (use 0 for the default webcam)
        self.last_query_time = time.time()
        cap = cv2.VideoCapture(0)
        with mp_hands.Hands(
            model_complexity=0,
            min_detection_confidence=0.5,
            min_tracking_confidence=0.5
        ) as hands:
            st = time.time()
            print('cam started',st)
            self.cameraReadySignal.emit()
            while cap.isOpened() and self.running:
                if time.time() > self.last_query_time+5: # No activity for 5 seconds.
                    self.running = False
                success, image = cap.read()
                if not success:
                    continue

                # Convert image to RGB for processing
                image.flags.writeable = False
                image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
                results = hands.process(image_rgb)

                # Draw hand landmarks and emit the coordinates
                image.flags.writeable = True
                image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
                if results.multi_hand_landmarks:
                    for hand_landmarks in results.multi_hand_landmarks:
                        self.last_query_time = time.time()
                        mp_drawing.draw_landmarks(
                            image_bgr,
                            hand_landmarks,
                            mp_hands.HAND_CONNECTIONS,
                            mp_drawing_styles.get_default_hand_landmarks_style(),
                            mp_drawing_styles.get_default_hand_connections_style()
                        )
                        # Emit the coordinates of the index finger tip
                        image_height, image_width, _ = image.shape
                        #index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
                        #coords = (index_finger_tip.x * image_width, index_finger_tip.y * image_height)
                        # Get coordinates for all landmarks
                        hand_coords = []
                        for landmark in hand_landmarks.landmark:
                            x = landmark.x * image_width
                            y = landmark.y * image_height
                            hand_coords.append((x, y))
                        self.coordinates_signal.emit(hand_coords)
                        break #only need one hand for now.

                # Convert to QImage and emit signal to update the UI
                qt_image = self.convert_cv_qt(image_bgr)
                self.change_pixmap_signal.emit(qt_image)

                if (not self.running):  # Close
                    break

        cap.release()
        self.dead_signal.emit()

    def convert_cv_qt(self, cv_img):
        """Convert from an OpenCV image to QImage for display."""
        rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        qt_image = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888)
        return qt_image

    def ping(self):
        self.last_query_time = time.time()