Compare commits

...

37 Commits

Author SHA1 Message Date
368d686e21 Dateien hochladen nach „“ 2024-02-14 16:26:08 +00:00
d065c58ab2 „recording.py“ löschen 2024-02-14 16:25:52 +00:00
fa23410c8d „author_contribution.md“ löschen 2024-02-14 16:25:48 +00:00
d79fd5e427 „README.md“ löschen 2024-02-14 16:25:44 +00:00
1c5afb9e45 „code/videos“ löschen 2024-02-14 16:24:32 +00:00
6b0b8274ad qewr 2024-02-14 16:24:13 +00:00
5d5a9077a9 Dateien hochladen nach „code“ 2024-02-14 16:23:39 +00:00
4b6f98fbec Dateien hochladen nach „code“ 2024-02-14 16:23:29 +00:00
a0d57e4cd8 „code/facedetection2.py“ löschen 2024-02-14 16:23:18 +00:00
38475f3457 „code/facedetection1.py“ löschen 2024-02-14 16:23:14 +00:00
3154a5cd3c „code/facedetection.py“ löschen 2024-02-14 16:23:08 +00:00
406505af6b „code/recording.py“ löschen 2024-02-14 16:23:02 +00:00
5b76520bbb Dateien hochladen nach „code“ 2024-02-14 16:22:42 +00:00
c4267cce7a Dateien hochladen nach „code“ 2024-02-14 16:22:36 +00:00
15cf3cf5d9 Dateien hochladen nach „code“ 2024-02-14 16:22:27 +00:00
6cfc8baac8 Dateien hochladen nach „“
Dateipfade angepasst, jetzt wie test recording
2024-02-14 16:21:48 +00:00
1340b94b0e Dateien hochladen nach „code“ 2024-02-14 16:20:06 +00:00
f707b8474b „constants.py“ löschen 2024-02-14 16:19:43 +00:00
55d66b05fe „doc.md“ löschen 2024-02-14 16:19:34 +00:00
cf1c4ce07c „eulerian.py“ löschen 2024-02-14 16:19:30 +00:00
40aa48c860 „excel_evaluation.py“ löschen 2024-02-14 16:19:26 +00:00
438240cc9a „excel_processing.py“ löschen 2024-02-14 16:19:23 +00:00
453fd4035d „requirements.txt“ löschen 2024-02-14 16:19:19 +00:00
82dbafdf94 „excel_update.py“ löschen 2024-02-14 16:19:13 +00:00
c65c015b64 Dateien hochladen nach „“
Habe nochmal Dateipfade anpassen müssen, jetzt läuft alles final
2024-02-14 16:18:22 +00:00
343a52f170 Dateien hochladen nach „code“ 2024-01-13 14:09:51 +00:00
0a0b013f84 Dateien hochladen nach „code“ 2024-01-13 14:09:10 +00:00
6f811dd0ae Push des funktionierenden Codes 2024-01-13 14:08:30 +00:00
aaf1b6add8 „README.md“ ändern 2024-01-11 19:58:58 +00:00
2dd385684c information tbd! 2024-01-11 19:54:02 +00:00
2dcf76ce67 noch nicht fertig! 2024-01-11 19:35:47 +00:00
3b465ce763 Button für Testauswertung hinzugefügt 2024-01-11 19:17:19 +00:00
7f94258a99 „README.md“ ändern
Projektbeschreibung und Anleitung ergänzt
2024-01-11 13:38:05 +00:00
b6c3ff5a42 changed tkinter to tk 2024-01-11 13:02:32 +00:00
db476fbce2 Testauswertung zusammengeführt und in den Testablauf integriert
In excel_processing habe ich nur den Funktionsaufruf der Evaluation hinzugefügt, die evaluation enthält die Funktionalitäten aus dem Testauswertung-Ordner
2024-01-11 12:52:43 +00:00
7c2c8f1b4d Dateien hochladen nach „Testauswertung“
Ich habs noch nicht sinnvoll zusammengeführt, mach ich noch. Zuerst zusammenführen, dann Abweichung berechnen, dann umstrukturieren
Außerdem hab ich es probeweise nicht im ordner mit der original excel ausgeführt, um im Fehlerfall nicht neu berechnen zu müssen
Da es aber alles funktioniert würde ich das Programm wenn es fertig ist in den Ordner mit den excel files packen
2024-01-09 18:15:54 +00:00
7704a34b1c test case record gefixxt und alte facedetect hinzugefügt 2024-01-04 14:13:28 +01:00
23 changed files with 752 additions and 266 deletions

View File

