Codebeispiel: Auswertung extrem großer Dokumente.

Grobe Funktionsdarstellung:

  1. Dokument einlesen
  2. Inhalt(e) auswerten
  3. „Fragen“ an die Inhalte „stellen“ und geeignete Antworten identifizieren
  4. Reporting.

import fitz  # PyMuPDF
from transformers import pipeline, AutoModelForQuestionAnswering, AutoTokenizer
import re
import pandas as pd
from io import BytesIO

# Funktion zum Einlesen des Kontextes aus einer PDF-Datei
def read_text_from_pdf(file_path):
    document = http://fitz.open(file_path)
    pages = []
    for page_num, page in enumerate(document):
        text = page.get_text()
        pages.append((text, page_num + 1))  # Speichert den Text und die Seitennummer
    document.close()
    return pages

# Funktion zum Einlesen der Fragen aus einer Textdatei
def read_questions_from_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        questions = file.readlines()
    return [question.strip() for question in questions]

# Funktion zur Bereinigung der Zahlenformatierung
def clean_number_format(text):
    # Entfernt Tausendertrennzeichen und stellt Dezimalpunkte sicher
    text = re.sub(r'(\d)(?=(\d{3})+(\.|\b))', r'\1.', text)  # Tausendertrennzeichen entfernen
    text = re.sub(r'(?<!\d)(\d+)(?=\.\d+)', r'\1.', text)  # Dezimalpunkt hinzufügen
    return text

# Funktion zum Finden des relevanten Textabschnitts
def find_relevant_text(context, answer_start, answer_end):
    # Finde die Textstelle um die Antwort herum
    context_len = len(context)
    start = max(answer_start - 100, 0)
    end = min(answer_end + 100, context_len)
    return context[start:end]

