|
|
|
|
|
|
|
|
""" |
|
|
|
|
|
Abhängigkeiten: |
|
|
|
|
|
- pyramids (für den Aufbau der Bildpyramiden) |
|
|
|
|
|
- heartrate (zur Berechnung der Herzfrequenz) |
|
|
|
|
|
- preprocessing (für die Video-Vorverarbeitung) |
|
|
|
|
|
- eulerian (für die Euler'sche Video-Magnifikation) |
|
|
|
|
|
- tkinter und constants (für die GUI und Konstantenverwaltung) |
|
|
|
|
|
|
|
|
|
|
|
Autor: Roberto Gelsinger |
|
|
|
|
|
Datum: 07.12.2023 |
|
|
|
|
|
Version: Modulversion |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
import pyramids |
|
|
|
|
|
import heartrate |
|
|
|
|
|
import facedetection |
|
|
|
|
|
import eulerian |
|
|
|
|
|
from constants import freq_max, freq_min |
|
|
|
|
|
import pandas as pd |
|
|
|
|
|
from excel_update import color_cells_based_on_deviation |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_video_for_excel(selected_video_name): |
|
|
|
|
|
""" |
|
|
|
|
|
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 |
|
|
|
|
|
der Herzfrequenz aus den Video-Daten. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
|
selected_video_name (str): Der Name des zu verarbeitenden Videos. |
|
|
|
|
|
|
|
|
|
|
|
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("Building Laplacian video pyramid...") |
|
|
|
|
|
lap_video = pyramids.build_video_pyramid(video_frames) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i, video in enumerate(lap_video): |
|
|
|
|
|
if i == 0 or i == len(lap_video)-1: |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
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("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: |
|
|
|
|
|
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_')] |
|
|
|
|
|
|
|
|
|
|
|
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']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for col in new_testcases: |
|
|
|
|
|
df_testruns[col] = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df_testruns.to_excel(testruns_excel_file_path, index=False) |
|
|
|
|
|
|
|
|
|
|
|
if new_testcases: |
|
|
|
|
|
print(f"Folgende neue Testcases wurden hinzugefügt: {new_testcases}") |
|
|
|
|
|
else: |
|
|
|
|
|
print("Keine neuen Testcases zum Hinzufügen gefunden.") |
|
|
|
|
|
|
|
|
|
|
|
next_testcase_index = len(df_testruns) + 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_run = { |
|
|
|
|
|
'Testnummer': next_testcase_index, |
|
|
|
|
|
'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) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testcase_column_name = f'Testcase_{row["Testcase"]}' |
|
|
|
|
|
new_run[testcase_column_name] = heart_rate |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
|
|
|
|
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.") |
|
|
|
|
|
|
|
|
|
|
|
color_cells_based_on_deviation(testruns_excel_file_path, testcase_excel_file_path) |
|
|
|
|
|
|
|
|
|
|
|
print("Zellen gefärbt") |
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
Abhängigkeiten:
|
|
|
|
|
|
- pyramids (für den Aufbau der Bildpyramiden)
|
|
|
|
|
|
- heartrate (zur Berechnung der Herzfrequenz)
|
|
|
|
|
|
- preprocessing (für die Video-Vorverarbeitung)
|
|
|
|
|
|
- eulerian (für die Euler'sche Video-Magnifikation)
|
|
|
|
|
|
- tkinter und constants (für die GUI und Konstantenverwaltung)
|
|
|
|
|
|
|
|
|
|
|
|
Autor: Roberto Gelsinger
|
|
|
|
|
|
Datum: 07.12.2023
|
|
|
|
|
|
Version: Modulversion
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import pyramids
|
|
|
|
|
|
import heartrate
|
|
|
|
|
|
import facedetection
|
|
|
|
|
|
import eulerian
|
|
|
|
|
|
from constants import freq_max, freq_min
|
|
|
|
|
|
import pandas as pd
|
|
|
|
|
|
from excel_update import color_cells_based_on_deviation
|
|
|
|
|
|
from excel_evaluation import evaluation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_video_for_excel(selected_video_name):
|
|
|
|
|
|
"""
|
|
|
|
|
|
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
|
|
|
|
|
|
der Herzfrequenz aus den Video-Daten.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
selected_video_name (str): Der Name des zu verarbeitenden Videos.
|
|
|
|
|
|
|
|
|
|
|
|
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(len(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):
|
|
|
|
|
|
print("test")
|
|
|
|
|
|
if i == 0 or i == len(lap_video)-1:
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
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("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:
|
|
|
|
|
|
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_')]
|
|
|
|
|
|
|
|
|
|
|
|
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'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for col in new_testcases:
|
|
|
|
|
|
df_testruns[col] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df_testruns.to_excel(testruns_excel_file_path, index=False)
|
|
|
|
|
|
|
|
|
|
|
|
if new_testcases:
|
|
|
|
|
|
print(f"Folgende neue Testcases wurden hinzugefügt: {new_testcases}")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("Keine neuen Testcases zum Hinzufügen gefunden.")
|
|
|
|
|
|
|
|
|
|
|
|
next_testcase_index = len(df_testruns) + 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_run = {
|
|
|
|
|
|
'Testnummer': next_testcase_index,
|
|
|
|
|
|
'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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testcase_column_name = f'Testcase_{row["Testcase"]}'
|
|
|
|
|
|
new_run[testcase_column_name] = heart_rate
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
|
|
|
|
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.")
|
|
|
|
|
|
|
|
|
|
|
|
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") |