@ -1,21 +1,19 @@
# Driving Simulator Team Video # Driving Simulator Team Video
## Projektbeschreibung ## Projektbeschreibung
ToDo Dieser Code ermittelt die Herzfrequenz einer Person anhand eines aufgenommenen Videos von deren Gesicht auf Basis des Eulerian Video Magnification (EVM) Verfahrens. Desweiteren ist ein Interface enthalten, das neben der Steuerung des Programms auch einen Testing-Modus zulässt.
## Installation ## Installation
pip install -r requirements.txt pip install -r requirements.txt
## Verwendung
## Verwendung Wenn ein fertiges feature in den Master Branch gemerged wird muss die code_version variable in der main.py inkrementiert werden. Für kleine features wird die nachkomma stelle inkrementiert, bei großen features wird die vorkomma stelle erhöht und die nachkomma stelle auf 0 gesetzt.
Wenn ein fertiges feature in den Master Branch gemerged wird muss die code_version variable in der main.py inkrementiert werden. Für kleine features wird die nachkomma stelle inkrementiert, bei großen features wird die vorkomma stelle erhöht und die nachkomma stelle auf 0 gesetzt.
ToDo ## Bedienungsanleitung
(ergänzen welche sachen nicht gepusht werden müssen) **Recording**: Aufösung und fps der verwendeten Kamera müssen eingetragen werden, ebenso der gewünschte Videoname. Videos beliebiger Länge können über "Aufnahme starten/stoppen" aufgezeichnet werden.
## Beiträge **Processing**: Über das Textfenster oder den Button "Video auswählen" kann das auszuwertende Video gewählt werden. Der Button "Verarbeiten" startet die Pulsberechnung, deren Ergebnis im Terminal ausgegeben wird.
ToDo **Create Testcase**: Solange das Programm noch nicht final ist, ist es mit einem Testing-Modus ausgestattet. Die eizustellenden Parameter entsprechen möglichen Einflüssen auf die Berechnung und sollten im Entwicklungsverlauf entsprechend der Testergebnisse angepasst werden. Der Button "Testcase aufnehmen" startet die Aufnahme, die nach der zuvor eingetragenen Zeit stoppt. Das Video wird gespeichert und in der Testcases-Excel-Datei wird ein entsprechender neuer Antrag angelegt.
**Testing**: Die Buttons "Open Testcase/-run Excel" öffnen die jeweiligen Excel-Tabellen. Der Button "Test durchführen" startet die Auswertung aller in der Testcases-Excel-Datei aufgelisteten Videos und trägt die Ergebnisse in die Testrun-Excel-Datei ein. Anschließend wird eine nach Genauigkeit der Auswertung sortierte Kopie der Testcases-Excel-Datei erstellt.
## Lizenz
ToDo ## Beiträge
Siehe author_contribution.md
## Danksagungen
ToDo

View File

@ -0,0 +1,57 @@
import openpyxl
def lese_zwei_spalten(file_path):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Lese die Werte der beiden Spalten aus
values_column1 = [cell.value for cell in sheet['O']][1:]
values_column2 = [cell.value for cell in sheet['Q']][1:]
# Schließe die Excel-Datei
workbook.close()
return values_column1, values_column2
def berechne_prozentuale_abweichung(liste1, liste2):
# Überprüfe, ob die Listen die gleiche Länge haben
if len(liste1) != len(liste2):
raise ValueError("Die Listen müssen die gleiche Länge haben")
# Berechne die prozentuale Abweichung zwischen den Werten
abweichungen = [((abs(float(b) - float(a)) / float(a)) * 100) if float(a) != 0 else None for a, b in zip(liste1, liste2)]
return abweichungen
def write_string_to_excel(file_path, input_string, column):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Trage jeden Buchstaben des Strings in eine eigene Zeile ein
for i, char in enumerate(input_string, 1):
sheet.cell(row=2 + i - 1, column=column, value=char)
# Speichere die Änderungen
workbook.save(file_path)
# Schließe die Excel-Datei
workbook.close()
# Funktionsaufruf
values_col1, values_col2 = lese_zwei_spalten('Testcase_excel_dataset.xlsx')
print(values_col1)
print(values_col2)
abweichungen = berechne_prozentuale_abweichung(values_col1, values_col2)
write_string_to_excel('Testcase_excel_dataset.xlsx', abweichungen, 18)

View File

@ -0,0 +1,42 @@
import openpyxl
def kopiere_header(input_sheet, output_sheet):
# Kopiere den Header manuell in das Ausgabe-Arbeitsblatt
for row in input_sheet.iter_rows(min_row=1, max_row=1, values_only=True):
output_sheet.append(row)
def sortiere_excel_tabelle(input_file_path, output_file_path, ):
# Öffne die Eingabe-Excel-Datei
input_workbook = openpyxl.load_workbook(input_file_path)
input_sheet = input_workbook['Sheet1']
# Erstelle eine neue Excel-Tabelle für die sortierten Zeilen
output_workbook = openpyxl.Workbook()
output_sheet = output_workbook.active
# Kopiere den Header ins Ausgabe-Arbeitsblatt
kopiere_header(input_sheet, output_sheet)
# Lese die Daten-Zeilen aus der Tabelle
data_rows = list(input_sheet.iter_rows(min_row=2, values_only=True))
# Sortiere die Daten-Zeilen nach dem Wert der angegebenen Spalte
sorted_data_rows = sorted(data_rows, key=lambda x: x[18 - 1]) # -1, da Listenindizes bei 0 beginnen
# Schreibe die sortierten Daten-Zeilen in die neue Tabelle
for row in sorted_data_rows:
output_sheet.append(row)
# Speichere die Änderungen in der neuen Excel-Datei
output_workbook.save(output_file_path)
# Schließe die Excel-Dateien
input_workbook.close()
output_workbook.close()
# Beispielaufruf
input_file_path = 'Testcase_excel_dataset.xlsx'
output_file_path = 'Testcases_nach_Genauigkeit.xlsx'
sortiere_excel_tabelle(input_file_path, output_file_path)

View File

