Kapitel 13/Tutorial.md aktualisiert
This commit is contained in:
@@ -1021,47 +1021,69 @@ frame_files = sorted([
|
|||||||
if f.endswith(".bmp")
|
if f.endswith(".bmp")
|
||||||
])
|
])
|
||||||
|
|
||||||
movement_threshold = 12000
|
# 3 Sekunden pro Frame fix
|
||||||
min_duration = 5
|
SECONDS_PER_FRAME = 3
|
||||||
candidates = []
|
MIN_CLIP_DURATION = 15 # Sekunden
|
||||||
|
PRE_POST_BUFFER = 2 # Sekunden
|
||||||
|
|
||||||
prev_frame = None
|
movement_scores = []
|
||||||
active_start = None
|
frames = []
|
||||||
|
|
||||||
|
# Scores sammeln
|
||||||
for idx, frame_path in enumerate(frame_files):
|
for idx, frame_path in enumerate(frame_files):
|
||||||
frame = cv2.imread(frame_path, cv2.IMREAD_GRAYSCALE)
|
frame = cv2.imread(frame_path, cv2.IMREAD_GRAYSCALE)
|
||||||
if frame is None:
|
if frame is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if prev_frame is not None:
|
if idx == 0:
|
||||||
diff = cv2.absdiff(prev_frame, frame)
|
prev_frame = frame
|
||||||
score = int(np.sum(diff))
|
continue
|
||||||
print(f"[DEBUG] Frame {idx}: Bewegungsscore = {score}")
|
|
||||||
|
|
||||||
t = idx * 3
|
diff = cv2.absdiff(prev_frame, frame)
|
||||||
|
score = int(np.sum(diff))
|
||||||
if score > movement_threshold:
|
movement_scores.append(score)
|
||||||
if active_start is None:
|
frames.append((idx, score))
|
||||||
active_start = t
|
|
||||||
else:
|
|
||||||
if active_start is not None and (t - active_start) >= min_duration:
|
|
||||||
# Pre/Post-Puffer hinzufügen
|
|
||||||
start_time = max(0, active_start - 2)
|
|
||||||
end_time = min(t + 2, len(frame_files) * 3)
|
|
||||||
candidates.append({
|
|
||||||
"start": round(start_time, 2),
|
|
||||||
"end": round(end_time, 2)
|
|
||||||
})
|
|
||||||
active_start = None
|
|
||||||
|
|
||||||
|
print(f"[DEBUG] Frame {idx}: Bewegungsscore = {score}")
|
||||||
prev_frame = frame
|
prev_frame = frame
|
||||||
|
|
||||||
# Letzter offener Clip am Ende
|
if not movement_scores:
|
||||||
|
print("[WARN] Keine Bewegungsscores ermittelt.")
|
||||||
|
with open(output_json, 'w') as f:
|
||||||
|
json.dump([], f)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
# Schwelle dynamisch bestimmen
|
||||||
|
cutoff = np.quantile(movement_scores, 0.99)
|
||||||
|
print(f"[INFO] Dynamische Bewegungsschwelle (99%): {int(cutoff)}")
|
||||||
|
print(f"[INFO] Min: {min(movement_scores)}, Max: {max(movement_scores)}, Median: {int(np.median(movement_scores))}")
|
||||||
|
|
||||||
|
# Kandidaten suchen
|
||||||
|
candidates = []
|
||||||
|
active_start = None
|
||||||
|
|
||||||
|
for idx, score in frames:
|
||||||
|
t = idx * SECONDS_PER_FRAME
|
||||||
|
|
||||||
|
if score > cutoff:
|
||||||
|
if active_start is None:
|
||||||
|
active_start = t
|
||||||
|
else:
|
||||||
|
if active_start is not None and (t - active_start) >= MIN_CLIP_DURATION:
|
||||||
|
start_time = max(0, active_start - PRE_POST_BUFFER)
|
||||||
|
end_time = min(t + PRE_POST_BUFFER, len(frame_files) * SECONDS_PER_FRAME)
|
||||||
|
candidates.append({
|
||||||
|
"start": round(start_time, 2),
|
||||||
|
"end": round(end_time, 2)
|
||||||
|
})
|
||||||
|
active_start = None
|
||||||
|
|
||||||
|
# Offener Clip am Ende
|
||||||
if active_start is not None:
|
if active_start is not None:
|
||||||
t = len(frame_files) * 3
|
t = len(frame_files) * SECONDS_PER_FRAME
|
||||||
if t - active_start >= min_duration:
|
if t - active_start >= MIN_CLIP_DURATION:
|
||||||
start_time = max(0, active_start - 2)
|
start_time = max(0, active_start - PRE_POST_BUFFER)
|
||||||
end_time = min(t + 2, len(frame_files) * 3)
|
end_time = min(t + PRE_POST_BUFFER, len(frame_files) * SECONDS_PER_FRAME)
|
||||||
candidates.append({
|
candidates.append({
|
||||||
"start": round(start_time, 2),
|
"start": round(start_time, 2),
|
||||||
"end": round(end_time, 2)
|
"end": round(end_time, 2)
|
||||||
@@ -1073,7 +1095,6 @@ with open(output_json, "w") as f:
|
|||||||
print(f"[DONE] Bewegungserkennung abgeschlossen → {len(candidates)} Clip(s) geschrieben in {output_json}")
|
print(f"[DONE] Bewegungserkennung abgeschlossen → {len(candidates)} Clip(s) geschrieben in {output_json}")
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
||||||
echo "[INFO] Vergleiche Audio- und visuelle Kandidaten..."
|
echo "[INFO] Vergleiche Audio- und visuelle Kandidaten..."
|
||||||
|
|
||||||
TMP_JSON_FINAL="$TMP_DIR/candidates.final.json"
|
TMP_JSON_FINAL="$TMP_DIR/candidates.final.json"
|
||||||
@@ -1145,6 +1166,7 @@ EOF
|
|||||||
echo "[INFO] Ersetze ursprüngliches JSON mit finaler Version..."
|
echo "[INFO] Ersetze ursprüngliches JSON mit finaler Version..."
|
||||||
mv "$TMP_JSON_FINAL" "$TMP_JSON"
|
mv "$TMP_JSON_FINAL" "$TMP_JSON"
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
1. **SSH Node – Analyze VOD** (Node-Name: Analyze VOD)
|
1. **SSH Node – Analyze VOD** (Node-Name: Analyze VOD)
|
||||||
- Node-Typ: SSH
|
- Node-Typ: SSH
|
||||||
|
|||||||
Reference in New Issue
Block a user