File size: 4,894 Bytes
8d7a724
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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)