@ -0,0 +1,52 @@
import openpyxl
def excel_row_to_string(file_path):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Erhalte die angegebene Zeile als Liste von Zellen
row_values = [cell.value for cell in sheet[2]]
# Ergebnisse werden ab Spalte 5 eingetragen
selected_columns = list(range(4, len(row_values)))
# Wähle nur die gewünschten Spalten aus
selected_values = [row_values[col] for col in selected_columns]
# Schließe die Excel-Datei
workbook.close()
# Konvertiere die Liste von Zellen in einen String
row_string = ', '.join(str(value) for value in selected_values)
return row_string
def write_string_to_excel(file_path, input_string):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Teile den String nach jedem Komma auf
parts = input_string.split(',')
# Trage jeden Teil des Strings in eine neue Zeile ein
for i, part in enumerate(parts, 1):
sheet.cell(row=2 + i - 1, column=17, value=part.strip()) # strip entfernt mögliche Leerzeichen
# Speichere die Änderungen
workbook.save(file_path)
# Schließe die Excel-Datei
workbook.close()
# Funktionsaufrufe
input_string = excel_row_to_string('Testruns.xlsx')
write_string_to_excel('Testcase_excel_dataset.xlsx', input_string)

View File

@ -1,85 +1,112 @@
# Author Contribution Team Video # Author Contribution Team Video
## Authors ## Authors
### Roberto Gelsinger ### Roberto Gelsinger
- Contribution: Algorithm development, Python Code - Contribution: Algorithm development, Python Code
- Email: gelsingerro81137@th-nuernberg.de - Email: gelsingerro81137@th-nuernberg.de
### Jonathan Frei
## Contribution - Contribution: Algorithm Development, Python Code, Testing
- Email: freijo85382@th-nuernberg.de
### Roberto Gelsinger
## Contribution
#### General Contributen
- **Creating README.md** ### Roberto Gelsinger
- **Creating requiremenents.txt**
- **Creating author_contribution.md structure** #### General Contributen
- **Added Docstrings to the code** - **Creating README.md structure**
- **Creating the Trello Agile Kanban Board and updating Team Video Tasks** - **Creating requiremenents.txt**
- **Creating author_contribution.md structure**
#### Code Contribution - **Added Docstrings to the code**
- **facedetection.py** - **Creating the Trello Agile Kanban Board and updating Team Video Tasks**
- Developed face and forehead detection using OpenCV.
#### Code Contribution
- **heartrate.py** - **facedetection.py**
- Implemented and optimized the heart rate calculation using SciPy - Developed face and forehead detection using OpenCV.
- **main.py** - **heartrate.py**
- Created user interface using Tkinter for recording, processing and testing porpuses. - Implemented and optimized the heart rate calculation using SciPy
- Connected all functionalities of the code to create a effective testing environment
- **main.py**
- **processing.py** - Created user interface using Tkinter for recording, processing and testing porpuses.
- Handled video data processing and applied image processing algorithms. - Connected all functionalities of the code to create a effective testing environment
- Collaborated in the development of video manipulation techniques for analysis.
- **processing.py**
- **pyramids.py** - Handled video data processing and applied image processing algorithms.
- Constructed image pyramids and performed image analysis. - Collaborated in the development of video manipulation techniques for analysis.
- Employed computer vision techniques for feature extraction and manipulation.
- **pyramids.py**
- **recording.py** - Constructed image pyramids and performed image analysis.
- Implemented video recording functionalities. - Employed computer vision techniques for feature extraction and manipulation.
- Developed modules for media file management and real-time video capture using threading.
- **recording.py**
- **constants.py** - Implemented video recording functionalities.
- Established global constants and configuration parameters. - Developed modules for media file management and real-time video capture using threading.
- Defined critical frequency and alpha value parameters for system-wide use.
- **constants.py**
- **eulerian.py** - Established global constants and configuration parameters.
- Applies the maginfication alpha to the signal - Defined critical frequency and alpha value parameters for system-wide use.
- **eulerian.py**
- **excel_processing.py** - Applies the maginfication alpha to the signal
- Is used to create test cases and prcoess the value for the test case
- Values and input is saved to a excel
- **excel_processing.py**
- **excel_update.py** - Is used to create test cases and prcoess the value for the test case
- Creates entry in testrun excel file - Values and input is saved to a excel
- Calculates the deviation and colors the excel cells.
- Calculates the deviation for each test case and adds a overall deviation for the test run - **excel_update.py**
- Creates entry in testrun excel file
#### Testing Contribution - Calculates the deviation and colors the excel cells.
- Calculates the deviation for each test case and adds a overall deviation for the test run
- **Design and implement solution for test automation**
- **Create testcase sample for test automation** #### Testing Contribution
- **Testing and optimizing the code**
- **Design and implement solution for test automation**
- **Create testcase sample for test automation**
- **Testing and optimizing the code**
--- ### Jonathan Frei
<div style="display: flex; justify-content: space-around; align-items: center;"> #### General Contribution
<div> - **Creating README.md**
<hr style="width: 200px;"> - **Algorithm Designs on previous versions**
<p style="text-align: center;">Roberto Gelsinger</p>
</div> #### Code Contribution
<div> - **general**
<hr style="width: 200px;"> - Edited other Authors' codes for bugfixing
<p style="text-align: center;">Author 2</p>
</div> - **prozentuale_Abweichung.py**
<div> - Calculates percentual deviation between our calculated and the external measured value
<hr style="width: 200px;"> - Adds the percentual deviation to the testcases excel sheet
<p style="text-align: center;">Author 3</p>
</div> - **tabellen_umstrukturieren.py**
- Sorts the rows of the testcases excel sheet by percentual deviation
- **tabellen_zusammenführen.py**
- Merges the testruns excel sheet into the testcases excel sheet
#### Testing Contribution
- **Designed testing environments**
- **Created various testcases**
- **Ran rest runs in multiple code versions for code optimization**
---
<div style="display: flex; justify-content: space-around; align-items: center;">
<div>
<hr style="width: 200px;">
<p style="text-align: center;">Roberto Gelsinger</p>
</div>
<div>
<hr style="width: 200px;">
<p style="text-align: center;">Author 2</p>
</div>
<div>
<hr style="width: 200px;">
<p style="text-align: center;">Author 3</p>
</div>
</div> </div>

