import os import cv2 import pandas as pd from fer import FER from concurrent.futures import ThreadPoolExecutor, as_completed import csv from collections import Counter def remove_file_if_exists(file_path): """Löscht eine Datei, wenn sie existiert.""" if os.path.exists(file_path): os.remove(file_path) def analyze_image(png_file, detector, input_folder, nd_log_file): """ Analysiert ein einzelnes Bild und gibt ein Dictionary mit Informationen zur dominanten Emotion und Emotionen zurück. """ img_path = os.path.join(input_folder, png_file) img = cv2.imread(img_path) if img is None: print(f"Could not load image {png_file}") return { 'image_name': png_file, 'dominant_emotion': 'neutral', 'emotion': {'neutral': 100} } try: results = detector.detect_emotions(img) if results: emotions = results[0]['emotions'] dominant_emotion = max(emotions, key=emotions.get) # Falls die dominante Emotion 'neutral' ist und mindestens noch eine weitere Emotion > 0 vorliegt, # wähle die zweithöchste Emotion. if dominant_emotion == 'neutral' and len(emotions) > 1: sorted_emotions = sorted(emotions.items(), key=lambda x: x[1], reverse=True) if sorted_emotions[1][1] > 0: dominant_emotion = sorted_emotions[1][0] result = { 'image_name': png_file, 'dominant_emotion': dominant_emotion, 'emotion': emotions } else: raise ValueError("No face detected") except Exception as e: with open(nd_log_file, 'a') as log_file: log_file.write(f"{png_file}: {str(e)}\n") result = { 'image_name': png_file, 'dominant_emotion': 'neutral', 'emotion': {'neutral': 100} } return result def count_dominant_emotions(csv_file, output_txt): """ Zählt die dominanten Emotionen aus einer CSV-Datei und speichert die Ergebnisse in einer Textdatei. """ emotion_counter = Counter() try: # CSV-Datei lesen und Emotionen zählen with open(csv_file, mode='r', encoding='utf-8') as file: reader = csv.DictReader(file) for row in reader: dominant_emotion = row.get('dominant_emotion', '').strip() if dominant_emotion: emotion_counter[dominant_emotion] += 1 # Ergebnisse in Textdatei speichern with open(output_txt, mode='w', encoding='utf-8') as output_file: output_file.write("Dominante Emotionen:\n") for emotion, count in emotion_counter.items(): output_file.write(f"{emotion}: {count}\n") print(f"Die Ergebnisse wurden in '{output_txt}' gespeichert.") except FileNotFoundError: print(f"Die Datei '{csv_file}' wurde nicht gefunden.") except Exception as e: print(f"Fehler beim Verarbeiten der Datei: {e}") if __name__ == "__main__": # Ordner und Dateinamen definieren input_folder = 'output_crop' csv_file = 'results-internalset-fer.csv' nd_log_file = 'nd-log-internalset-fer.txt' output_txt = 'emotion_counts.txt' # Vorhandene Dateien löschen, um sie neu zu erstellen remove_file_if_exists(csv_file) remove_file_if_exists(nd_log_file) # PNG-Dateien im Ordner sammeln (ohne versteckte Dateien wie ._*) absolute_path = os.path.abspath(input_folder) png_files = sorted([ f for f in os.listdir(input_folder) if f.lower().endswith('.png') and not f.startswith('._') ]) total_files = len(png_files) print(f"{total_files} PNG-Datei(en) gefunden.") # FER-Detector initialisieren detector = FER(mtcnn=True) results_list = [] # Bilder parallel analysieren with ThreadPoolExecutor(max_workers=8) as executor: future_to_file = { executor.submit(analyze_image, png_file, detector, input_folder, nd_log_file): png_file for png_file in png_files } for index, future in enumerate(as_completed(future_to_file), start=1): result = future.result() results_list.append(result) progress = int((index / total_files) * 100) print(f'Processing {index}/{total_files} [{progress}%]', end='\r') # CSV-Datei schreiben, wenn Ergebnisse vorhanden sind if results_list: result_df = pd.DataFrame(results_list) result_df.to_csv(csv_file, index=False) print("\nCSV-Datei wurde erstellt und gespeichert.") else: print("\nKeine Ergebnisse vorhanden. CSV-Datei wird nicht erstellt.") # Dominante Emotionen aus der CSV zählen und in .txt speichern count_dominant_emotions(csv_file, output_txt)