import cv2
import numpy as np
import os
import matplotlib.pyplot as plt
def process_frame(frame, threshold, grid_size, face_cascade):
# Wandle das Bild in Graustufen um
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Suche nach Gesichtern im Bild
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
noise_frames = []
# Wenn Gesichter gefunden wurden, sortiere sie nach Größe
if len(faces) > 0:
# Sortiere Gesichter nach Fläche (Größe)
faces = sorted(faces, key=lambda x: x[2] * x[3], reverse=True)
# Verwende nur das größte Gesicht
(x, y, w, h) = faces[0]
# Begrenze die Bildverarbeitung auf das Gesicht (ROI)
face_roi = frame[y:y+h, x:x+w]
# Teile das Gesicht in Bereiche auf
regions = np.array_split(face_roi, grid_size[0], axis=0)
regions = [np.array_split(region, grid_size[1], axis=1) for region in regions]
std_deviations = [[np.std(region) for region in row] for row in regions]
# Berechne den Durchschnitt des Pixelrauschens in der Gesichtsregion
face_avg_noise = np.mean(std_deviations)
for i, row in enumerate(std_deviations):
for j, std_deviation in enumerate(row):
# Vergleiche das Pixelrauschen mit dem Durchschnitt der Gesichtsregion
if std_deviation > threshold * face_avg_noise:
noise_frames.append((i, j, (x, y, w, h)))
# Zeichne einen Rahmen um den erkannten Bereich
y_start = int(y + i * h / grid_size[0])
y_end = int(y + (i + 1) * h / grid_size[0])
x_start = int(x + j * w / grid_size[1])
x_end = int(x + (j + 1) * w / grid_size[1])
cv2.rectangle(frame, (x_start, y_start), (x_end, y_end), (0, 0, 255), 2)
return noise_frames, frame
def detect_noise(video_path, threshold=1.5, grid_size=(50, 50), top_n_frames=5):
# Erstelle den Ausgabeordner, falls er nicht existiert
output_folder = "analyse/video"
os.makedirs(output_folder, exist_ok=True)
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
video_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
video_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
frame_number = 0
noise_frames = []
# Lade den Gesichts-Kaskadenklassifikator von OpenCV
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# Extrahiere den Dateinamen ohne Pfad und Erweiterung
file_name = os.path.splitext(os.path.basename(video_path))[0]
# Erstelle einen VideoWriter für die Ausgabe mit dem angepassten Dateinamen
output_video_path = os.path.join(output_folder, f"{file_name}_analyzed.mp4")
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_path, fourcc, fps, (video_width, video_height))
# Erstelle ein Fenster für die Anzeige
cv2.namedWindow("Frame", cv2.WINDOW_NORMAL)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
total_noise_frames = 0
top_n_frames_info = []
# Zusätzliche Variable für statistische Analyse
frame_with_noise_count = np.zeros(total_frames)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Führe die Bildverarbeitung in einem Thread aus
noise_frames, frame_with_annotations = process_frame(frame.copy(), threshold, grid_size, face_cascade)
# Schriftformausgabe im Video
cv2.putText(frame_with_annotations, f"Pixelrauschen: {len(noise_frames)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
# Schreibe den aktuellen Frame in die Ausgabedatei
out.write(frame_with_annotations)
# Zeige das aktuelle Frame in einem Fenster an
cv2.imshow("Frame", frame_with_annotations)
# Berechne Statistiken
total_noise_frames += len(noise_frames)
if len(noise_frames) > top_n_frames:
top_n_frames_info.append((frame_number, len(noise_frames)))
# Speichere die Anzahl der Auffälligkeiten für jedes Frame
frame_with_noise_count[frame_number] = len(noise_frames)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
frame_number += 1
cap.release()
out.release()
cv2.destroyAllWindows()
print(f"Analysevideo wurde gespeichert unter: {output_video_path}")
print(f"Durchschnittliche Anzahl der Rauschframes pro Frame: {total_noise_frames / total_frames}")
print(f"Durchschnittliche Anzahl der Rauschframes pro Sekunde: {total_noise_frames / fps}")
# Statistik für die N frames mit den meisten Auffälligkeiten
print(f"\nTop {top_n_frames} Frames mit den meisten Auffälligkeiten:")
for idx, (frame_num, num_auffaelligkeiten) in enumerate(sorted(top_n_frames_info, key=lambda x: x[1], reverse=True)[:top_n_frames]):
print(f"Frame Nummer: {frame_num}, Auffälligkeiten: {num_auffaelligkeiten}")
# Zeichnen Sie ein Diagramm der zeitlichen Verteilung der Auffälligkeiten
plt.plot(frame_with_noise_count)
plt.xlabel('Frame Nummer')
plt.ylabel('Anzahl der Auffälligkeiten')
plt.title('Zeitliche Verteilung der Auffälligkeiten')
plt.show()
# Beispielaufruf
video_path = input("Geben Sie den Pfad zur Videodatei ein: ")
detect_noise(video_path)
Scriptbeispiel: Umsetzung einer Diktiersoftware inkl. Vorlesefunktion und Übersetzung
import sounddevice as sd
import numpy as np
from scipy.io.wavfile import write
import os
import subprocess
import pyttsx3
import time
import pyperclip
import pyautogui
def transkription_und_uebersetzung(aufnahme_dateiname):
# Führe die Transkription durch
command_transkrip = f"whisper {aufnahme_dateiname} --device cuda --model medium --output_dir transkrip"
os.system(command_transkrip)
# Führe die Übersetzung durch
command_transl = f"whisper {aufnahme_dateiname} --device cuda --model medium --output_dir transl --task translate"
os.system(command_transl)
# Konfiguration der Aufnahme
fs = 44100 # Abtastrate (Samples pro Sekunde)
# Starte die kontinuierliche Aufnahme
aufnahme = sd.InputStream(samplerate=fs, channels=1, dtype='int16')
aufnahme.start()
buffer = []
recording = True
print("Bitte sprechen Sie etwas ins Mikrofon...")
try:
while recording:
# Lies die aktuellen Audiodaten
audiodaten, _ = aufnahme.read(fs)
# Füge die aktuellen Audiodaten zum Puffer hinzu
buffer.extend(audiodaten)
# Überprüfe, ob der Puffer zu groß ist (2 Sekunden Stille)
if len(buffer) > fs * 20:
recording = False
except KeyboardInterrupt:
print("\nAufnahme manuell gestoppt.")
finally:
# Stoppe die Aufnahme
aufnahme.stop()
# Konvertiere den Buffer zu einem NumPy-Array
buffer = np.array(buffer)
# Speichern der Aufnahme als WAV-Datei mit fester Bezeichnung "aufnahme.wav"
aufnahme_dateiname = "aufnahme.wav"
write(aufnahme_dateiname, fs, buffer)
# Führe die restlichen Befehle aus
transkription_und_uebersetzung(aufnahme_dateiname)
print("Aufnahme, Transkription und Übersetzung abgeschlossen.")
# Wechsle zum Ordner "transl"
transl_ordner = "transkrip"
os.chdir(transl_ordner)
# Lese den Inhalt der Datei "aufnahme.txt"
ergebnis_dateiname = "aufnahme.txt"
with open(ergebnis_dateiname, 'r', encoding='utf-8') as file:
inhalt = file.read()
print(f"Inhalt der Datei {ergebnis_dateiname}:\n{inhalt}")
# Vorlesen des Inhalts per Audio
text_to_speech = pyttsx3.init()
text_to_speech.say(inhalt)
text_to_speech.runAndWait()
# Warte für eine kurze Zeit, damit das Vorlesen abgeschlossen werden kann
time.sleep(2)
# Lese den Inhalt der Datei "aufnahme.txt"
ergebnis_dateiname = "aufnahme.txt"
with open(ergebnis_dateiname, 'r', encoding='utf-8') as file:
inhalt = file.read()
print(f"Inhalt der Datei {ergebnis_dateiname}:\n{inhalt}")
# Kopiere den Text in die Zwischenablage
pyperclip.copy(inhalt)
# Füge den Text an der aktuellen Cursorposition ein (zum Beispiel durch Tastenkombination Strg+V)
pyautogui.hotkey('ctrl', 'v')
print("Text wurde an der aktuellen Cursorposition eingefügt.")
Scriptbeispiel: Einzeltranskription inkl. Übersetzung
Code als *.py speichern und mit dem Anaconda-Prompt aufrufen.
# Einzelabfrage
import os
# Dateinamen in der Konsole abfragen
file_name = input("Geben Sie den Dateinamen (mit Erweiterung, z.B. video.mp4) ein: ")
# Überprüfe, ob der Dateiname Leerzeichen enthält
if ' ' in file_name:
# Wenn der Dateiname Leerzeichen enthält, füge Gänsefüßchen hinzu
quoted_file_name = f'"{file_name}"'
else:
# Ansonsten lasse den Dateinamen unverändert
quoted_file_name = file_name
# Überprüfe, ob eine TXT-Datei mit demselben Namen im Ordner "transkrip" existiert
if not os.path.exists(f"transkrip/{os.path.splitext(file_name)[0]}.txt"):
# Führe die Whisper-Befehle aus und verwende den zitierten Dateinamen
command = f"whisper {quoted_file_name} --output_dir transkrip"
os.system(command)
command = f"whisper {quoted_file_name} --output_dir transl --task translate"
os.system(command)
else:
print(f"Datei {file_name} wurde übersprungen, da bereits eine TXT-Datei im Ordner 'transkrip' existiert.")
# Ordnerabfrage
import os
# Ordnerpfad in der Konsole abfragen
folder_path = input("Geben Sie den Pfad des Ordners ein: ")
# Überprüfe, ob der Ordner existiert
if not os.path.exists(folder_path):
print(f"Der angegebene Ordner '{folder_path}' existiert nicht.")
else:
# Durchsuche den Ordner nach MP4-Dateien
for file_name in os.listdir(folder_path):
if file_name.endswith('.mp4'):
# Überprüfe, ob der Dateiname Leerzeichen enthält
if ' ' in file_name:
# Wenn der Dateiname Leerzeichen enthält, füge Gänsefüßchen hinzu
quoted_file_name = f'"{os.path.join(folder_path, file_name)}"'
else:
# Ansonsten lasse den Dateinamen unverändert
quoted_file_name = os.path.join(folder_path, file_name)
# Überprüfe, ob eine TXT-Datei mit demselben Namen im Ordner "transkrip" existiert
if not os.path.exists(f"transkrip/{os.path.splitext(file_name)[0]}.txt"):
# Führe die Whisper-Befehle aus und verwende den zitierten Dateinamen
command = f"whisper {quoted_file_name} --output_dir transkrip"
os.system(command)
command = f"whisper {quoted_file_name} --output_dir transl --task translate"
os.system(command)
else:
print(f"Datei {file_name} wurde übersprungen, da bereits eine TXT-Datei im Ordner 'transkrip' existiert.")
Wie kann ich eine saubere Transkriptionslösung (KI) bei mir installieren und in das Tagesgeschäft einbauen? (Whisper – OpenAI)
Vorraussetzung: installiertes Python oder Anaconda.
- Anaconda-Prompt starten
- pip install -U openai-whisper
- pip install setuptools-rust
- FFmpeg installieren (Anleitung: https://www.geeksforgeeks.org/how-to-install-ffmpeg-on-windows/)
- Anaconda-Prompt zu und im Administrator-Modus starten
- setx /m PATH „C:\ffmpeg\bin;%PATH%“ da eintragen und bestätigen
Befehle für für diese Lösung
- whisper datei.mp4 –model medium
- whisper datei.mp4 –model large
- whisper datei.mp4 –device cuda –task translate
Vorteil: diese Offline-KI-Lösung erkennt die Sprache automatisch und beinhaltet eine optionale Übersetzungsfunktion. Stapeltranskriptionen lassen sich mittels eigener Scripte lösen und für 20 Minuten Videotranskript inkl. Übersetzung werden etwas um die 2 Minuten benötigt.
Weiter lesen: https://github.com/openai/whisper
Wie kann ich eine saubere ÜbersetzungsKI bei mir installieren, bedienen und in das Tagesgeschäft implementieren?
Viele Anwendungsfälle und diverse aktuelle Datensicherheitsdebatten zwingen zur Prüfung selbstgehosteter Systeme und wir verwenden „Argos-Translate“ für 2 Szenarien:
(A) Einzelübersetzungen
(B) Stapelübersetzungen: große Datenbanken und Dokumente (DocX, PPTX etc.)
Installation:
Vorraussetzung: installiertes Python oder Anaconda.
Installationsweg bei der Anaconda-Variante
- Anaconda Prompt starten
- pip install argostranslate // -> Kernsystem
- pip install argostranslategui // -> GUI
- pip install argos-translate-files // -> Übersetzungssystem für Dateien
- Rechtsklick auf Desktop + Neu -> Verknüpfung + „%windir%\System32\cmd.exe „/K“ C:\Users\user\anaconda3\Scripts\activate.bat C:\Users\user\anaconda3″ (User entsprechend austauschen) eintragen und alles bestätigen // -> Anaconda-Prompt
- (5) wiederholen und da „%windir%\System32\cmd.exe „/K“ C:\Users\user\anaconda3\Scripts\activate.bat C:\Users\user\anaconda3 && python c:\users\user\anaconda3\scripts\argos-translate-gui “ eintragen (User entsprechend austauschen)
- Die Anaconda-GUI starten.
- In der GUI auf „Manage Packages“ klicken und alle Sprachdateien downloaden + installieren (der Installprozess läuft automatisch)
Wenn alles fertig ist, lassen sich Texte problemlos über die GUI übersetzen. Die Qualität ist „nahebei“ Deepl und wir haben das System auf die Sprachrichtungen RU -> EN, RU -> DE getestet. Spannend sind auch FS -> EN.
Tensorflow unter Windows mit GPU-Unterstützung laufen lassen
(1) https://www.dll-files.com/cudnn64_8.dll.html, die DLL downloaden
(2) die DLL in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\bin speichern
(3) pip install tensorflow[and-cuda] (linux)
(4) https://www.tensorflow.org/install/pip#windows-native
(5) https://discuss.tensorflow.org/t/tensorflow-2-13-0-does-not-find-gpu-with-cuda-12-1/18939
conda install -c conda-forge -y zlib-wapi
Tools / Ansätze für „Cascade“ (Objekterkennung)
https://pythonprogramming.net/haar-cascade-object-detection-python-opencv-tutorial/
Ressourcen: Stimmenerkennung, Emotionen
Gesichts- und Mimikenerkennung mit Python
Vorbereitung
- Installation v. cv2, numpy und imutils
- Download der xml-Dateien
- Organisation der zu analysierenden Videofiles
Code-Anpassungen
- „minSize“ beschreibt die Mind.-Gesichtsgröße in Pixel
- „minNeighbors“ & „scaleFactor“ beschreibt div. Tuningmetriken
- „cv2.VideoCapture“ beschreibt die Quelle. cv2.VideoCapture(0) -> Webcam
Code
import cv2
import numpy as np
import imutils
from tensorflow.keras.models import load_model
# Gesichtserkennungs-Modell laden
# face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + ‚haarcascade_profileface.xml‘)
face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + ‚haarcascade_frontalface_default.xml‘)
# Mimik-Erkennungs-Modell laden
# emotion_classifier = load_model(“, compile=True)
emotion_classifier = load_model(‚fer_model.h5‘, compile=True)
emotion_labels = {0: ‚Angry‘, 1: ‚Disgust‘, 2: ‚Fear‘, 3: ‚Happy‘, 4: ‚Sad‘, 5: ‚Surprise‘, 6: ‚Neutral‘}
# Video-Stream initialisieren
cap = cv2.VideoCapture(„Dateiname“)
while True:
ret, frame = cap.read()
if not ret:
break
# Gesichtserkennung
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=1, minSize=(150, 150), flags=cv2.CASCADE_SCALE_IMAGE)
for (x, y, w, h) in faces:
# Gesichtsausschnitt extrahieren
face = gray[y:y + h, x:x + w]
face = cv2.resize(face, (48, 48))
face = face.astype(„float“) / 255.0
face = np.expand_dims(face, axis=0)
face = np.expand_dims(face, axis=-1)
# Mimik erkennen
predictions = emotion_classifier.predict(face)[0]
emotion_probability = np.max(predictions)
label = emotion_labels[np.argmax(predictions)]
# Rechteck um das Gesicht zeichnen
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Text mit der erkannten Mimik hinzufügen
cv2.putText(frame, label, (x, y – 10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
cv2.imshow(‚frame‘, frame)
if cv2.waitKey(1) & 0xFF == ord(‚q‘):
break
cap.release()
cv2.destroyAllWindows()
Vorstellung: Youtube-Kanal
Ab sofort werde ich auf https://www.youtube.com/@Magic_Data_Playground/videos in unregelmäßigen Abständen Beispielvideos aus dem internen DataSience – „Labor“ veröffentlichen. Schwerpunkt sind diverse KNIME-Visualisierungen.