151
code/excel_evaluation.py Normal file
View File

@ -0,0 +1,151 @@
import openpyxl
def excel_row_to_string(file_path):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Erhalte die angegebene Zeile als Liste von Zellen
row_values = [cell.value for cell in sheet[2]]
# Ergebnisse werden ab Spalte 5 eingetragen
selected_columns = list(range(4, len(row_values)))
# Wähle nur die gewünschten Spalten aus
selected_values = [row_values[col] for col in selected_columns]
# Schließe die Excel-Datei
workbook.close()
# Konvertiere die Liste von Zellen in einen String
row_string = ', '.join(str(value) for value in selected_values)
return row_string
def write_subdivided_string_to_excel(file_path, input_string):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Teile den String nach jedem Komma auf
parts = input_string.split(',')
# Trage jeden Teil des Strings in eine neue Zeile ein
for i, part in enumerate(parts, 1):
#Spalte 17 kann sich je nach Tabellenstruktur ändern!
sheet.cell(row=2 + i - 1, column=17, value=part.strip()) # strip entfernt mögliche Leerzeichen
# Speichere die Änderungen
workbook.save(file_path)
# Schließe die Excel-Datei
workbook.close()
def read_columns(file_path):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Lese die Werte der beiden Spalten aus
values_column1 = [cell.value for cell in sheet['O']][1:]
values_column2 = [cell.value for cell in sheet['Q']][1:]
# Schließe die Excel-Datei
workbook.close()
return values_column1, values_column2
def calculate_deviation(liste1, liste2):
# Überprüfe, ob die Listen die gleiche Länge haben
if len(liste1) != len(liste2):
raise ValueError("Die Listen müssen die gleiche Länge haben")
# Berechne die prozentuale Abweichung zwischen den Werten
deviations = [((abs(float(b) - float(a)) / float(a)) * 100) if float(a) != 0 else None for a, b in zip(liste1, liste2)]
return deviations
def write_string_to_excel(file_path, input_string, column):
# Öffne die Excel-Datei
workbook = openpyxl.load_workbook(file_path)
# Wähle das Arbeitsblatt aus
sheet = workbook['Sheet1']
# Trage jeden Buchstaben des Strings in eine eigene Zeile ein
for i, char in enumerate(input_string, 1):
sheet.cell(row=2 + i - 1, column=column, value=char)
# Speichere die Änderungen
workbook.save(file_path)
# Schließe die Excel-Datei
workbook.close()
def copy_header(input_sheet, output_sheet):
# Kopiere den Header manuell in das Ausgabe-Arbeitsblatt
for row in input_sheet.iter_rows(min_row=1, max_row=1, values_only=True):
output_sheet.append(row)
def sort_excel(input_file_path, output_file_path, ):
# Öffne die Eingabe-Excel-Datei
input_workbook = openpyxl.load_workbook(input_file_path)
input_sheet = input_workbook['Sheet1']
# Erstelle eine neue Excel-Tabelle für die sortierten Zeilen
output_workbook = openpyxl.Workbook()
output_sheet = output_workbook.active
# Kopiere den Header ins Ausgabe-Arbeitsblatt
copy_header(input_sheet, output_sheet)
# Lese die Daten-Zeilen aus der Tabelle
data_rows = list(input_sheet.iter_rows(min_row=2, values_only=True))
# Sortiere die Daten-Zeilen nach dem Wert der angegebenen Spalte
sorted_data_rows = sorted(data_rows, key=lambda x: x[18 - 1]) # -1, da Listenindizes bei 0 beginnen
# Schreibe die sortierten Daten-Zeilen in die neue Tabelle
for row in sorted_data_rows:
output_sheet.append(row)
# Speichere die Änderungen in der neuen Excel-Datei
output_workbook.save(output_file_path)
# Schließe die Excel-Dateien
input_workbook.close()
output_workbook.close()
#Sollten mehrere Testruns ausgewertet werden wollen, müssen die enthaltenen Funktionen umstrukturiert werden
#Aktuell wird nur der Testrun in Zeile 1 ausgewertet
#Eine Weitere Funktion, die zwei Tabellenzeilen tauscht, wäre der einfachste workaround
def evaluation(testcases, testruns):
#liest die Ergebnisse des Testruns aus
#bei mehreren Testruns muss diese Funktion angepasst werden!
input_string = excel_row_to_string(testruns)
#schreibt die Berechneten Ergebnisse in die Testcases-Tabelle
write_subdivided_string_to_excel(testcases, input_string)
#liest die gemessenen und die errechneten Werte aus den Testcases
values_col1, values_col2 = read_columns(testcases)
#berechnet aus diesen Werten die prozentuale Abweichung
deviations = calculate_deviation(values_col1, values_col2)
#Trägt die prozentualen Abweichungen in die Testcases-Tabelle
#je nach Tabellenstruktur kann sich die 18 ändern!
write_string_to_excel(testcases, deviations, 18)
#Gibt die eine Kopie der Testcases-Tabelle sortiert nach Genauigkeit aus
sort_excel(testcases, 'Testcases_nach_Genauigkeit.xlsx')

