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)