Skip to content

Commit

Permalink
remove Connection class, fix threads
Browse files Browse the repository at this point in the history
  • Loading branch information
kzaleskaa committed Jan 17, 2022
1 parent 53a6424 commit 6c0f69b
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 132 deletions.
70 changes: 0 additions & 70 deletions Connection.py

This file was deleted.

32 changes: 17 additions & 15 deletions GUI/DetectionWindow.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@
# Katarzyna Zaleska
# WCY19IJ1S1
from threading import Thread

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import pyqtSlot, pyqtSignal
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QDialog

from Connection import Connection
from GestureRecognition import GestureRecognition
from queue import Queue
from pyui.DetectionWindow import Ui_DetectionWindow


class DetectionWindow(QDialog, Ui_DetectionWindow):
"""The class represents detection window of GUI."""

def __init__(self):
"""DetectionWindow constructor"""
super().__init__()
self.token = ""
self.setupUi(self)
self.connection = Connection(self)
self.token = ""
self._connect_buttons()
self.queue = Queue()
self.detection = GestureRecognition()

def _connect_buttons(self) -> None:
"""Function connects button with its action."""
self.pushButton_2.clicked.connect(self.connection_action)

def connection_action(self) -> None:
self.connection.change_gesture_name.connect(self.update_gesture_name)
self.connection.change_confidence.connect(self.update_confidence)
self.connection.change_image.connect(self.update_image)
self.connection.token = self.token
self.connection.started.connect(self.connection.start_detection)
self.connection.start()

def destroy_thread(self):
self.connection.quit()
self.connection = None
self.detection.change_image.connect(self.update_image)
self.detection.change_confidence.connect(self.update_confidence)
self.detection.change_gesture_name.connect(self.update_gesture_name)
self.detection.add_gesture.connect(self.add_gesture)
self.detection.token = self.token
self.detection.start()

@pyqtSlot(str)
def update_confidence(self, confidence: str) -> None:
Expand Down Expand Up @@ -62,3 +60,7 @@ def update_image(self, image: QImage) -> None:
image (QImage): converted frame from camera
"""
self.detection_camera.setPixmap(QPixmap.fromImage(image))

@pyqtSlot(str)
def add_gesture(self, gesture_name: str) -> None:
self.q.put(gesture_name)
50 changes: 26 additions & 24 deletions GestureRecognition.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
# Katarzyna Zaleska
# WCY19IJ1S1

from queue import Queue
import typing
from typing import Type

import cv2
import mediapipe as mp
import numpy as np
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtCore import Qt, pyqtSignal, QThread, QObject
from PyQt5.QtGui import QImage
from keras.models import load_model
from mediapipe.python.solutions.holistic import Holistic

from Spotify import SpotifyAPI
from constants import ACTIONS, THRESHOLD


class GestureRecognition:
class GestureRecognition(QThread):
"""The class represents gesture recognition based on image from camera and created model."""
change_image = pyqtSignal(QImage)

def __init__(self, model_name: str) -> None:
def __init__(self, model_name: str="model/nadzieja.h5") -> None:
"""HandDetectionModel constructor.
Args:
parent(typing.Optional[QObject]): pass
model_name (str): file name to load the model
"""
super().__init__()
self.mp_holistic = mp.solutions.holistic
self.mp_drawing = mp.solutions.drawing_utils
self.cap = cv2.VideoCapture(0)
self.model_name = model_name
self.gesture = None
self.confidence = None
self.token = ""

change_gesture_name = pyqtSignal(str)
change_confidence = pyqtSignal(str)
change_image = pyqtSignal(QImage)
add_gesture = pyqtSignal(str)

def hand_prediction(self, frame: np.ndarray, model: Holistic) -> Type:
"""Function makes prediction based on holistic model
Expand Down Expand Up @@ -91,17 +95,14 @@ def convert_image(self, image: np.ndarray) -> QImage:
scaled_image = converted_image.scaled(600, 600, Qt.KeepAspectRatio)
return scaled_image

def detect_gestures(self, output_gesture: Queue[str], change_image) -> None:
"""Function detect gestures based on image from camera and add detected gesture's name to the queue.
Args:
output_gesture (Queue[str]): queue to save detected gesture' information
change_image (): pass
"""
def detect_gestures(self) -> None:
"""Function detect gestures based on image from camera and add detected gesture's name to the queue."""
landmarks_from_frame = []

model = load_model(self.model_name)

spotify = SpotifyAPI(token=self.token)

with self.mp_holistic.Holistic(min_detection_confidence=0.5, min_tracking_confidence=0.5) as holistic:
while self.cap.isOpened():

Expand All @@ -115,7 +116,7 @@ def detect_gestures(self, output_gesture: Queue[str], change_image) -> None:

self.create_landmarks(frame, results)

change_image.emit(self.convert_image(frame))
self.change_image.emit(self.convert_image(frame))

landmarks = self.save_landmarks(results)

Expand All @@ -131,13 +132,11 @@ def detect_gestures(self, output_gesture: Queue[str], change_image) -> None:
max_prediction_index = np.argmax(prediction)