View File

@ -1,132 +1,138 @@
""" """
Abhängigkeiten: Abhängigkeiten:
- pyramids (für den Aufbau der Bildpyramiden) - pyramids (für den Aufbau der Bildpyramiden)
- heartrate (zur Berechnung der Herzfrequenz) - heartrate (zur Berechnung der Herzfrequenz)
- preprocessing (für die Video-Vorverarbeitung) - preprocessing (für die Video-Vorverarbeitung)
- eulerian (für die Euler'sche Video-Magnifikation) - eulerian (für die Euler'sche Video-Magnifikation)
- tkinter und constants (für die GUI und Konstantenverwaltung) - tkinter und constants (für die GUI und Konstantenverwaltung)
Autor: Roberto Gelsinger Autor: Roberto Gelsinger
Datum: 07.12.2023 Datum: 07.12.2023
Version: Modulversion Version: Modulversion
""" """
import pyramids import pyramids
import heartrate import heartrate
import facedetection import facedetection
import eulerian import eulerian
from constants import freq_max, freq_min from constants import freq_max, freq_min
import pandas as pd import pandas as pd
from excel_update import color_cells_based_on_deviation from excel_update import color_cells_based_on_deviation
from excel_evaluation import evaluation
def process_video_for_excel(selected_video_name):
""" def process_video_for_excel(selected_video_name):
Verarbeitet ein ausgewähltes Video, um die Herzfrequenz der abgebildeten Person zu ermitteln. """
Verarbeitet ein ausgewähltes Video, um die Herzfrequenz der abgebildeten Person zu ermitteln.
Dieser Prozess umfasst die Vorverarbeitung des Videos, den Aufbau einer Laplace-Pyramide,
die Anwendung von FFT-Filterung und Euler'scher Magnifikation, und schließlich die Berechnung Dieser Prozess umfasst die Vorverarbeitung des Videos, den Aufbau einer Laplace-Pyramide,
der Herzfrequenz aus den Video-Daten. die Anwendung von FFT-Filterung und Euler'scher Magnifikation, und schließlich die Berechnung
der Herzfrequenz aus den Video-Daten.
Args:
selected_video_name (str): Der Name des zu verarbeitenden Videos. Args:
selected_video_name (str): Der Name des zu verarbeitenden Videos.
Returns:
None: Die Funktion gibt direkt die berechnete Herzfrequenz auf der Konsole aus. Returns:
""" None: Die Funktion gibt direkt die berechnete Herzfrequenz auf der Konsole aus.
"""
print("Reading + preprocessing video...")
video_frames, frame_ct, fps = facedetection.read_video("videos/"+selected_video_name) print("Reading + preprocessing video...")
video_frames, frame_ct, fps = facedetection.read_video("code/videos/"+selected_video_name)
print("Building Laplacian video pyramid...")
lap_video = pyramids.build_video_pyramid(video_frames) print("Building Laplacian video pyramid...")
lap_video = pyramids.build_video_pyramid(video_frames)
print(len(lap_video))
for i, video in enumerate(lap_video):
if i == 0 or i == len(lap_video)-1: for i, video in enumerate(lap_video):
continue print("test")
if i == 0 or i == len(lap_video)-1:
print("Running FFT and Eulerian magnification...") continue
result, fft, frequencies = eulerian.fft_filter(video, freq_min, freq_max, fps)
lap_video[i] += result print("Running FFT and Eulerian magnification...")
result, fft, frequencies = eulerian.fft_filter(video, freq_min, freq_max, fps)
lap_video[i] += result
print("Calculating heart rate...")
heart_rate = heartrate.find_heart_rate(fft, frequencies, freq_min, freq_max)
print("Calculating heart rate...")
heart_rate = heartrate.find_heart_rate(fft, frequencies, freq_min, freq_max)
print("Heart rate: ", heart_rate*0.7, "bpm")
return heart_rate *0.7
print("Heart rate: ", heart_rate*0.7, "bpm")
return heart_rate *0.7
def process_all_videos_and_save_results(testcase_excel_file_path, testruns_excel_file_path, code_version, kommentar):
try: def process_all_videos_and_save_results(testcase_excel_file_path, testruns_excel_file_path, code_version, kommentar):
df_testruns = pd.read_excel(testruns_excel_file_path)
except FileNotFoundError: try:
df_testruns = pd.DataFrame() df_testruns = pd.read_excel(testruns_excel_file_path)
except FileNotFoundError:
df_testruns = pd.DataFrame()
df_testcases = pd.read_excel(testcase_excel_file_path)
existing_testcases = [col for col in df_testruns.columns if col.startswith('Testcase_')] df_testcases = pd.read_excel(testcase_excel_file_path)
new_testcases = [f'Testcase_{tc}' for tc in df_testcases['Testcase'] if f'Testcase_{tc}' not in existing_testcases] existing_testcases = [col for col in df_testruns.columns if col.startswith('Testcase_')]
new_testcases = [f'Testcase_{tc}' for tc in df_testcases['Testcase'] if f'Testcase_{tc}' not in existing_testcases]
if df_testruns.empty:
df_testruns = pd.DataFrame(columns=['Testnummer', 'Codeversion', 'Kommentar', 'Abweichung'])
if df_testruns.empty:
df_testruns = pd.DataFrame(columns=['Testnummer', 'Codeversion', 'Kommentar', 'Abweichung'])
for col in new_testcases:
df_testruns[col] = None
for col in new_testcases:
df_testruns[col] = None
df_testruns.to_excel(testruns_excel_file_path, index=False)
if new_testcases: df_testruns.to_excel(testruns_excel_file_path, index=False)
print(f"Folgende neue Testcases wurden hinzugefügt: {new_testcases}")
else: if new_testcases:
print("Keine neuen Testcases zum Hinzufügen gefunden.") print(f"Folgende neue Testcases wurden hinzugefügt: {new_testcases}")
else:
next_testcase_index = len(df_testruns) + 1 print("Keine neuen Testcases zum Hinzufügen gefunden.")
next_testcase_index = len(df_testruns) + 1
new_run = {
'Testnummer': next_testcase_index,
'Codeversion': code_version, new_run = {
'Kommentar': kommentar, 'Testnummer': next_testcase_index,
'Abweichung': 'Wert_für_Abweichung' 'Codeversion': code_version,
} 'Kommentar': kommentar,
'Abweichung': 'Wert_für_Abweichung'
}
for index, row in df_testcases.iterrows():
video_name = row['VideoName']
heart_rate = process_video_for_excel(video_name) for index, row in df_testcases.iterrows():
video_name = row['VideoName']
heart_rate = process_video_for_excel(video_name)
testcase_column_name = f'Testcase_{row["Testcase"]}'
new_run[testcase_column_name] = heart_rate
testcase_column_name = f'Testcase_{row["Testcase"]}'
try: new_run[testcase_column_name] = heart_rate
df_testruns = df_testruns._append(new_run, ignore_index=True) try:
except TypeError:
pass df_testruns = df_testruns._append(new_run, ignore_index=True)
except TypeError:
pass
df_testruns.to_excel(testruns_excel_file_path, index=False)
print("Testrun wurde verarbeitet und das Ergebnis in der Testruns-Excel-Datei gespeichert.") df_testruns.to_excel(testruns_excel_file_path, index=False)
color_cells_based_on_deviation(testruns_excel_file_path, testcase_excel_file_path) print("Testrun wurde verarbeitet und das Ergebnis in der Testruns-Excel-Datei gespeichert.")
print("Zellen gefärbt") color_cells_based_on_deviation(testruns_excel_file_path, testcase_excel_file_path)
print("Zellen gefärbt")
evaluation(testcase_excel_file_path, testruns_excel_file_path)
print("Testcases sortiert")