# Funktion zum Erstellen von Reports in verschiedenen Formaten
def generate_reports(answers, html_file, csv_file, xlsx_file):
    # Erstellen eines DataFrames für die Berichterstellung
    df = pd.DataFrame(answers, columns=["Frage", "Antwort", "Seite", "Score", "Textstelle"])

    # HTML-Bericht
    html_content = http://df.to_html(index=False, escape=False, formatters={'Textstelle': lambda x: x.replace('\n', '<br>')})

    # HTML-Kopf und -Fuß
    html_header = """
    <!DOCTYPE html>
    <html lang="de">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Frage-Antwort-Bericht</title>
        <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            h1 { color: #333; }
            table { width: 100%; border-collapse: collapse; margin-top: 20px; }
            th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
            th { background-color: #f4f4f4; }
            tr:hover { background-color: #f1f1f1; }
        </style>
    </head>
    <body>
        <h1>Frage-Antwort-Bericht</h1>
        <p>Erstellt am: {date}</p>
        <p>Bericht über Fragen und Antworten basierend auf dem bereitgestellten Kontext.</p>
    """.format(date=http://pd.Timestamp.now().strftime("%d.%m.%Y %H:%M:%S"))

    html_footer = """
    </body>
    </html>
    """

    full_html_content = html_header + html_content + html_footer

    with open(html_file, 'w', encoding='utf-8') as f:
        f.write(full_html_content)

    # CSV-Bericht
    http://df.to_csv(csv_file, index=False, encoding='utf-8')

    # XLSX-Bericht
    http://df.to_excel(xlsx_file, index=False, engine='openpyxl')

# Pfad zur Datei mit dem Kontext und zur Textdatei mit den Fragen
context_file = "module/content.pdf"  # Pfad zur PDF-Datei mit dem Kontext
questions_file = "module/fragen.txt"  # Pfad zur Datei mit den Fragen

# Pfade zu den Berichtdateien
html_file = "report.html"
csv_file = "report.csv"
xlsx_file = "report.xlsx"

# Laden des Modells und Tokenizers für deutsche Frage-Antwort-Aufgaben
model_name = "deepset/gelectra-base-germanquad"
model = AutoModelForQuestionAnswering.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Erstellen der Frage-Antwort-Pipeline
nlp = pipeline("question-answering", model=model, tokenizer=tokenizer)

# Einlesen des Kontextes aus der PDF-Datei
contexts = read_text_from_pdf(context_file)

# Einlesen der Fragen
questions = read_questions_from_file(questions_file)

# Beantwortung der Fragen und Sammlung der Ergebnisse
answers = []

for question in questions:
    for context, page_num in contexts:
        cleaned_context = clean_number_format(context)  # Bereinigung des Kontextes
        result = nlp(question=question, context=cleaned_context, max_answer_len=100)
        
        if result['score'] > 0.5:  # Optional: Setze einen Schwellenwert für die Mindest-Score
            answer_start = result['start']
            answer_end = result['end']
            relevant_text = find_relevant_text(cleaned_context, answer_start, answer_end)
            answers.append((question, result['answer'], page_num, result['score'], relevant_text))

# Konsolenausgabe und Generierung der Berichte
for question in questions:
    answers_found = [a for a in answers if a[0] == question]

    if answers_found:
        print(f"Frage: {question}")
        for answer, page_num, score, relevant_text in answers_found:
            print(f"Antwort: {answer}")
            print(f"Seite: {page_num}")
            print(f"Score: {score:.2f}")
            print(f"Textstelle: {relevant_text}\n")
    else:
        print(f"Frage: {question}")
        print("Antwort: Keine Antwort gefunden\n")

# Generierung der Berichte
generate_reports(answers, html_file, csv_file, xlsx_file)

Quellcode: Zusammenführung von Videoschnipsel zu einem Gesamtvideo

Funktionen:

  1. Einlesen eines Ordners
  2. Einlesen der Dateinamen
  3. Zusammenführung der Dateien zu einem Gesamtvideo
  4. Einblendung von Untertitel, die sich aus den Datennamen (2) generieren.
import os
from moviepy.editor import VideoFileClip, concatenate_videoclips, CompositeVideoClip, ImageClip
from PIL import Image, ImageDraw, ImageFont

def create_text_clip(text, duration, fontsize=60, color='white'):
    # Erstelle ein leeres Bild mit transparentem Hintergrund
    img = Image.new('RGBA', (640, 100), (0, 0, 0, 0))  # Transparenter Hintergrund
    d = ImageDraw.Draw(img)
    
    # Schriftart laden
    try:
        font = ImageFont.truetype("Arial.ttf", fontsize)
    except IOError:
        font = ImageFont.load_default()

    # Berechne die Größe des Textes
    text_width, text_height = d.textbbox((0, 0), text, font=font)[2:]

    # Text in die Mitte zeichnen
    d.text(((640 - text_width) // 2, (100 - text_height) // 2), text, fill=color, font=font)

    # Speichere das Bild temporär
    img.save("temp_text_clip.png")
    
    # Erstelle einen VideoClip aus dem Bild
    return ImageClip("temp_text_clip.png").set_duration(duration).set_position(('left', 'bottom')).margin(left=10, bottom=10)

# Pfad zum Ordner mit den .mp4-Dateien
ordner_pfad = '_test'

# Liste zum Speichern der einzelnen Clips
clips = []

# Zähler für die Video-Nummerierung
video_counter = 1

# Durchlaufe alle Dateien im Ordner und Unterordnern
for root, dirs, files in os.walk(ordner_pfad):
    for datei_name in sorted(files):  # sortiert nach Dateinamen
        if datei_name.endswith(".mp4"):
            datei_pfad = os.path.join(root, datei_name)
            # VideoClip laden
            clip = VideoFileClip(datei_pfad)

            # Dateiname ohne .mp4 und Nummer hinzufügen
            titel_text = f"{video_counter}: {os.path.splitext(datei_name)[0]}"  # Zähler

            # TextClip für den Dateinamen als Untertitel erstellen
            text_clip = create_text_clip(titel_text, clip.duration)

            # Clip zur Liste hinzufügen
            video_mit_untertitel = CompositeVideoClip([clip, text_clip])
            clips.append(video_mit_untertitel)

            # Zähler erhöhen
            video_counter += 1

# Videos zusammenfügen
if clips:
    final_video = concatenate_videoclips(clips, method="compose")

    # Ausgabe-Datei speichern
    final_video_output = os.path.join(ordner_pfad, "zusammengefuegtes_video.mp4")
    final_video.write_videofile(final_video_output, codec="libx264", fps=24)

    print(f"Video erfolgreich erstellt: {final_video_output}")
else:
    print("Keine .mp4-Dateien gefunden.")

Gesichts- und Mimikenerkennung mit Python

Vorbereitung

  1. Installation v. cv2, numpy und imutils
  2. Download der xml-Dateien
  3. Organisation der zu analysierenden Videofiles

Code-Anpassungen

  1. „minSize“ beschreibt die Mind.-Gesichtsgröße in Pixel
  2. „minNeighbors“ & „scaleFactor“ beschreibt div. Tuningmetriken
  3. „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()