if prediction[max_prediction_index] > THRESHOLD:
self.confidence = prediction[max_prediction_index]
self.gesture = ACTIONS[max_prediction_index]
gesture_info = {
"gesture": self.gesture,
"confidence": str(round(self.confidence*100, 2)),
}
output_gesture.put(gesture_info)
confidence = prediction[max_prediction_index]
gesture = ACTIONS[max_prediction_index]
self.change_gesture_name.emit(gesture)
spotify.gesture_action(gesture)
self.change_confidence.emit(str(round(confidence*100, 2)))
landmarks_from_frame = []

cv2.waitKey(10)
Expand All @@ -147,3 +146,6 @@ def detect_gestures(self, output_gesture: Queue[str], change_image) -> None:

self.cap.release()
cv2.destroyAllWindows()

def run(self):
self.detect_gestures()
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
<img src="https://user-images.githubusercontent.com/62251989/149663561-90e99712-58a9-40c6-9822-69a7092d582b.png" alt="Spotify Gesture Controller logo"/>
</div>


##Credits
## Credits
- Heart photo created by nakaridore - [Freepik](www.freepik.com)
31 changes: 19 additions & 12 deletions Spotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def __init__(self, client_id: str = "", client_secret: str = "", token: str = ""
token (str): represents the authorization
redirect_uri (str): after user approves, where do we send them back to?
"""
super(SpotifyAPI, self).__init__()
self.client_id = client_id
self.client_secret = client_secret
self.redirect_uri = redirect_uri
Expand Down Expand Up @@ -50,7 +51,6 @@ def get_playback_state(self) -> dict:
return info
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def skip_to_previous(self) -> None:
"""Function skip to previous track"""
Expand All @@ -59,7 +59,6 @@ def skip_to_previous(self) -> None:
requests.post(endpoint, headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music or restart app...")

def skip_to_next(self) -> None:
"""Function skip to next track"""
Expand All @@ -68,7 +67,6 @@ def skip_to_next(self) -> None:
requests.post(endpoint, headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def change_playing_status(self) -> None:
"""Function starts play or pauses music based on current status."""
Expand All @@ -81,7 +79,6 @@ def change_playing_status(self) -> None:
self.start_playback()
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def pause_playback(self) -> None:
"""Function pauses playing track"""
Expand All @@ -90,7 +87,6 @@ def pause_playback(self) -> None:
requests.put(endpoint, headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def start_playback(self) -> None:
"""Function starts playing paused track"""
Expand All @@ -99,7 +95,6 @@ def start_playback(self) -> None:
requests.put(endpoint, headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def volume_down(self) -> None:
"""Function changes current volume <- current_volume - step """
Expand All @@ -112,7 +107,6 @@ def volume_down(self) -> None:
requests.put(f"{endpoint}{volume}", headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def volume_up(self) -> None:
"""Function changes current volume <- current_volume + step """
Expand All @@ -125,7 +119,6 @@ def volume_up(self) -> None:
requests.put(f"{endpoint}{volume}", headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def fav_track(self) -> None:
"""Function checks if current track is in the list of saved track and save or remove it from this list."""
Expand All @@ -141,7 +134,6 @@ def fav_track(self) -> None:
self.save_track(current_track_id)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def saved_tracks_id(self) -> list[str]:
"""Function creates list of saved tracks' id"""
Expand All @@ -158,7 +150,6 @@ def saved_tracks_id(self) -> list[str]:
return items_id
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def save_track(self, current_track_id: str) -> None:
"""Function adds track to saved playlist.
Expand All @@ -171,7 +162,6 @@ def save_track(self, current_track_id: str) -> None:
requests.put(f"{endpoint}{current_track_id}", headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def remove_track(self, current_track_id: str) -> None:
"""Function removes currently playing track from saved playlist.
Expand All @@ -184,5 +174,22 @@ def remove_track(self, current_track_id: str) -> None:
requests.delete(f"{endpoint}{current_track_id}", headers=self.headers)
except Exception as e:
print(f"Exception: {e}")
print("Open spotify and start play music...")

def gesture_action(self, gesture: str) -> None:
"""Function makes action based on gesture name from input_gesture queue.
Args:
gesture (str): name of detected gesture
"""
if gesture == "next":
self.skip_to_next()
elif gesture == "prev":
self.skip_to_previous()
elif gesture == "love":
self.fav_track()
elif gesture == "louder":
self.volume_up()
elif gesture == "quieter":
self.volume_down()
elif gesture == "play_pause":
self.change_playing_status()
18 changes: 9 additions & 9 deletions pyui/DetectionWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ def retranslateUi(self, DetectionWindow):
self.detection_confidence.setText(_translate("DetectionWindow", "<html><head/><body><p><br/></p></body></html>"))
self.pushButton_2.setText(_translate("DetectionWindow", "START"))


if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
DetectionWindow = QtWidgets.QDialog()
ui = Ui_DetectionWindow()
ui.setupUi(DetectionWindow)
DetectionWindow.show()
sys.exit(app.exec_())
#
# if __name__ == "__main__":
# import sys
# app = QtWidgets.QApplication(sys.argv)
# DetectionWindow = QtWidgets.QDialog()
# ui = Ui_DetectionWindow()
# ui.setupUi(DetectionWindow)
# DetectionWindow.show()
# sys.exit(app.exec_())

0 comments on commit 6c0f69b

Please sign in to comment.