77
code/facedetection1.py Normal file
View File

@ -0,0 +1,77 @@
"""
Abhängigkeiten:
- cv2 (OpenCV-Paket)
- numpy
Autor: Ihr Name
Datum: Erstellungs- oder Änderungsdatum
Version: Modulversion
"""
import cv2
import numpy as np
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_alt2.xml")
eyeCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_eye.xml")
def read_video(path):
"""
Liest ein Video, erkennt Gesichter und extrahiert Regionen von Interesse (ROIs).
Diese Funktion nimmt einen Pfad zu einer Videodatei und liest das Video. Während des Lesens erkennt sie
Gesichter im Video und extrahiert die ROIs (Gesichtsbereiche), die anschließend in einer Liste von Frames
gespeichert werden. Die Frames werden für spätere Verarbeitungsschritte skaliert.
Args:
path (str): Der Pfad zur Videodatei.
Returns:
tuple: Ein Tupel, bestehend aus:
- video_frames (list): Eine Liste von Frames, die die ROIs (Gesichtsbereiche) darstellen.
- frame_ct (int): Die Anzahl der extrahierten Frames.
- fps (int): Die Bildrate (Frames pro Sekunde) des Videos.
"""
cap = cv2.VideoCapture(path)
fps = int(cap.get(cv2.CAP_PROP_FPS))
video_frames = []
while cap.isOpened():
ret, img = cap.read()
if not ret:
break
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
for (x, y, w, h) in faces:
face_roi_gray = gray[y:y+h, x:x+w]
face_roi_color = img[y:y+h, x:x+w]
eyes = eyeCascade.detectMultiScale(face_roi_gray)
# Annahme: Wir brauchen mindestens zwei Augen für die Berechnung
if len(eyes) == 2:
# Berechne die Position und Größe des Stirnbereichs
eye1_x, eye1_y, eye1_w, eye1_h = eyes[0]
eye2_x, eye2_y, eye2_w, eye2_h = eyes[1]
# Bestimme die horizontale Position und Breite des Stirnbereichs
forehead_x = min(eye1_x, eye2_x)
forehead_w = max(eye1_x + eye1_w, eye2_x + eye2_w) - forehead_x
# Bestimme die vertikale Position und Höhe des Stirnbereichs
forehead_y = 0
forehead_h = int((min(eye1_y, eye2_y) - forehead_y) / 3)
# Extrahiere und skaliere den Stirnbereich
forehead_roi = face_roi_color[forehead_y:forehead_y + forehead_h, forehead_x:forehead_x + forehead_w]
forehead_resized = cv2.resize(forehead_roi, (500, 500))
video_frames.append(forehead_resized.astype("float") / 255.0)
cap.release()
for frame in video_frames:
cv2.imshow("frame", frame)
cv2.waitKey(20)
cv2.destroyAllWindows()
return video_frames, len(video_frames), fps

