Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung |
pflegeruf [2022/06/23 20:45] – student | pflegeruf [2023/07/03 10:16] (aktuell) – Externe Bearbeitung 127.0.0.1 |
---|
| ====== Projekt: PflegeRuf ====== |
| |
| {{ :bamicapflegeruf.jpeg?400 |}} |
| |
| ===== Ziel & Funktion des PflegeRufs ===== |
| |
| ===Ziel:=== |
| Das Pflegepersonal in medizinischen Einrichtungen, wie Krankenhäusern oder Pflegeeinrichtungen, ist, |
| aufgrund des Mangels an Pflegepersonal, mit der intensiven und zeitaufwendigen Pflege der Patienten oder Bewohner stark überfordert. |
| Das System "PflegeRuf" soll das Pflegepersonal unterstützen und entlasten, indem die Patienten auswählen können, |
| **warum** Sie das Pflegepersonal zu sich ins Zimmer rufen möchten. Somit spart sich das Pflegepersonal kostbare Zeit und Energie, hin und her zu laufen, um erstmal den Grund für den Ruf zu erfahren und daraufhin die notwendigen Materialien zu holen, um dann wieder zurück zum Patienten zu gehen. |
| |
| ===Funktion:=== |
| Um den PflegeRuf nutzen zu können, muss der Patient die Gesichtserkennung nutzen, indem er das Gesicht zur Kamera hält, welche sich über dem Touch Display befindet. Die Kamera erkennt nur bereits vorher registrierte Nutzer. Unbekannte Gesichter werden mit der Bezeichnung "Unknown" nicht zur Nutzung des PflegeRufs zugelassen. |
| Nachdem der Patient erkannt wurde, öffnet sich der PflegeRuf. Hier gibt es 3 Auswahlmöglichkeiten (//siehe Bild oben//). |
| - Entweder kann der Patient das Pflegepersonal rufen und ein bestimmtes Anliegen auswählen. Nachdem einer der Button angeklickt wurde, erhält das Pflegepersonal sofort eine Email mit dem ausgewählten Grund für den Ruf. Folgende Anliegen können auf der grafischen Benutzeroberfläche ausgewählt werden: |
| * Schmerzen {{ :pflegerufanliegen.jpeg?300|}} |
| * Medikamente |
| * WC |
| * Waschen |
| * Essen |
| * Getränke |
| * TV |
| - (2) Zusätzlich kann der Patient eigenständig seinen Puls messen. Sobald der Button "Puls messen" betätigt wird, startet die Messung. Auf dem kleineren Display unter dem großen Display wird dem Patienten angezeigt, wann die Messung startet und wann es fertig ist. Sobald die Messung vollendet ist, erscheint eine Grafik mit der Herzschlag des Patienten. Wenn der Wert zu hoch oder zu niedrig ist, erhält auch hier das Pflegepersonal ebenfalls eine E-Mail mit einer Warnung. |
| - (3) Zu guter Letzt kann der Patient, falls Langeweile besteht, mit dem Zimmergenosse "TicTacToe" spielen. Der Gewinner wird auf dem kleinen Display angezeigt. |
| |
| |
| ===== Diese Bauteile wurden verwendet: ===== |
| * Raspberry Pi 4 B |
| * (Half-Size) Breadboard --> darauf: MCP 3008 A/D Wandler |
| * Jumper Kabel |
| * KY-039 Herzschlagsensor |
| * RASPBERRY PI 7TD Raspberry Pi Shield - Display LCD-Touch, 7", 800x480 Pixel |
| * I2C LCD Display |
| * Raspberry Pi Camera Module V2 |
| |
| ===== Beschreibung des Quellcodes ===== |
| ==== Gesichtserkennung ==== |
| //Der Vorgang zur Einrichtung der Gesichtserkennung, sowie der Quellcode mit Ausnahme Zeile 78-80, sowie Zeile 113-114, wurden aus folgendem Tutorial entnommen und kann dort ausführlich nachgelesen werden: [[https://core-electronics.com.au/guides/face-identify-raspberry-pi/]] // |
| Um die Gesichtserkennung starten zu können musste OpenCV installiert werden und eine haarcascade_frontalface.xml Datei aus dem Internet heruntergeladen werden für das Erkennen von Gesichtern. |
| Wir haben mindestens 10 Fotos von unseren Gesichtern aufgenommen und diese in einem Ordner gespeichert. Auf diesen Ordner wird zugegriffen und während der Videoaufnahme erscheint der Name des Ordners und somit der Name der Person. |
| |
| <file python facial_req.py> |
| <#!/usr/bin/python3 |
| |
| # import the necessary packages |
| from imutils.video import VideoStream |
| from imutils.video import FPS |
| import face_recognition |
| import imutils |
| import pickle |
| import time |
| import cv2 |
| import RPi.GPIO as GPIO |
| from time import sleep |
| import subprocess |
| import sys |
| |
| #Initialize 'currentname' to trigger only when a new person is identified. |
| currentname = "unknown" |
| #Determine faces from encodings.pickle file model created from train_model.py |
| encodingsP = "encodings.pickle" |
| |
| # load the known faces and embeddings along with OpenCV's Haar |
| # cascade for face detection |
| print("[INFO] loading encodings + face detector...") |
| data = pickle.loads(open(encodingsP, "rb").read()) |
| |
| # initialize the video stream and allow the camera sensor to warm up |
| # Set the ser to the followng |
| # src = 0 : for the build in single web cam, could be your laptop webcam |
| # src = 2 : I had to set it to 2 inorder to use the USB webcam attached to my laptop |
| #vs = VideoStream(src=2,framerate=10).start() |
| vs = VideoStream(usePiCamera=True).start() |
| time.sleep(2.0) |
| |
| # start the FPS counter |
| fps = FPS().start() |
| |
| # loop over frames from the video file stream |
| while True: |
| # grab the frame from the threaded video stream and resize it |
| # to 500px (to speedup processing) |
| frame = vs.read() |
| frame = imutils.resize(frame, width=500) |
| # Detect the fce boxes |
| boxes = face_recognition.face_locations(frame) |
| # compute the facial embeddings for each face bounding box |
| encodings = face_recognition.face_encodings(frame, boxes) |
| names = [] |
| |
| # loop over the facial embeddings |
| for encoding in encodings: |
| # attempt to match each face in the input image to our known |
| # encodings |
| matches = face_recognition.compare_faces(data["encodings"], |
| encoding) |
| name = "Unknown" #if face is not recognized, then print Unknown |
| |
| # check to see if we have found a match |
| if True in matches: |
| # find the indexes of all matched faces then initialize a |
| # dictionary to count the total number of times each face |
| # was matched |
| matchedIdxs = [i for (i, b) in enumerate(matches) if b] |
| counts = {} |
| |
| # loop over the matched indexes and maintain a count for |
| # each recognized face face |
| for i in matchedIdxs: |
| name = data["names"][i] |
| counts[name] = counts.get(name, 0) + 1 |
| |
| # determine the recognized face with the largest number |
| # of votes (note: in the event of an unlikely tie Python |
| # will select first entry in the dictionary) |
| name = max(counts, key=counts.get) |
| #If someone in your dataset is identified, print their name on the screen |
| if currentname != name: |
| currentname = name |
| cmd = 'python3 pflegeRuf.py' |
| p = subprocess.Popen(cmd, shell=True) |
| sys.exit().sys.exit() |
| |
| |
| # update the list of names |
| names.append(name) |
| |
| |
| |
| # loop over the recognized faces |
| for ((top, right, bottom, left), name) in zip(boxes, names): |
| # draw the predicted face name on the image - color is in BGR |
| cv2.rectangle(frame, (left, top), (right, bottom), |
| (0, 255, 225), 2) |
| y = top - 15 if top - 15 > 15 else top + 15 |
| cv2.putText(frame, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX, |
| .8, (0, 255, 255), 2) |
| |
| # display the image to our screen |
| cv2.imshow("Facial Recognition is Running", frame) |
| key = cv2.waitKey(1) & 0xFF |
| |
| # quit when 'q' key is pressed |
| if key == ord("q"): |
| break |
| |
| # update the FPS counter |
| fps.update() |
| |
| # stop the timer and display FPS information |
| fps.stop() |
| print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) |
| print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) |
| |
| if currentname != name: |
| sys.exit().sys.exit() |
| cv2.destroyAllWindows() |
| vs.stop() |
| > |
| </file> |
| |
| ---- |
| |
| === Graphische Benutzeroberfläche === |
| Die Graphische Benutzeroberfläche wurde mit dem GUI-Framework PysimpleGui erstellt. Jede Zeile mit den []-Klammern erweitert das Display und ermöglicht das Hinzufügen von den gewünschten Elementen wie z.B. Button, Bilder, Text, Input Felder und vieles mehr. |
| Um "Image Buttons" erstellen zu können, müssen Bilder (png oder jpeg) vorher zu Base_64 konvertiert und im Quellcode als Variable hinzugefügt werden. Erst dann können die Bilder als Button genutzt werden. Nachdem ein Anliegen ausgewählt wurde, erscheint für 4 Sekunden ein Pop up Fenster, welches sich automatisch wieder schließt. |
| Zusätzlich werden E-Mails verschickt, indem der Email Sender und Empfänger, sowie ein Passwort für die externe Nutzung durch weniger gesicherte Apps, notiert werden. |
| <file python pflegeRuf.py> |
| <#!/usr/bin/python3 |
| import PySimpleGUI as sg |
| import smtplib |
| import os |
| from email.message import EmailMessage |
| import ssl |
| import subprocess |
| import RPi.GPIO as GPIO |
| import time |
| |
| email_sender = 'melaley98@gmail.com' |
| email_password = 'ddvpqksaxtxvhlne' |
| email_receiver = 'pflegepersonal98@gmail.com' |
| |
| |
| |
| schmerzen_base64 = b'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 |