61
code/facedetection2.py Normal file
View File

@ -0,0 +1,61 @@
"""
Abhängigkeiten:
- cv2 (OpenCV-Paket)
- numpy
Autor: Ihr Name
Datum: Erstellungs- oder Änderungsdatum
Version: Modulversion
"""
import cv2
import numpy as np
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_alt2.xml")
def read_video(path):
"""
Liest ein Video, erkennt Gesichter und extrahiert Regionen von Interesse (ROIs).
Diese Funktion nimmt einen Pfad zu einer Videodatei und liest das Video. Während des Lesens erkennt sie
Gesichter im Video und extrahiert die ROIs (Gesichtsbereiche), die anschließend in einer Liste von Frames
gespeichert werden. Die Frames werden für spätere Verarbeitungsschritte skaliert.
Args:
path (str): Der Pfad zur Videodatei.
Returns:
tuple: Ein Tupel, bestehend aus:
- video_frames (list): Eine Liste von Frames, die die ROIs (Gesichtsbereiche) darstellen.
- frame_ct (int): Die Anzahl der extrahierten Frames.
- fps (int): Die Bildrate (Frames pro Sekunde) des Videos.
"""
cap = cv2.VideoCapture(path)
fps = int(cap.get(cv2.CAP_PROP_FPS))
video_frames = []
while cap.isOpened():
ret, img = cap.read()
if not ret:
break
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect faces
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# Extract ROIs and resize
for (x, y, w, h) in faces:
face_roi = cv2.resize(img[y:y+h, x:x+w], (500, 500))
frame = face_roi.astype("float") / 255.0
video_frames.append(frame)
cap.release()
for frame in video_frames:
cv2.imshow("frame", frame)
cv2.waitKey(20)
cv2.destroyAllWindows()
return video_frames, len(video_frames), fps

View File

@ -27,8 +27,9 @@ code_version= "1.0"
current_dir = os.getcwd() current_dir = os.getcwd()
testcase_excel_file_path = os.path.join(current_dir, 'testing/excel/Testcase_excel_dataset.xlsx') testcase_excel_file_path = os.path.join(current_dir, 'code/testing/excel/Testcase_excel_dataset.xlsx')
testruns_excel_file_path = os.path.join(current_dir, 'testing/excel/Testruns.xlsx') testruns_excel_file_path = os.path.join(current_dir, 'code/testing/excel/Testruns.xlsx')
evaluation_excel_file_path = os.path.join(current_dir, 'Testcases_nach_Genauigkeit.xlsx')
class VideoProcessingApp(tk.Tk): class VideoProcessingApp(tk.Tk):
def __init__(self): def __init__(self):
@ -61,6 +62,9 @@ class VideoProcessingApp(tk.Tk):
def open_testrun_excel_file(self): def open_testrun_excel_file(self):
os.startfile(testruns_excel_file_path) os.startfile(testruns_excel_file_path)
def open_evaluation_excel_file(self):
os.startfile(evaluation_excel_file_path)
def test_data_set(self): def test_data_set(self):
kommentar = self.testrun_kommentar_entry.get("1.0", "end-1c") kommentar = self.testrun_kommentar_entry.get("1.0", "end-1c")
@ -186,27 +190,33 @@ class VideoProcessingApp(tk.Tk):
def check_recording_status(self): def check_recording_status(self):
excel_file_path = 'testing/excel/Testcase_excel_dataset.xlsx' excel_file_path = 'code/testing/excel/Testcase_excel_dataset.xlsx'
global recording_finished # Deklarieren Sie die Verwendung der globalen Variable global recording_finished
if recording_finished_event.is_set(): if recording_finished_event.is_set():
recording_finished_event.clear() recording_finished_event.clear()
video_name = self.testcase_name_entry.get() video_name = self.testcase_name_entry.get()
length = int(self.video_length_entry.get()) # Hole die Länge des Videos length = int(self.video_length_entry.get())
pulse = simpledialog.askinteger("Puls", "Bitte geben Sie Ihren Puls ein:") pulse = simpledialog.askinteger("Puls", "Bitte geben Sie Ihren Puls ein:")
if pulse is not None: if pulse is not None:
new_video_name = f"{video_name}_{length}_{pulse}.avi" new_video_name = f"{video_name}_{length}_{pulse}.avi"
original_video_path = os.path.join('videos', f"{video_name}.avi") original_video_path = os.path.join('code', 'videos', f"{video_name}.avi")
new_video_path = os.path.join('videos', new_video_name) new_video_path = os.path.join('code', 'videos', new_video_name)
os.rename(original_video_path, new_video_path)
print(f"Video umbenannt zu {new_video_name}") if not os.path.exists(original_video_path):
self.write_to_excel(new_video_name, excel_file_path) print(f"Datei nicht gefunden: {original_video_path}")
return
try:
os.rename(original_video_path, new_video_path)
print(f"Video umbenannt zu {new_video_name}")
self.write_to_excel(new_video_name, excel_file_path)
except Exception as e:
print(f"Fehler beim Umbenennen der Datei: {e}")
else: else:
print("recording_finished ist False, warte auf Aufnahmeende")
print("Kein Puls eingegeben.") print("Kein Puls eingegeben.")
# Planen Sie die nächste Überprüfung
self.after(100, self.check_recording_status) self.after(100, self.check_recording_status)
#ui relateted methods #ui relateted methods
@ -264,7 +274,7 @@ class VideoProcessingApp(tk.Tk):
self.app_name_label.config(fg="#c82423", bg="#FFFFFF") self.app_name_label.config(fg="#c82423", bg="#FFFFFF")
# Laden Sie das Bild mit PIL und konvertieren Sie es in ein Format, das Tkinter verwenden kann # Laden Sie das Bild mit PIL und konvertieren Sie es in ein Format, das Tkinter verwenden kann
self.image = Image.open("code\Interface\ohmbild2.png") self.image = Image.open(r"code\interface\ohmbild2.png")
self.resized_image = self.image.resize((50, 30), Image.LANCZOS) self.resized_image = self.image.resize((50, 30), Image.LANCZOS)
self.photo = ImageTk.PhotoImage(self.resized_image) self.photo = ImageTk.PhotoImage(self.resized_image)
@ -531,16 +541,21 @@ class VideoProcessingApp(tk.Tk):
# Button open testcase excel # Button open testcase excel
self.open_testcase_button = tk.Button(self.testing_frame, text="Open Testcase Excel", command=self.open_testcase_excel_file) self.open_testcase_button = tk.Button(self.testing_frame, text="Open Testcase Excel", command=self.open_testcase_excel_file)
self.open_testcase_button.place(x=10, y=200) self.open_testcase_button.place(x=10, y=180)
self.open_testcase_button.config(bg="#c82423", fg="#FFFFFF") self.open_testcase_button.config(bg="#c82423", fg="#FFFFFF")
# Button open testrun excel # Button open testrun excel
self.open_testrun_button = tk.Button(self.testing_frame, text="Open Testrun Excel", command=self.open_testrun_excel_file) self.open_testrun_button = tk.Button(self.testing_frame, text="Open Testrun Excel", command=self.open_testrun_excel_file)
self.open_testrun_button.place(x=10, y=235) self.open_testrun_button.place(x=10, y=215)
self.open_testrun_button.config(bg="#c82423", fg="#FFFFFF") self.open_testrun_button.config(bg="#c82423", fg="#FFFFFF")
# Button open sorted excel
self.open_testrun_button = tk.Button(self.testing_frame, text="Open Evaluation Excel", command=self.open_evaluation_excel_file)
self.open_testrun_button.place(x=10, y=250)
self.open_testrun_button.config(bg="#c82423", fg="#FFFFFF")
def initialize_icon(self): def initialize_icon(self):
# Icon ändern # Icon ändern
self.iconbitmap('code\Interface\ohm.ico') self.iconbitmap(r'code\interface\ohm.ico')
# Ändert die Hintergrundfarbe # Ändert die Hintergrundfarbe
self.configure(bg="#FFFFFF") self.configure(bg="#FFFFFF")

View File

@ -36,7 +36,7 @@ def process_video(selected_video_name):
# Preprocessing phase # Preprocessing phase
print("Reading + preprocessing video...") print("Reading + preprocessing video...")
video_frames, frame_ct, fps = facedetection.read_video("videos/"+selected_video_name) video_frames, frame_ct, fps = facedetection.read_video("code/videos/"+selected_video_name)
# Build Laplacian video pyramid # Build Laplacian video pyramid
print("Building Laplacian video pyramid...") print("Building Laplacian video pyramid...")

View File

@ -56,7 +56,7 @@ def record_video(video_name="aufgenommenes_video", length=5,testcase_resolution1
""" """
output_folder = "videos" output_folder = "code/videos"
output_file = os.path.join(output_folder, video_name + ".avi") output_file = os.path.join(output_folder, video_name + ".avi")
frame_rate = testcase_fps frame_rate = testcase_fps
@ -124,7 +124,7 @@ def record_normal_video(video_name="aufgenommenes_video",video_resolution1=2560,
Args: Args:
video_name (str): Der Basisname der Videodatei (Standard ist "aufgenommenes_video"). video_name (str): Der Basisname der Videodatei (Standard ist "aufgenommenes_video").
""" """
output_folder = "videos" output_folder = "code/videos"
output_file = os.path.join(output_folder, video_name + ".avi") output_file = os.path.join(output_folder, video_name + ".avi")
cap = cv2.VideoCapture(0) cap = cv2.VideoCapture(0)

View File

@ -1,7 +1,7 @@
tkinter tk
numpy numpy
openpyxl openpyxl
pandas pandas
scipy scipy
opencv-python opencv-python
Pillow Pillow