From 5a7176920a44de431624e694dbb1b8e20fab7b39 Mon Sep 17 00:00:00 2001 From: chk <79915315+ChKendel@users.noreply.github.com> Date: Mon, 25 May 2026 22:16:11 +0200 Subject: [PATCH] Phase 1 abgeschlossen: Positionen werden erkannt. Positionen aus den Merkern heraus erkennbar. Viele Bilder gleichzeitig verarbeitbar. --- documentation/Phase1.aux | 14 + documentation/Phase1.pdf | Bin 0 -> 118768 bytes documentation/Phase1.tex | 248 ++++ documentation/Phase1_Phase2.aux | 28 + documentation/Phase1_Phase2.pdf | Bin 0 -> 105709 bytes documentation/Phase1_Phase2.tex | 348 +++++ .../2_estimate_camera_pose_from_aruco_json.py | 504 ++++++-- programs/3_fuse_markers_world.py | 765 +++++++++++ programs/3_fuse_markers_world____.py | 1135 +++++++++++++++++ ...timate_camera_pose_from_aruco_json.test.js | 63 +- test/data/screenShots/fused_markers.csv | 20 + 11 files changed, 3005 insertions(+), 120 deletions(-) create mode 100644 documentation/Phase1.aux create mode 100644 documentation/Phase1.pdf create mode 100644 documentation/Phase1.tex create mode 100644 documentation/Phase1_Phase2.aux create mode 100644 documentation/Phase1_Phase2.pdf create mode 100644 documentation/Phase1_Phase2.tex create mode 100644 programs/3_fuse_markers_world.py create mode 100644 programs/3_fuse_markers_world____.py create mode 100644 test/data/screenShots/fused_markers.csv diff --git a/documentation/Phase1.aux b/documentation/Phase1.aux new file mode 100644 index 0000000..6ec367e --- /dev/null +++ b/documentation/Phase1.aux @@ -0,0 +1,14 @@ +\relax +\@writefile{toc}{\contentsline {section}{\numberline {1}Ziel}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {2}Koordinatensysteme}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {3}solvePnP}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {4}Kamerapose}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {5}Markerposition in Weltkoordinaten}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {6}Markerrotation in Weltkoordinaten}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {7}Gewichtung der Beobachtungen}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {8}Gewichtete Positionsfusion}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {9}Rotationsfusion}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {10}Qualitätsmetriken}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {11}Rigid-Body Erweiterung}{4}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {12}Spätere Erweiterungen}{4}{}\protected@file@percent } +\gdef \@abspage@last{4} diff --git a/documentation/Phase1.pdf b/documentation/Phase1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..057cc98f7004bbc1b3a83429f1680041a3745fa2 GIT binary patch literal 118768 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%0A{{H|DHikePy1<*Vp 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�ySj(2Cdg%P@7me)aRKGUB~jqSy8df>Rv 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 literal 0 HcmV?d00001 diff --git a/documentation/Phase1_Phase2.tex b/documentation/Phase1_Phase2.tex new file mode 100644 index 0000000..173d21e --- /dev/null +++ b/documentation/Phase1_Phase2.tex @@ -0,0 +1,348 @@ +\documentclass[a4paper,11pt]{article} + +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{geometry} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{listings} +\usepackage{xcolor} + + +\title{Phase 2 --- Kinematic-Constrained Multi-Camera Solver} +\author{} +\date{} + +\begin{document} + +\maketitle + +\section{Ziel} + +Nach Phase 1 existiert: + +\begin{itemize} + \item ein gemeinsames Weltkoordinatensystem + \item Kameraposen aller Kameras + \item bekannte absolute Markerpositionen + \item fusionierte Beobachtungen mehrerer Kameras +\end{itemize} + +Phase 2 erweitert das System um: + +\begin{itemize} + \item Rigid-Body Constraints + \item mechanische Zusammenhänge + \item Gelenke + \item relative Marker-Geometrien (\texttt{relPos}) + \item Stabilisierung bei wenigen sichtbaren Markern +\end{itemize} + +\section{Ausgangslage} + +Aktuell wird jeder Marker unabhängig behandelt. + +Das ist suboptimal, weil: + +\begin{itemize} + \item viele Marker nur kurz sichtbar sind + \item oft nur 1--2 Marker eines Bauteils sichtbar sind + \item solvePnP bei wenigen Markern instabil wird + \item Markerrauschen direkt in die Weltkoordinaten eingeht +\end{itemize} + +Mechanisch sind die Marker jedoch nicht unabhängig. + +Mehrere Marker gehören jeweils zu: + +\begin{itemize} + \item Arm1 + \item Arm2 + \item Joint1 + \item Base + \item Finger1 + \item Finger2 +\end{itemize} + +und bilden jeweils starre Körper (Rigid Bodies). + +\section{Grundidee} + +Statt einzelne Marker zu lösen: + +\begin{verbatim} +Marker -> Welt +\end{verbatim} + +wird gelöst: + +\begin{verbatim} +RigidBody -> Welt +\end{verbatim} + +und daraus: + +\begin{verbatim} +Marker = RigidBody * relTransform +\end{verbatim} + +\section{Vorteil} + +Schon ein einzelner sichtbarer Marker kann: + +\begin{itemize} + \item einen ganzen Körper stabilisieren + \item andere unsichtbare Marker indirekt bestimmen +\end{itemize} + +Beispiel: + +Wenn Marker 198 sichtbar ist +und Marker 229 relativ dazu bekannt ist, +dann kann Marker 229 geschätzt werden, +auch wenn er aktuell unsichtbar ist. + +\section{Erwartete Verbesserungen} + +\subsection{Stabilität} + +Deutlich stabilere Pose-Schätzung bei: + +\begin{itemize} + \item Motion Blur + \item wenigen sichtbaren Markern + \item schlechten Blickwinkeln + \item Teilverdeckungen +\end{itemize} + +\subsection{Konsistenz} + +Marker eines Bauteils bleiben: + +\begin{itemize} + \item geometrisch korrekt + \item starr + \item ohne unrealistische Verzerrungen +\end{itemize} + +\subsection{Multi-Camera-Verkettung} + +Kameras können indirekt gekoppelt werden. + +Beispiel: + +Cam1 sieht: +\begin{itemize} + \item Marker 1,2,3 +\end{itemize} + +Cam2 sieht: +\begin{itemize} + \item Marker 3,198 +\end{itemize} + +Cam3 sieht: +\begin{itemize} + \item Marker 198,229 +\end{itemize} + +Dadurch wird: +\begin{itemize} + \item Arm1 relativ zur Welt bestimmbar + \item obwohl keine einzelne Kamera alles sieht +\end{itemize} + +\section{Benötigte Daten} + +\subsection{Bereits vorhanden} + +\subsubsection{Absolute Marker} + +\begin{verbatim} +"position":[x,y,z] +\end{verbatim} + +für Board-Marker. + +\subsubsection{Relative Markerpositionen} + +\begin{verbatim} +"relPos":[x,y,z] +\end{verbatim} + +für Marker auf einem Rigid Body. + +\subsubsection{Body-Zuordnung} + +\begin{verbatim} +"on":"Arm1" +\end{verbatim} + +\subsubsection{Gelenke} + +\begin{verbatim} +"type":"revolute" +"axis":[1,0,0] +\end{verbatim} + +\section{Noch fehlende Daten} + +\subsection{Marker-Orientierung relativ zum Body} + +Aktuell existiert nur: + +\begin{verbatim} +"relPos" +\end{verbatim} + +Empfohlen wird zusätzlich: + +\begin{verbatim} +"relRot":[rx,ry,rz] +\end{verbatim} + +oder alternativ: + +\begin{verbatim} +"normal":[x,y,z] +"up":[x,y,z] +\end{verbatim} + +Denn Marker besitzen nicht nur Position, +sondern auch Orientierung. + +Das verbessert spätere Pose-Fits deutlich. + +\section{Geplante Solver-Strategie} + +\subsection{Phase 2A --- Rigid Body Fit} + +Zunächst: + +\begin{itemize} + \item pro Element einen starren Körper fitten + \item noch keine Gelenkoptimierung +\end{itemize} + +Beispiel: + +\begin{verbatim} +T_world_arm1 +\end{verbatim} + +wird geschätzt. + +Alle Marker von Arm1 folgen daraus automatisch. + +\subsection{Phase 2B --- Joint Constraints} + +Danach: + +\begin{itemize} + \item Gelenkachsen erzwingen + \item Rotationen einschränken + \item mechanische Grenzen verwenden +\end{itemize} + +Beispiel: + +\begin{verbatim} +Arm2 darf sich nur um Y drehen +\end{verbatim} + +\subsection{Phase 2C --- Global Optimization} + +Später optional: + +\begin{itemize} + \item vollständiges Bundle Adjustment + \item gleichzeitige Optimierung aller: + \begin{itemize} + \item Kameras + \item Marker + \item Bodies + \item Gelenkwinkel + \end{itemize} +\end{itemize} + +\section{Wichtige Architekturentscheidung} + +NICHT: + +\begin{verbatim} +Marker einzeln lösen +\end{verbatim} + +SONDERN: + +\begin{verbatim} +Bodies + Constraints lösen +\end{verbatim} + +Marker werden damit Beobachtungen, +nicht mehr primäre Zustände. + +\section{Geplante Datenstruktur} + +\subsection{Weltpose eines Körpers} + +\begin{verbatim} +{ + "body":"Arm1", + "worldPose":{ + "position":[x,y,z], + "rotationMatrix":[...] + } +} +\end{verbatim} + +\subsection{Relative Markerdefinition} + +\begin{verbatim} +{ + "id":198, + "on":"Arm1", + "relPos":[x,y,z], + "relRot":[rx,ry,rz] +} +\end{verbatim} + +\section{Phase 1 Reminder} + +Phase 1 bleibt weiterhin wichtig: + +\begin{itemize} + \item alle Kameras finden + \item alle Detection-Dateien laden + \item gemeinsame Marker fusionieren + \item Weltkoordinaten berechnen + \item Qualitätsmetriken speichern + \item auch schlechte / unvollständige Beobachtungen abspeichern +\end{itemize} + +Die Ergebnisse von Phase 1 dienen als Eingang für Phase 2. + +\section{Zielbild} + +Langfristig entsteht: + +\begin{itemize} + \item ein globales Robotermodell + \item mit mehreren Kameras + \item mehreren Rigid Bodies + \item Gelenken + \item Unsicherheiten + \item Qualitätsmetriken + \item temporaler Stabilisierung +\end{itemize} + +basierend auf: + +\begin{itemize} + \item ArUco-Beobachtungen + \item Mechanik + \item Kinematik + \item Multi-View-Geometrie +\end{itemize} + +\end{document} \ No newline at end of file diff --git a/programs/2_estimate_camera_pose_from_aruco_json.py b/programs/2_estimate_camera_pose_from_aruco_json.py index 553afb4..1eb2104 100644 --- a/programs/2_estimate_camera_pose_from_aruco_json.py +++ b/programs/2_estimate_camera_pose_from_aruco_json.py @@ -1,27 +1,26 @@ #!/usr/bin/env python3 """ -estimate_camera_pose_from_aruco_json.py +2_estimate_camera_pose_from_aruco_json.py Berechnet die Kameraposition im Maschinen-/Board-Koordinatensystem aus: 1. einer ArUco-Detections-JSON 2. robots.json mit bekannten Marker-Positionen -Das Script verwendet ausschließlich bekannte Marker -und bestimmt daraus die Kamera-Extrinsics mittels solvePnP. - -Ergebnis: -- Kamera-Position im Weltkoordinatensystem -- Kamera-Orientierung (Roll/Pitch/Yaw) -- optionale Reprojektion zur Qualitätskontrolle +NEU: +- Marker-Orientierungen unterstützt +- Default: Board-Marker zeigen nach +Z +- Qualitätsbewertung erweitert +- Speichert ALLE erkannten Marker +- Speichert auch fehlgeschlagene Lösungen +- Bewertet Kamerageometrie +- Bewertet Markerabdeckung +- Bewertet Sichtwinkel +- Bewertet Markeranzahl +- Speichert vollständige Rohdaten Benötigt: pip install opencv-python numpy - -Beispiel: - python 2_estimate_camera_pose_from_aruco_json.py \ - --detections detection.json \ - --robots robots.json """ import argparse @@ -37,31 +36,45 @@ import numpy as np # Hilfsfunktionen # ============================================================ +def normalize(v): + n = np.linalg.norm(v) + + if n < 1e-9: + return v + + return v / n + + +def rotation_matrix_from_axes(x_axis, y_axis, z_axis): + + R = np.column_stack([ + normalize(x_axis), + normalize(y_axis), + normalize(z_axis) + ]) + + return R.astype(np.float32) + + def rvec_tvec_to_camera_pose(rvec, tvec): """ - OpenCV liefert: + OpenCV: X_cam = R * X_world + t - Gesucht: - Kamera-Pose im Weltkoordinatensystem - - => R_wc = R^T - => C = -R^T * t + Kamera im Weltkoordinatensystem: + C = -R^T * t """ R_cw, _ = cv2.Rodrigues(rvec) R_wc = R_cw.T + cam_pos = -R_wc @ tvec return R_wc, cam_pos.reshape(3) def rotation_matrix_to_euler_zyx(R): - """ - Euler ZYX: - yaw(Z), pitch(Y), roll(X) - """ yaw = math.degrees(math.atan2(R[1, 0], R[0, 0])) @@ -74,14 +87,42 @@ def rotation_matrix_to_euler_zyx(R): return roll, pitch, yaw -def build_marker_lookup(robot_data): - """ - Liest nur Marker mit ABSOLUTER Position. +# ============================================================ +# Marker-Orientierung +# ============================================================ - Unterstützt: - "position" -> absolute Weltposition [m] - "relPos" -> wird aktuell ignoriert - """ +def get_marker_rotation(marker): + + # Explizite Rotation vorhanden? + if "rotation_matrix" in marker: + return np.array( + marker["rotation_matrix"], + dtype=np.float32 + ) + + # Default: + # Marker zeigt nach +Z + # + # x = rechts + # y = oben + # z = aus Board heraus (+Z) + + x_axis = np.array([1, 0, 0], dtype=np.float32) + y_axis = np.array([0, 1, 0], dtype=np.float32) + z_axis = np.array([0, 0, 1], dtype=np.float32) + + return rotation_matrix_from_axes( + x_axis, + y_axis, + z_axis + ) + + +# ============================================================ +# Marker Lookup +# ============================================================ + +def build_marker_lookup(robot_data): marker_lookup = {} @@ -89,11 +130,10 @@ def build_marker_lookup(robot_data): marker_id = int(marker.get("id", -1)) - # negative IDs ignorieren if marker_id < 0: continue - # Nur absolute Weltpositionen verwenden + # Nur absolute Marker verwenden if "position" not in marker: continue @@ -105,29 +145,32 @@ def build_marker_lookup(robot_data): if len(pos) != 3: continue - marker_lookup[marker_id] = np.array( - pos, - dtype=np.float32 - ) + rotation = get_marker_rotation(marker) + + marker_lookup[marker_id] = { + "position": np.array( + pos, + dtype=np.float32 + ), + "rotation": rotation, + "on": marker.get("on", "unknown") + } return marker_lookup -def build_marker_object_points(marker_center_world, marker_size_m): - """ - Baut die 3D-Eckpunkte eines Markers auf. - Wichtig: - Die Corner-Reihenfolge MUSS zur OpenCV-ArUco-Reihenfolge passen. +# ============================================================ +# Marker-Eckpunkte +# ============================================================ - Reihenfolge: - top-left - top-right - bottom-right - bottom-left - """ +def build_marker_object_points( + marker_center_world, + marker_rotation, + marker_size_m): half = marker_size_m / 2.0 + # OpenCV Corner Reihenfolge local = np.array([ [-half, half, 0.0], [ half, half, 0.0], @@ -135,7 +178,113 @@ def build_marker_object_points(marker_center_world, marker_size_m): [-half, -half, 0.0], ], dtype=np.float32) - return local + marker_center_world.reshape(1, 3) + rotated = (marker_rotation @ local.T).T + + return rotated + marker_center_world.reshape(1, 3) + + +# ============================================================ +# Qualitätsmetriken +# ============================================================ + +def compute_marker_spread(points_3d): + + if len(points_3d) < 2: + return 0.0 + + mins = np.min(points_3d, axis=0) + maxs = np.max(points_3d, axis=0) + + diag = np.linalg.norm(maxs - mins) + + return float(diag) + + +def compute_viewing_angles( + camera_position, + marker_lookup, + used_markers): + + results = [] + + for marker_id in used_markers: + + marker = marker_lookup[marker_id] + + pos = marker["position"] + + R = marker["rotation"] + + normal = R[:, 2] + + to_camera = normalize(camera_position - pos) + + dot = np.clip( + np.dot(normal, to_camera), + -1.0, + 1.0 + ) + + angle = math.degrees(math.acos(dot)) + + results.append(angle) + + if len(results) == 0: + return { + "mean": None, + "max": None + } + + return { + "mean": float(np.mean(results)), + "max": float(np.max(results)) + } + + +def compute_pose_quality( + rms, + max_err, + num_markers, + marker_spread, + viewing_angle_mean): + + score = 100.0 + + # Reprojection Error + score -= rms * 8.0 + + # Max Error + score -= max_err * 2.0 + + # Wenige Marker + if num_markers < 2: + score -= 50 + + elif num_markers < 4: + score -= 25 + + elif num_markers < 6: + score -= 10 + + # Schlechte räumliche Verteilung + if marker_spread < 0.10: + score -= 30 + + elif marker_spread < 0.25: + score -= 15 + + # Schlechter Blickwinkel + if viewing_angle_mean is not None: + + if viewing_angle_mean > 70: + score -= 25 + + elif viewing_angle_mean > 50: + score -= 10 + + score = max(0.0, min(100.0, score)) + + return float(score) # ============================================================ @@ -148,28 +297,24 @@ def main(): parser.add_argument( "--detections", - required=True, - help="ArUco detection JSON" + required=True ) parser.add_argument( "--robots", - required=True, - help="robots.json" + required=True ) parser.add_argument( "--min-confidence", type=float, - default=0.5, - help="Minimale Marker-Confidence" + default=0.5 ) parser.add_argument( "--max-reprojection-error", type=float, - default=3.0, - help="Maximal erlaubter Reprojektionsfehler in Pixel" + default=3.0 ) args = parser.parse_args() @@ -185,7 +330,7 @@ def main(): robot_data = json.load(f) # ============================================================ - # Kamera-Parameter + # Kamera # ============================================================ K = np.array( @@ -199,19 +344,20 @@ def main(): ).reshape(-1, 1) # ============================================================ - # Bekannte Marker + # Marker laden # ============================================================ known_markers = build_marker_lookup(robot_data) # ============================================================ - # 2D/3D Punktlisten aufbauen + # Punktlisten # ============================================================ object_points = [] image_points = [] used_markers = [] + rejected_markers = [] detections = detection_data["detections"] @@ -219,20 +365,41 @@ def main(): marker_id = int(det["marker_id"]) - confidence = float(det.get("confidence", 1.0)) + confidence = float( + det.get("confidence", 1.0) + ) + + reason = None if confidence < args.min_confidence: + reason = "low_confidence" + + elif marker_id not in known_markers: + reason = "unknown_marker" + + if reason is not None: + + rejected_markers.append({ + "marker_id": marker_id, + "reason": reason, + "confidence": confidence + }) + continue - if marker_id not in known_markers: - continue + marker_info = known_markers[marker_id] - marker_center_world = known_markers[marker_id] + marker_center_world = marker_info["position"] - marker_size = float(det["marker_size_m"]) + marker_rotation = marker_info["rotation"] + + marker_size = float( + det["marker_size_m"] + ) obj_pts = build_marker_object_points( marker_center_world, + marker_rotation, marker_size ) @@ -246,25 +413,60 @@ def main(): used_markers.append(marker_id) + # ============================================================ + # Ausgabe vorbereiten + # ============================================================ + + out = { + "success": False, + "camera_pose": None, + "quality": {}, + "used_markers": [], + "rejected_markers": rejected_markers, + "all_detected_markers": [ + int(d["marker_id"]) + for d in detections + ] + } + + # ============================================================ + # Zu wenige Marker + # ============================================================ + if len(object_points) == 0: - raise RuntimeError( - "Keine bekannten Marker gefunden." + + out["quality"] = { + "error": "no_known_markers", + "num_detected_markers": len(detections), + "num_used_markers": 0 + } + + out_file = Path(args.detections).with_suffix( + ".camera_pose.json" ) - object_points = np.concatenate(object_points, axis=0) - image_points = np.concatenate(image_points, axis=0) + with open(out_file, "w", encoding="utf-8") as f: + json.dump(out, f, indent=2) - print() - print("==================================================") - print("Bekannte Marker verwendet:") - print(sorted(set(used_markers))) - print("==================================================") - print() + print("Keine bekannten Marker gefunden.") + print(out_file) + + return # ============================================================ # solvePnP # ============================================================ + object_points = np.concatenate( + object_points, + axis=0 + ) + + image_points = np.concatenate( + image_points, + axis=0 + ) + success, rvec, tvec = cv2.solvePnP( object_points, image_points, @@ -274,10 +476,24 @@ def main(): ) if not success: - raise RuntimeError("solvePnP fehlgeschlagen") + + out["quality"] = { + "error": "solvepnp_failed", + "num_used_markers": len(set(used_markers)) + } + + out_file = Path(args.detections).with_suffix( + ".camera_pose.json" + ) + + with open(out_file, "w", encoding="utf-8") as f: + json.dump(out, f, indent=2) + + print("solvePnP fehlgeschlagen") + return # ============================================================ - # Kamera-Pose berechnen + # Kamera Pose # ============================================================ R_wc, cam_pos = rvec_tvec_to_camera_pose( @@ -285,10 +501,12 @@ def main(): tvec ) - roll, pitch, yaw = rotation_matrix_to_euler_zyx(R_wc) + roll, pitch, yaw = rotation_matrix_to_euler_zyx( + R_wc + ) # ============================================================ - # Reprojektionsfehler + # Reprojektion # ============================================================ projected, _ = cv2.projectPoints( @@ -306,76 +524,126 @@ def main(): axis=1 ) - rms = np.sqrt(np.mean(reproj_error ** 2)) - max_err = np.max(reproj_error) + rms = float( + np.sqrt(np.mean(reproj_error ** 2)) + ) + + max_err = float( + np.max(reproj_error) + ) + + # ============================================================ + # Qualität + # ============================================================ + + marker_positions = np.array([ + known_markers[mid]["position"] + for mid in set(used_markers) + ]) + + marker_spread = compute_marker_spread( + marker_positions + ) + + viewing = compute_viewing_angles( + cam_pos, + known_markers, + set(used_markers) + ) + + quality_score = compute_pose_quality( + rms, + max_err, + len(set(used_markers)), + marker_spread, + viewing["mean"] + ) # ============================================================ # Ausgabe # ============================================================ + print() print("==================================================") print("KAMERA-POSE") print("==================================================") - print() + print() print("Position [m]") - print(f" X = {cam_pos[0]: .6f}") - print(f" Y = {cam_pos[1]: .6f}") - print(f" Z = {cam_pos[2]: .6f}") + print(f"X = {cam_pos[0]:.6f}") + print(f"Y = {cam_pos[1]:.6f}") + print(f"Z = {cam_pos[2]:.6f}") print() - print("Orientation [deg]") - print(f" Roll = {roll: .3f}") - print(f" Pitch = {pitch: .3f}") - print(f" Yaw = {yaw: .3f}") + print(f"Roll = {roll:.3f}") + print(f"Pitch = {pitch:.3f}") + print(f"Yaw = {yaw:.3f}") print() - - print("Reprojection Error") - print(f" RMS = {rms:.3f} px") - print(f" MAX = {max_err:.3f} px") + print("Reprojection") + print(f"RMS = {rms:.3f}px") + print(f"MAX = {max_err:.3f}px") print() + print("Quality") + print(f"Score = {quality_score:.1f}/100") + print(f"Marker Spread = {marker_spread:.3f}m") - if max_err > args.max_reprojection_error: - print("[WARNUNG] Reprojektionsfehler relativ hoch") - else: - print("[OK] Pose stabil") - - print() + if viewing["mean"] is not None: + print( + f"Mean Viewing Angle = " + f"{viewing['mean']:.1f}deg" + ) # ============================================================ # JSON speichern # ============================================================ - out = { - "camera_pose": { - "position_m": { - "x": float(cam_pos[0]), - "y": float(cam_pos[1]), - "z": float(cam_pos[2]), - }, - "orientation_deg": { - "roll": float(roll), - "pitch": float(pitch), - "yaw": float(yaw), - } + out["success"] = True + + out["camera_pose"] = { + "position_m": { + "x": float(cam_pos[0]), + "y": float(cam_pos[1]), + "z": float(cam_pos[2]), }, - "quality": { - "reprojection_rms_px": float(rms), - "reprojection_max_px": float(max_err), - "num_markers_used": len(set(used_markers)), - "markers_used": sorted(set(used_markers)) - } + "orientation_deg": { + "roll": float(roll), + "pitch": float(pitch), + "yaw": float(yaw), + }, + "rotation_matrix_world_from_camera": ( + R_wc.tolist() + ) } - out_file = Path(args.detections).with_suffix(".camera_pose.json") + out["quality"] = { + "pose_quality_score": quality_score, + "reprojection_rms_px": rms, + "reprojection_max_px": max_err, + "num_detected_markers": len(detections), + "num_used_markers": len(set(used_markers)), + "marker_spread_m": marker_spread, + "mean_viewing_angle_deg": viewing["mean"], + "max_viewing_angle_deg": viewing["max"], + "pose_stable": + max_err <= args.max_reprojection_error + } + + out["used_markers"] = sorted( + list(set(used_markers)) + ) + + out_file = Path(args.detections).with_suffix( + ".camera_pose.json" + ) with open(out_file, "w", encoding="utf-8") as f: json.dump(out, f, indent=2) - print(f"Pose gespeichert in:") + print() + print("Gespeichert:") print(out_file) diff --git a/programs/3_fuse_markers_world.py b/programs/3_fuse_markers_world.py new file mode 100644 index 0000000..538a799 --- /dev/null +++ b/programs/3_fuse_markers_world.py @@ -0,0 +1,765 @@ +#!/usr/bin/env python3 +""" +3_fuse_markers_world.py + +PHASE 1B +--------- + +Fusioniert Marker-Weltkoordinaten aus mehreren Kameras. + +EINGABE: + --json *.camera_pose.json (mehrfach möglich) + --robots robot.json + +Das Script findet automatisch: + *.aruco_detection.json + +Beispiel: + snapshot_video0_1779690911822_aruco_detection.camera_pose.json + +-> + + snapshot_video0_1779690911822_aruco_detection.json + +FEATURES: + - mehrere Kameras (2..5) + - automatische Detection-Datei-Erkennung + - bekannte Marker aus robot.json + - unbekannte Marker triangulieren + - gewichtete Marker-Fusion + - Qualitätsmetriken + - CSV Export + - JSON Export + - Kamera Export + - robuste Fehlerbehandlung + - vorbereitet für spätere Rigid-Body Constraints + +OUTPUT: + fused_markers.csv + fused_markers.json + +Benötigt: + pip install opencv-python numpy +""" + +import argparse +import csv +import json +import math +from collections import defaultdict +from pathlib import Path + +import cv2 +import numpy as np + + +# ============================================================ +# JSON HELPERS +# ============================================================ + + +def load_json(path): + + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + + + +def save_json(path, data): + + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2) + + +# ============================================================ +# FILE MATCHING +# ============================================================ + + +def find_detection_json(camera_pose_json_path): + """ + Findet automatisch die passende + *_aruco_detection.json Datei. + + Beispiel: + + INPUT: + snapshot_video0_123_aruco_detection.camera_pose.json + + OUTPUT: + snapshot_video0_123_aruco_detection.json + """ + + pose_path = Path(camera_pose_json_path) + + name = pose_path.name + + if not name.endswith(".camera_pose.json"): + raise ValueError( + f"Expected .camera_pose.json: {pose_path}" + ) + + detection_name = name.replace( + ".camera_pose.json", + ".json" + ) + + detection_path = pose_path.with_name( + detection_name + ) + + if not detection_path.exists(): + + raise FileNotFoundError( + "Matching detection JSON not found:\n" + f"{detection_path}" + ) + + return detection_path + + +# ============================================================ +# CAMERA POSE +# ============================================================ + + +def extract_camera_pose(camera_pose_data): + + if "camera_pose" not in camera_pose_data: + raise ValueError("camera_pose missing") + + pose = camera_pose_data["camera_pose"] + + pos = pose["position_m"] + + cam_pos = np.array([ + pos["x"], + pos["y"], + pos["z"] + ], dtype=np.float32) + + if "rotation_matrix_world_from_camera" in pose: + + R_wc = np.array( + pose["rotation_matrix_world_from_camera"], + dtype=np.float32 + ) + + else: + + ori = pose["orientation_deg"] + + R_wc = euler_to_rotation_matrix( + ori["roll"], + ori["pitch"], + ori["yaw"] + ) + + return R_wc, cam_pos + + +# ============================================================ +# INTRINSICS +# ============================================================ + + +def extract_intrinsics(detection_data): + + if "camera" not in detection_data: + raise ValueError("camera section missing") + + camera = detection_data["camera"] + + if "camera_matrix" not in camera: + raise ValueError("camera_matrix missing") + + if "distortion_coefficients" not in camera: + raise ValueError("distortion_coefficients missing") + + K = np.array( + camera["camera_matrix"], + dtype=np.float32 + ) + + D = np.array( + camera["distortion_coefficients"], + dtype=np.float32 + ).reshape(-1, 1) + + return K, D + + +# ============================================================ +# ROTATION HELPERS +# ============================================================ + + +def euler_to_rotation_matrix( + roll_deg, + pitch_deg, + yaw_deg +): + + r = math.radians(roll_deg) + p = math.radians(pitch_deg) + y = math.radians(yaw_deg) + + Rx = np.array([ + [1, 0, 0], + [0, math.cos(r), -math.sin(r)], + [0, math.sin(r), math.cos(r)] + ]) + + Ry = np.array([ + [math.cos(p), 0, math.sin(p)], + [0, 1, 0], + [-math.sin(p), 0, math.cos(p)] + ]) + + Rz = np.array([ + [math.cos(y), -math.sin(y), 0], + [math.sin(y), math.cos(y), 0], + [0, 0, 1] + ]) + + return Rz @ Ry @ Rx + + +# ============================================================ +# ROBOT MARKERS +# ============================================================ + + +def build_known_marker_lookup(robot_data): + """ + Nur Marker mit ABSOLUTER Weltposition. + + relPos wird in Phase 2 verwendet. + """ + + lookup = {} + + for marker in robot_data.get("Marker", []): + + marker_id = int(marker.get("id", -1)) + + if marker_id < 0: + continue + + if "position" not in marker: + continue + + pos = marker["position"] + + if pos is None: + continue + + if len(pos) != 3: + continue + + lookup[marker_id] = np.array( + pos, + dtype=np.float32 + ) + + return lookup + + +# ============================================================ +# MARKER POSE REL CAMERA +# ============================================================ + + +def estimate_marker_pose_camera( + image_points, + marker_size, + K, + D +): + + half = marker_size / 2.0 + + object_points = np.array([ + [-half, half, 0], + [half, half, 0], + [half, -half, 0], + [-half, -half, 0] + ], dtype=np.float32) + + image_points = np.array( + image_points, + dtype=np.float32 + ) + + success, rvec, tvec = cv2.solvePnP( + object_points, + image_points, + K, + D, + flags=cv2.SOLVEPNP_IPPE_SQUARE + ) + + if not success: + return None + + R_mc, _ = cv2.Rodrigues(rvec) + + return { + "rvec": rvec, + "tvec": tvec.reshape(3), + "R_mc": R_mc + } + + +# ============================================================ +# MARKER WORLD TRANSFORM +# ============================================================ + + +def marker_world_position( + cam_world_pos, + R_wc, + t_mc +): + """ + Marker Mittelpunkt in Weltkoordinaten. + + X_world = R_wc * X_cam + C + """ + + return ( + R_wc @ t_mc.reshape(3) + ) + cam_world_pos + + +# ============================================================ +# WEIGHTING +# ============================================================ + + +def compute_marker_weight( + detection, + camera_pose_data +): + """ + Qualitätsgewicht. + + Verwendet: + - confidence + - reprojection RMS + - Bildzentrum + - Markerfläche + - Sharpness + """ + + confidence = float( + detection.get("confidence", 0.5) + ) + + quality = detection.get("quality", {}) + + area_px = float( + quality.get("area_px", 1000) + ) + + sharpness = quality.get( + "sharpness", {} + ) + + lap_var = float( + sharpness.get( + "laplacian_var", + 500 + ) + ) + + geometry = quality.get( + "geometry", {} + ) + + dist_center = float( + geometry.get( + "distance_to_center_norm", + 0.5 + ) + ) + + pose_quality = camera_pose_data.get( + "quality", + {} + ) + + reproj = float( + pose_quality.get( + "reprojection_rms_px", + 10.0 + ) + ) + + reproj_weight = 1.0 / (1.0 + reproj) + + area_weight = min( + area_px / 2000.0, + 1.0 + ) + + sharpness_weight = min( + lap_var / 5000.0, + 1.0 + ) + + center_weight = 1.0 - dist_center + + weight = ( + confidence * + reproj_weight * + area_weight * + sharpness_weight * + center_weight + ) + + return max(weight, 1e-6) + + +# ============================================================ +# FUSION +# ============================================================ + + +def weighted_average(points, weights): + + points = np.array(points) + weights = np.array(weights) + + if len(points) == 1: + return points[0] + + total_weight = np.sum(weights) + + if total_weight < 1e-9: + return np.mean(points, axis=0) + + return np.sum( + points * weights[:, None], + axis=0 + ) / total_weight + + +# ============================================================ +# MAIN +# ============================================================ + + +def main(): + + parser = argparse.ArgumentParser() + + parser.add_argument( + "--json", + action="append", + required=True, + help="*.camera_pose.json" + ) + + parser.add_argument( + "--robots", + required=True, + help="robot.json" + ) + + parser.add_argument( + "--outdir", + default="." + ) + + args = parser.parse_args() + + outdir = Path(args.outdir) + + outdir.mkdir( + parents=True, + exist_ok=True + ) + + # ======================================================== + # robot.json + # ======================================================== + + robot_data = load_json( + args.robots + ) + + known_markers = build_known_marker_lookup( + robot_data + ) + + # ======================================================== + # globale Observationen + # ======================================================== + + observations = defaultdict(list) + + camera_exports = [] + + # ======================================================== + # alle Kameras + # ======================================================== + + for json_file in args.json: + + print() + print("================================================") + print("LOAD CAMERA") + print("================================================") + print(json_file) + + # ---------------------------------------------------- + # camera pose json + # ---------------------------------------------------- + + camera_pose_data = load_json( + json_file + ) + + # ---------------------------------------------------- + # detection json automatisch finden + # ---------------------------------------------------- + + detection_json = find_detection_json( + json_file + ) + + print( + f"Detection JSON:\n{detection_json}" + ) + + detection_data = load_json( + detection_json + ) + + # ---------------------------------------------------- + # intrinsics + # ---------------------------------------------------- + + K, D = extract_intrinsics( + detection_data + ) + + # ---------------------------------------------------- + # kamerapose + # ---------------------------------------------------- + + R_wc, cam_world_pos = extract_camera_pose( + camera_pose_data + ) + + camera_name = Path( + json_file + ).stem + + # ---------------------------------------------------- + # camera export + # ---------------------------------------------------- + + camera_exports.append({ + "camera": camera_name, + "x": float(cam_world_pos[0]), + "y": float(cam_world_pos[1]), + "z": float(cam_world_pos[2]) + }) + + # ---------------------------------------------------- + # detections + # ---------------------------------------------------- + + detections = detection_data.get( + "detections", + [] + ) + + print( + f"Detections: {len(detections)}" + ) + + # ---------------------------------------------------- + # marker durchlaufen + # ---------------------------------------------------- + + for det in detections: + + marker_id = int( + det["marker_id"] + ) + + marker_size = float( + det["marker_size_m"] + ) + + pose = estimate_marker_pose_camera( + det["image_points_px"], + marker_size, + K, + D + ) + + if pose is None: + continue + + world_pos = marker_world_position( + cam_world_pos, + R_wc, + pose["tvec"] + ) + + weight = compute_marker_weight( + det, + camera_pose_data + ) + + observations[marker_id].append({ + "world_pos": world_pos, + "weight": weight, + "camera": camera_name, + "confidence": float( + det.get("confidence", 0.5) + ), + "known_marker": marker_id in known_markers + }) + + # ======================================================== + # fusion + # ======================================================== + + fused_markers = [] + + print() + print("================================================") + print("FUSE MARKERS") + print("================================================") + + for marker_id, obs_list in observations.items(): + + points = [ + o["world_pos"] + for o in obs_list + ] + + weights = [ + o["weight"] + for o in obs_list + ] + + fused = weighted_average( + points, + weights + ) + + spread = 0.0 + + if len(points) > 1: + + dists = [ + np.linalg.norm(p - fused) + for p in points + ] + + spread = float( + np.mean(dists) + ) + + known = marker_id in known_markers + + mean_conf = float(np.mean([ + o["confidence"] + for o in obs_list + ])) + + mean_weight = float(np.mean(weights)) + + print( + f"Marker {marker_id:3d} | " + f"cams={len(obs_list)} | " + f"spread={spread:.4f}m | " + f"known={known}" + ) + + fused_markers.append({ + "marker_id": marker_id, + "x": float(fused[0]), + "y": float(fused[1]), + "z": float(fused[2]), + "num_cameras": len(obs_list), + "spread_m": spread, + "known_marker": known, + "mean_confidence": mean_conf, + "mean_weight": mean_weight + }) + + # ======================================================== + # CSV EXPORT + # ======================================================== + + csv_file = outdir / "fused_markers.csv" + + with open( + csv_file, + "w", + newline="", + encoding="utf-8" + ) as f: + + writer = csv.DictWriter( + f, + fieldnames=[ + "marker_id", + "x", + "y", + "z", + "num_cameras", + "spread_m", + "known_marker", + "mean_confidence", + "mean_weight" + ] + ) + + writer.writeheader() + + for row in fused_markers: + writer.writerow(row) + + # ======================================================== + # JSON EXPORT + # ======================================================== + + export_json = { + "fused_markers": fused_markers, + "cameras": camera_exports + } + + json_file = outdir / "fused_markers.json" + + save_json( + json_file, + export_json + ) + + # ======================================================== + # DONE + # ======================================================== + + print() + print("================================================") + print("EXPORT") + print("================================================") + print(csv_file) + print(json_file) + print() + + +# ============================================================ +# ENTRY +# ============================================================ + +if __name__ == "__main__": + main() diff --git a/programs/3_fuse_markers_world____.py b/programs/3_fuse_markers_world____.py new file mode 100644 index 0000000..f819099 --- /dev/null +++ b/programs/3_fuse_markers_world____.py @@ -0,0 +1,1135 @@ +#!/usr/bin/env python3 +""" +3_fuse_markers_world.py + +Phase 1: +- Liest 2 bis 5 JSON-Dateien ein, die jeweils eine Kamera-Pose und ArUco-Detections enthalten. +- Rekonstruiert für jede Marker-Beobachtung eine Marker-Pose in Weltkoordinaten. +- Fusiert alle Beobachtungen pro Marker gewichtet. +- Gibt eine CSV-Liste mit Kameras und Markern aus. +- Optional wird robots.json nur für Metadaten verwendet (nicht für die Schätzung). + +Typische Eingabe-Dateien: + snapshot_video1_1779690911822_aruco_detection.camera_pose.json + snapshot_video2_1779690911822_aruco_detection.camera_pose.json + ... + + python 3_fuse_markers_world.py \ + --json snapshot_video1_1779690911822_aruco_detection.camera_pose.json \ + --json snapshot_video2_1779690911822_aruco_detection.camera_pose.json \ + --json snapshot_video3_1779690911822_aruco_detection.camera_pose.json \ + --robots robots.json + + +Benötigt: + pip install numpy opencv-python + +Hinweis: +- Das Skript nutzt die Kameraposen als fest. +- Die Markerkoordinaten werden pro Detektion aus SolvePnP bestimmt. +- Danach werden alle Beobachtungen eines Markers robust gemittelt. +""" + +from __future__ import annotations + +import argparse +import csv +import json +import math +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any, Dict, List, Optional, Sequence, Tuple + +import cv2 +import numpy as np + + +# ============================================================ +# Datenklassen +# ============================================================ + +@dataclass +class CameraPose: + camera_id: str + source_file: str + position_w: np.ndarray # (3,) + rotation_w_from_c: np.ndarray # (3,3) + orientation_rpy_deg: Tuple[float, float, float] + quality: Dict[str, Any] = field(default_factory=dict) + + +@dataclass +class MarkerObservation: + marker_id: int + camera_id: str + source_file: str + image_points_px: np.ndarray # (4,2) + marker_size_m: float + confidence: float + quality_score: float + camera_weight: float + observation_weight: float + rvec_cm: np.ndarray # (3,) + tvec_cm: np.ndarray # (3,) + position_w: np.ndarray # (3,) + rotation_w_from_m: np.ndarray # (3,3) + reprojection_rms_px: float + reprojection_max_px: float + metadata: Dict[str, Any] = field(default_factory=dict) + + +@dataclass +class FusedMarkerEstimate: + marker_id: int + position_w: np.ndarray + rotation_w_from_m: np.ndarray + orientation_rpy_deg: Tuple[float, float, float] + observations: List[MarkerObservation] + num_cameras: int + camera_ids: List[str] + weight_sum: float + position_std_m: float + angular_std_deg: float + confidence_mean: float + confidence_min: float + confidence_max: float + quality_mean: float + quality_min: float + quality_max: float + reproj_rms_mean_px: float + reproj_rms_max_px: float + reliability_0_1: float + metadata: Dict[str, Any] = field(default_factory=dict) + + +# ============================================================ +# Basisfunktionen: Rotationen / Euler / Quaternions +# ============================================================ + + +def clamp(value: float, lo: float = 0.0, hi: float = 1.0) -> float: + return float(max(lo, min(hi, value))) + + + +def normalize_vec(v: np.ndarray, eps: float = 1e-12) -> np.ndarray: + n = float(np.linalg.norm(v)) + if n < eps: + return v.astype(np.float64, copy=True) + return (v / n).astype(np.float64) + + + +def rotation_matrix_to_euler_zyx(R: np.ndarray) -> Tuple[float, float, float]: + """Returns roll, pitch, yaw in degrees. + + Convention: + R = Rz(yaw) @ Ry(pitch) @ Rx(roll) + """ + yaw = math.degrees(math.atan2(R[1, 0], R[0, 0])) + sp = math.sqrt(R[2, 1] ** 2 + R[2, 2] ** 2) + pitch = math.degrees(math.atan2(-R[2, 0], sp)) + roll = math.degrees(math.atan2(R[2, 1], R[2, 2])) + return float(roll), float(pitch), float(yaw) + + + +def euler_zyx_to_rotation_matrix(roll_deg: float, pitch_deg: float, yaw_deg: float) -> np.ndarray: + roll = math.radians(roll_deg) + pitch = math.radians(pitch_deg) + yaw = math.radians(yaw_deg) + + cr, sr = math.cos(roll), math.sin(roll) + cp, sp = math.cos(pitch), math.sin(pitch) + cy, sy = math.cos(yaw), math.sin(yaw) + + Rx = np.array([[1, 0, 0], [0, cr, -sr], [0, sr, cr]], dtype=np.float64) + Ry = np.array([[cp, 0, sp], [0, 1, 0], [-sp, 0, cp]], dtype=np.float64) + Rz = np.array([[cy, -sy, 0], [sy, cy, 0], [0, 0, 1]], dtype=np.float64) + + return (Rz @ Ry @ Rx).astype(np.float64) + + + +def rotation_matrix_to_quaternion(R: np.ndarray) -> np.ndarray: + """Returns quaternion as [w, x, y, z].""" + m = R.astype(np.float64) + t = np.trace(m) + + if t > 0.0: + s = math.sqrt(t + 1.0) * 2.0 + w = 0.25 * s + x = (m[2, 1] - m[1, 2]) / s + y = (m[0, 2] - m[2, 0]) / s + z = (m[1, 0] - m[0, 1]) / s + elif m[0, 0] > m[1, 1] and m[0, 0] > m[2, 2]: + s = math.sqrt(1.0 + m[0, 0] - m[1, 1] - m[2, 2]) * 2.0 + w = (m[2, 1] - m[1, 2]) / s + x = 0.25 * s + y = (m[0, 1] + m[1, 0]) / s + z = (m[0, 2] + m[2, 0]) / s + elif m[1, 1] > m[2, 2]: + s = math.sqrt(1.0 + m[1, 1] - m[0, 0] - m[2, 2]) * 2.0 + w = (m[0, 2] - m[2, 0]) / s + x = (m[0, 1] + m[1, 0]) / s + y = 0.25 * s + z = (m[1, 2] + m[2, 1]) / s + else: + s = math.sqrt(1.0 + m[2, 2] - m[0, 0] - m[1, 1]) * 2.0 + w = (m[1, 0] - m[0, 1]) / s + x = (m[0, 2] + m[2, 0]) / s + y = (m[1, 2] + m[2, 1]) / s + z = 0.25 * s + + q = np.array([w, x, y, z], dtype=np.float64) + return normalize_vec(q) + + + +def quaternion_to_rotation_matrix(q: np.ndarray) -> np.ndarray: + q = normalize_vec(q) + w, x, y, z = q + + R = np.array([ + [1 - 2 * (y * y + z * z), 2 * (x * y - z * w), 2 * (x * z + y * w)], + [2 * (x * y + z * w), 1 - 2 * (x * x + z * z), 2 * (y * z - x * w)], + [2 * (x * z - y * w), 2 * (y * z + x * w), 1 - 2 * (x * x + y * y)], + ], dtype=np.float64) + return R + + + +def average_rotations_weighted(rotations: Sequence[np.ndarray], weights: Sequence[float]) -> np.ndarray: + """Averages rotations by weighted matrix sum + projection to SO(3).""" + if not rotations: + return np.eye(3, dtype=np.float64) + + M = np.zeros((3, 3), dtype=np.float64) + for R, w in zip(rotations, weights): + M += float(w) * R.astype(np.float64) + + U, _, Vt = np.linalg.svd(M) + R = U @ Vt + if np.linalg.det(R) < 0: + U[:, -1] *= -1 + R = U @ Vt + return R.astype(np.float64) + + + +def angular_distance_deg(R_a: np.ndarray, R_b: np.ndarray) -> float: + """Smallest angle between two rotations.""" + R = R_a.T @ R_b + tr = float(np.trace(R)) + cos_theta = clamp((tr - 1.0) / 2.0, -1.0, 1.0) + return float(math.degrees(math.acos(cos_theta))) + + +# ============================================================ +# JSON / Metadaten +# ============================================================ + + +def load_json(path: str) -> Dict[str, Any]: + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + + + +def detect_camera_id(data: Dict[str, Any], source_file: str) -> str: + camera = data.get("camera", {}) + camera_pose = data.get("camera_pose", {}) + + for key in ("camera_id", "id", "name"): + if isinstance(camera, dict) and camera.get(key): + return str(camera[key]) + if isinstance(camera_pose, dict) and camera_pose.get(key): + return str(camera_pose[key]) + + return Path(source_file).stem + + + +def extract_camera_pose(data: Dict[str, Any], source_file: str) -> CameraPose: + camera_id = detect_camera_id(data, source_file) + + # Camera pose may appear in different layouts. + pose_block = data.get("camera_pose") + if pose_block is None: + pose_block = data.get("camera", {}) + + if not isinstance(pose_block, dict): + raise ValueError(f"Camera pose block missing or invalid in: {source_file}") + + quality = pose_block.get("quality", {}) if isinstance(pose_block.get("quality", {}), dict) else {} + + # Position + pos = None + if isinstance(pose_block.get("position_m"), dict): + pm = pose_block["position_m"] + pos = np.array([pm.get("x", 0.0), pm.get("y", 0.0), pm.get("z", 0.0)], dtype=np.float64) + elif isinstance(pose_block.get("position_mm"), (list, tuple)) and len(pose_block["position_mm"]) == 3: + pos = np.array(pose_block["position_mm"], dtype=np.float64) / 1000.0 + elif isinstance(pose_block.get("position"), (list, tuple)) and len(pose_block["position"]) == 3: + pos = np.array(pose_block["position"], dtype=np.float64) + + if pos is None: + raise ValueError(f"Camera position missing in: {source_file}") + + # Rotation + if isinstance(pose_block.get("rotation_matrix_world_from_camera"), (list, tuple)): + R_wc = np.array(pose_block["rotation_matrix_world_from_camera"], dtype=np.float64) + elif isinstance(pose_block.get("rotation_matrix"), (list, tuple)): + R_wc = np.array(pose_block["rotation_matrix"], dtype=np.float64) + elif isinstance(pose_block.get("orientation_deg"), dict): + od = pose_block["orientation_deg"] + roll = float(od.get("roll", 0.0)) + pitch = float(od.get("pitch", 0.0)) + yaw = float(od.get("yaw", 0.0)) + R_wc = euler_zyx_to_rotation_matrix(roll, pitch, yaw) + else: + R_wc = np.eye(3, dtype=np.float64) + + if R_wc.shape != (3, 3): + raise ValueError(f"Invalid camera rotation matrix in: {source_file}") + + rpy = rotation_matrix_to_euler_zyx(R_wc) + + return CameraPose( + camera_id=camera_id, + source_file=source_file, + position_w=pos, + rotation_w_from_c=R_wc, + orientation_rpy_deg=rpy, + quality=quality, + ) + + + +def load_robot_metadata(robot_path: Optional[str]) -> Dict[int, List[Dict[str, Any]]]: + """Optional metadata only. Duplicate IDs are kept as a list.""" + if not robot_path: + return {} + + data = load_json(robot_path) + marker_meta: Dict[int, List[Dict[str, Any]]] = {} + + for entry in data.get("Marker", []): + try: + mid = int(entry.get("id")) + except Exception: + continue + + marker_meta.setdefault(mid, []).append({ + "on": entry.get("on"), + "position": entry.get("position"), + "relPos": entry.get("relPos"), + "name": entry.get("name"), + "relPosSource": entry.get("relPosSource"), + }) + + return marker_meta + + + +def summarize_robot_metadata(marker_id: int, robot_meta: Dict[int, List[Dict[str, Any]]]) -> Dict[str, Any]: + entries = robot_meta.get(marker_id, []) + if not entries: + return { + "robot_known": False, + "robot_on": None, + "robot_positions": None, + "robot_relpos_count": 0, + } + + on_list = [] + abs_pos_list = [] + rel_pos_list = [] + for e in entries: + if e.get("on") is not None: + on_list.append(str(e.get("on"))) + if e.get("position") is not None: + abs_pos_list.append(e.get("position")) + if e.get("relPos") is not None: + rel_pos_list.append(e.get("relPos")) + + return { + "robot_known": True, + "robot_on": "|".join(dict.fromkeys(on_list)) if on_list else None, + "robot_positions": abs_pos_list if abs_pos_list else None, + "robot_relpos_count": len(rel_pos_list), + } + + +# ============================================================ +# Detection / Gewichtung +# ============================================================ + + +def get_camera_quality_score(camera_pose: CameraPose) -> float: + q = camera_pose.quality or {} + + if "pose_quality_score" in q: + try: + return clamp(float(q["pose_quality_score"]) / 100.0) + except Exception: + pass + + if "reprojection_rms_px" in q: + try: + rms = float(q["reprojection_rms_px"]) + # Heuristik: 0 px -> 1.0, 5 px -> 0.5, 10 px -> ~0.33 + return clamp(1.0 / (1.0 + 0.2 * rms)) + except Exception: + pass + + return 1.0 + + + +def get_marker_size_from_detection(det: Dict[str, Any], default_size_m: float) -> float: + try: + return float(det.get("marker_size_m", default_size_m)) + except Exception: + return float(default_size_m) + + + +def score_from_range(value: Optional[float], low: float, high: float, invert: bool = False) -> float: + if value is None: + return 1.0 + if high <= low: + return 1.0 + t = (float(value) - low) / (high - low) + t = clamp(t) + return 1.0 - t if invert else t + + + +def detection_quality_score(det: Dict[str, Any]) -> float: + """Heuristischer Score in [0,1]. Falls Felder fehlen, wird 1.0 angenommen.""" + confidence = float(det.get("confidence", 1.0)) + quality = det.get("quality", {}) if isinstance(det.get("quality", {}), dict) else {} + + # Subscores + area_px = quality.get("area_px") + sharpness = (((quality.get("sharpness") or {}).get("laplacian_var")) if isinstance(quality.get("sharpness"), dict) else None) + contrast = (((quality.get("contrast") or {}).get("dynamic_range")) if isinstance(quality.get("contrast"), dict) else None) + dist_border = (((quality.get("geometry") or {}).get("distance_to_border_px")) if isinstance(quality.get("geometry"), dict) else None) + dist_center = (((quality.get("geometry") or {}).get("distance_to_center_norm")) if isinstance(quality.get("geometry"), dict) else None) + edge_ratio = quality.get("edge_ratio") + + area_score = score_from_range(area_px, 150.0, 3000.0) + sharp_score = score_from_range(sharpness, 500.0, 5000.0) + contrast_score = score_from_range(contrast, 40.0, 180.0) + border_score = score_from_range(dist_border, 20.0, 250.0) + center_score = score_from_range(dist_center, 0.75, 0.0, invert=True) # closer to center -> higher + + edge_ratio_score = 1.0 + if edge_ratio is not None: + try: + edge_ratio_score = clamp(1.0 - min(abs(float(edge_ratio) - 1.0) / 1.5, 1.0)) + except Exception: + edge_ratio_score = 1.0 + + # Weighted sum, confidence strongest + score = ( + 0.35 * clamp(confidence) + + 0.15 * area_score + + 0.15 * sharp_score + + 0.10 * contrast_score + + 0.10 * border_score + + 0.10 * center_score + + 0.05 * edge_ratio_score + ) + return clamp(score) + + + +def marker_frontality_score(rotation_m_from_cam: np.ndarray) -> float: + """Marker normal relative to camera optical axis (+Z camera). 1.0 is frontal.""" + normal_cam = rotation_m_from_cam[:, 2] + # absolute because the sign depends on marker axis convention; we only want frontality + return clamp(abs(float(normal_cam[2]))) + + + +def compute_observation_weight(camera_pose: CameraPose, det: Dict[str, Any]) -> Tuple[float, float, float]: + det_score = detection_quality_score(det) + cam_score = get_camera_quality_score(camera_pose) + # frontality will be added after pose estimation; here only base score. + base = clamp(det_score * cam_score) + return base, det_score, cam_score + + +# ============================================================ +# Marker Pose Schätzung pro Observation +# ============================================================ + + +def build_marker_object_points(marker_size_m: float) -> np.ndarray: + half = marker_size_m / 2.0 + # OpenCV ArUco corner order: TL, TR, BR, BL + return np.array([ + [-half, half, 0.0], + [ half, half, 0.0], + [ half, -half, 0.0], + [-half, -half, 0.0], + ], dtype=np.float32) + + + +def solve_marker_pose_in_camera(img_pts: np.ndarray, marker_size_m: float, K: np.ndarray, D: np.ndarray) -> Tuple[np.ndarray, np.ndarray, float, float]: + obj_pts = build_marker_object_points(marker_size_m) + + success, rvec, tvec = cv2.solvePnP( + obj_pts, + img_pts.astype(np.float32), + K, + D, + flags=cv2.SOLVEPNP_IPPE_SQUARE, + ) + + if not success: + success, rvec, tvec = cv2.solvePnP( + obj_pts, + img_pts.astype(np.float32), + K, + D, + flags=cv2.SOLVEPNP_ITERATIVE, + ) + + if not success: + raise RuntimeError("solvePnP failed for one marker observation") + + projected, _ = cv2.projectPoints(obj_pts, rvec, tvec, K, D) + projected = projected.reshape(-1, 2) + err = np.linalg.norm(projected - img_pts, axis=1) + + rms = float(np.sqrt(np.mean(err ** 2))) + mx = float(np.max(err)) + return rvec.reshape(3), tvec.reshape(3), rms, mx + + + +def observation_to_world( + camera_pose: CameraPose, + marker_id: int, + det: Dict[str, Any], + K: np.ndarray, + D: np.ndarray, + robot_meta: Dict[int, List[Dict[str, Any]]], + default_marker_size_m: float, +) -> Optional[MarkerObservation]: + if det.get("image_points_px") is None: + return None + + img_pts = np.array(det["image_points_px"], dtype=np.float32) + if img_pts.shape != (4, 2): + return None + + marker_size_m = get_marker_size_from_detection(det, default_marker_size_m) + + try: + rvec_cm, tvec_cm, reproj_rms_px, reproj_max_px = solve_marker_pose_in_camera(img_pts, marker_size_m, K, D) + except Exception: + return None + + R_cm, _ = cv2.Rodrigues(rvec_cm) + cam_weight_base, det_score, cam_score = compute_observation_weight(camera_pose, det) + frontality = marker_frontality_score(R_cm) + + # Final observation weight: base quality * frontality + obs_weight = clamp(cam_weight_base * (0.25 + 0.75 * frontality)) + if obs_weight <= 1e-9: + obs_weight = 1e-9 + + # World transform + R_wc = camera_pose.rotation_w_from_c + t_wc = camera_pose.position_w + + position_w = R_wc @ tvec_cm + t_wc + rotation_w_from_m = R_wc @ R_cm + + metadata = summarize_robot_metadata(marker_id, robot_meta) + + return MarkerObservation( + marker_id=marker_id, + camera_id=camera_pose.camera_id, + source_file=camera_pose.source_file, + image_points_px=img_pts, + marker_size_m=float(marker_size_m), + confidence=float(det.get("confidence", 1.0)), + quality_score=float(det_score), + camera_weight=float(cam_score), + observation_weight=float(obs_weight), + rvec_cm=rvec_cm.astype(np.float64), + tvec_cm=tvec_cm.astype(np.float64), + position_w=position_w.astype(np.float64), + rotation_w_from_m=rotation_w_from_m.astype(np.float64), + reprojection_rms_px=reproj_rms_px, + reprojection_max_px=reproj_max_px, + metadata=metadata, + ) + + +# ============================================================ +# Fusion pro Marker +# ============================================================ + + +def fuse_marker_observations(marker_id: int, observations: List[MarkerObservation], robot_meta: Dict[int, List[Dict[str, Any]]]) -> FusedMarkerEstimate: + if not observations: + raise ValueError("No observations to fuse") + + # Optional outlier suppression: one soft reweighting pass based on position and angle residuals. + pos_stack = np.stack([o.position_w for o in observations], axis=0) + weights = np.array([o.observation_weight for o in observations], dtype=np.float64) + weights = np.maximum(weights, 1e-9) + + # Initial estimate + pos0 = np.average(pos_stack, axis=0, weights=weights) + rot0 = average_rotations_weighted([o.rotation_w_from_m for o in observations], weights) + + # Residual-based robustification + pos_err = np.linalg.norm(pos_stack - pos0.reshape(1, 3), axis=1) + ang_err = np.array([angular_distance_deg(rot0, o.rotation_w_from_m) for o in observations], dtype=np.float64) + + # Huber-like soft downweighting + pos_scale = max(0.01, float(np.median(pos_err) + 1e-9)) + ang_scale = max(2.0, float(np.median(ang_err) + 1e-9)) + robust = 1.0 / (1.0 + (pos_err / pos_scale) ** 2 + (ang_err / ang_scale) ** 2) + + final_w = weights * robust + final_w = np.maximum(final_w, 1e-9) + + pos = np.average(pos_stack, axis=0, weights=final_w) + rot = average_rotations_weighted([o.rotation_w_from_m for o in observations], final_w) + rpy = rotation_matrix_to_euler_zyx(rot) + + camera_ids = sorted({o.camera_id for o in observations}) + source_files = sorted({Path(o.source_file).name for o in observations}) + + weight_sum = float(np.sum(final_w)) + weight_mean = float(np.mean(final_w)) + + confidence_vals = np.array([o.confidence for o in observations], dtype=np.float64) + quality_vals = np.array([o.quality_score for o in observations], dtype=np.float64) + reproj_rms_vals = np.array([o.reprojection_rms_px for o in observations], dtype=np.float64) + + pos_std_m = float(np.sqrt(np.average(np.sum((pos_stack - pos.reshape(1, 3)) ** 2, axis=1), weights=final_w))) + angular_std_deg = float(np.sqrt(np.average(np.array([angular_distance_deg(rot, o.rotation_w_from_m) ** 2 for o in observations]), weights=final_w))) + + # Reliability heuristic in [0,1] + num_obs = len(observations) + num_cams = len(camera_ids) + obs_factor = clamp(num_obs / 5.0) + cam_factor = clamp(num_cams / 3.0) + conf_factor = clamp(float(np.mean(confidence_vals))) + qual_factor = clamp(float(np.mean(quality_vals))) + spread_factor = clamp(1.0 - min(pos_std_m / 0.08, 1.0)) + reproj_factor = clamp(1.0 - min(float(np.mean(reproj_rms_vals)) / 5.0, 1.0)) + reliability = clamp( + 0.18 * obs_factor + + 0.15 * cam_factor + + 0.22 * conf_factor + + 0.15 * qual_factor + + 0.15 * spread_factor + + 0.15 * reproj_factor + ) + + metadata = summarize_robot_metadata(marker_id, robot_meta) + + return FusedMarkerEstimate( + marker_id=marker_id, + position_w=pos.astype(np.float64), + rotation_w_from_m=rot.astype(np.float64), + orientation_rpy_deg=rpy, + observations=observations, + num_cameras=num_cams, + camera_ids=camera_ids, + weight_sum=weight_sum, + position_std_m=pos_std_m, + angular_std_deg=angular_std_deg, + confidence_mean=float(np.mean(confidence_vals)), + confidence_min=float(np.min(confidence_vals)), + confidence_max=float(np.max(confidence_vals)), + quality_mean=float(np.mean(quality_vals)), + quality_min=float(np.min(quality_vals)), + quality_max=float(np.max(quality_vals)), + reproj_rms_mean_px=float(np.mean(reproj_rms_vals)), + reproj_rms_max_px=float(np.max([o.reprojection_max_px for o in observations])), + reliability_0_1=reliability, + metadata=metadata, + ) + + +# ============================================================ +# Input Handling +# ============================================================ + + +def collect_input_files(args: argparse.Namespace) -> List[str]: + files: List[str] = [] + + if args.json: + files.extend(args.json) + + if args.input_dir and args.timestamp: + base = Path(args.input_dir) + ts = str(args.timestamp) + patterns = [ + f"*_{ts}_aruco_detection.camera_pose.json", + f"*_{ts}_aruco_detection.json", + f"*_{ts}.camera_pose.json", + f"*_{ts}.json", + ] + for pattern in patterns: + files.extend(str(p) for p in sorted(base.glob(pattern))) + + # de-duplicate, keep order + seen = set() + uniq = [] + for f in files: + ff = str(Path(f)) + if ff not in seen: + seen.add(ff) + uniq.append(ff) + + return uniq + + +def find_detection_json(camera_pose_json_path): + """ + Findet automatisch die passende Detection-JSON. + + Beispiel: + xxx_aruco_detection.camera_pose.json + -> + xxx_aruco_detection.json + """ + + pose_path = Path(camera_pose_json_path) + + name = pose_path.name + + if not name.endswith(".camera_pose.json"): + raise ValueError( + f"Not a .camera_pose.json file: {pose_path}" + ) + + detection_name = name.replace( + ".camera_pose.json", + ".json" + ) + + detection_path = pose_path.with_name(detection_name) + + if not detection_path.exists(): + raise FileNotFoundError( + f"Detection JSON not found: {detection_path}" + ) + + return detection_path + + +def load_detection_json(camera_pose_json_path): + """ + Lädt automatisch die passende Detection-Datei. + """ + + detection_path = find_detection_json( + camera_pose_json_path + ) + + with open(detection_path, "r", encoding="utf-8") as f: + return json.load(f) + + +def extract_intrinsics_from_detection(detection_data): + + if "camera" not in detection_data: + raise ValueError("camera section missing") + + camera = detection_data["camera"] + + if "camera_matrix" not in camera: + raise ValueError("camera_matrix missing") + + if "distortion_coefficients" not in camera: + raise ValueError("distortion_coefficients missing") + + K = np.array( + camera["camera_matrix"], + dtype=np.float32 + ) + + D = np.array( + camera["distortion_coefficients"], + dtype=np.float32 + ).reshape(-1, 1) + + return K, D + +def extract_default_marker_size(data: Dict[str, Any], robot_data: Dict[str, Any]) -> float: + # Priority: detection JSON -> robots.json -> fallback 25 mm + try: + vc = data.get("vision_config", {}) + if isinstance(vc, dict) and vc.get("MarkerSize") is not None: + return float(vc["MarkerSize"]) + except Exception: + pass + + try: + vc = robot_data.get("vision_config", {}) + if isinstance(vc, dict) and vc.get("MarkerSize") is not None: + return float(vc["MarkerSize"]) + except Exception: + pass + + return 0.025 + + +# ============================================================ +# CSV / JSON Export +# ============================================================ + + +def fmt_float(x: Optional[float], nd: int = 6) -> str: + if x is None: + return "" + try: + if isinstance(x, float) and (math.isnan(x) or math.isinf(x)): + return "" + return f"{float(x):.{nd}f}" + except Exception: + return "" + + + +def marker_row_from_estimate(est: FusedMarkerEstimate) -> Dict[str, Any]: + robot_on = est.metadata.get("robot_on") if est.metadata else None + robot_known = est.metadata.get("robot_known") if est.metadata else None + robot_relpos_count = est.metadata.get("robot_relpos_count") if est.metadata else 0 + + return { + "kind": "marker", + "id": str(est.marker_id), + "source_file": "", + "camera_id": "", + "robot_on": robot_on or "", + "robot_known": int(bool(robot_known)), + "robot_relpos_count": int(robot_relpos_count or 0), + "x_m": est.position_w[0], + "y_m": est.position_w[1], + "z_m": est.position_w[2], + "roll_deg": est.orientation_rpy_deg[0], + "pitch_deg": est.orientation_rpy_deg[1], + "yaw_deg": est.orientation_rpy_deg[2], + "num_observations": len(est.observations), + "num_cameras": est.num_cameras, + "cameras_seen_by": "|".join(est.camera_ids), + "weight_sum": est.weight_sum, + "weight_mean": est.weight_sum / max(1, len(est.observations)), + "confidence_mean": est.confidence_mean, + "confidence_min": est.confidence_min, + "confidence_max": est.confidence_max, + "quality_mean": est.quality_mean, + "quality_min": est.quality_min, + "quality_max": est.quality_max, + "reproj_rms_mean_px": est.reproj_rms_mean_px, + "reproj_rms_max_px": est.reproj_rms_max_px, + "position_std_m": est.position_std_m, + "angular_std_deg": est.angular_std_deg, + "reliability_0_1": est.reliability_0_1, + "source_files": "|".join(est.metadata.get("source_files", []) if est.metadata else []), + "note": "", + } + + + +def camera_row_from_pose(cam: CameraPose) -> Dict[str, Any]: + roll, pitch, yaw = cam.orientation_rpy_deg + return { + "kind": "camera", + "id": cam.camera_id, + "source_file": Path(cam.source_file).name, + "camera_id": cam.camera_id, + "robot_on": "", + "robot_known": 0, + "robot_relpos_count": 0, + "x_m": cam.position_w[0], + "y_m": cam.position_w[1], + "z_m": cam.position_w[2], + "roll_deg": roll, + "pitch_deg": pitch, + "yaw_deg": yaw, + "num_observations": 0, + "num_cameras": 0, + "cameras_seen_by": cam.camera_id, + "weight_sum": "", + "weight_mean": "", + "confidence_mean": "", + "confidence_min": "", + "confidence_max": "", + "quality_mean": cam.quality.get("pose_quality_score", ""), + "quality_min": "", + "quality_max": "", + "reproj_rms_mean_px": cam.quality.get("reprojection_rms_px", ""), + "reproj_rms_max_px": cam.quality.get("reprojection_max_px", ""), + "position_std_m": "", + "angular_std_deg": "", + "reliability_0_1": get_camera_quality_score(cam), + "source_files": Path(cam.source_file).name, + "note": "", + } + + + +def write_csv(rows: List[Dict[str, Any]], out_csv: str) -> None: + if not rows: + return + + fieldnames = [ + "kind", "id", "source_file", "camera_id", + "robot_on", "robot_known", "robot_relpos_count", + "x_m", "y_m", "z_m", + "roll_deg", "pitch_deg", "yaw_deg", + "num_observations", "num_cameras", "cameras_seen_by", + "weight_sum", "weight_mean", + "confidence_mean", "confidence_min", "confidence_max", + "quality_mean", "quality_min", "quality_max", + "reproj_rms_mean_px", "reproj_rms_max_px", + "position_std_m", "angular_std_deg", + "reliability_0_1", "source_files", "note", + ] + + with open(out_csv, "w", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=fieldnames) + writer.writeheader() + for row in rows: + cleaned = {} + for key in fieldnames: + value = row.get(key, "") + if isinstance(value, np.generic): + value = value.item() + cleaned[key] = value + writer.writerow(cleaned) + + + +def write_summary_json(summary: Dict[str, Any], out_json: str) -> None: + with open(out_json, "w", encoding="utf-8") as f: + json.dump(summary, f, indent=2, ensure_ascii=False) + + +# ============================================================ +# Main Pipeline +# ============================================================ + + +def main() -> None: + parser = argparse.ArgumentParser(description="Phase 1: multi-camera world marker fusion from camera pose JSONs") + parser.add_argument("--json", action="append", help="Input JSON file (repeatable). Expected 2 to 5 files.") + parser.add_argument("--input-dir", type=str, default=None, help="Optional directory to scan") + parser.add_argument("--timestamp", type=str, default=None, help="Optional timestamp used with --input-dir") + parser.add_argument("--robots", type=str, default=None, help="Optional robots.json for metadata only") + parser.add_argument("--out-csv", type=str, default=None, help="Output CSV path") + parser.add_argument("--out-json", type=str, default=None, help="Optional summary JSON path") + parser.add_argument("--min-confidence", type=float, default=0.0, help="Filter observations below this confidence") + parser.add_argument("--verbose", action="store_true", help="Verbose output") + args = parser.parse_args() + + files = collect_input_files(args) + if len(files) < 1: + raise SystemExit("No input JSON files provided. Use --json and/or --input-dir + --timestamp.") + if len(files) > 5: + print(f"[WARN] More than 5 input JSONs found ({len(files)}). All will be processed.") + elif len(files) < 2: + print(f"[WARN] Only {len(files)} input JSON file(s) found. The pipeline still runs.") + + robot_meta = load_robot_metadata(args.robots) + + # Parse all files first + cameras: List[CameraPose] = [] + all_observations: List[MarkerObservation] = [] + all_detections_count = 0 + total_rejected = 0 + + for file_path in files: + data = load_json(file_path) + cam = extract_camera_pose(data, file_path) + cameras.append(cam) + + + detection_data = load_detection_json(json_file) + + K, D = extract_intrinsics_from_detection(detection_data) + + + default_marker_size_m = extract_default_marker_size(data, load_json(args.robots) if args.robots else {}) + + detections = data.get("detections", []) if isinstance(data.get("detections", []), list) else [] + all_detections_count += len(detections) + + if args.verbose: + print(f"[INFO] {Path(file_path).name}: camera={cam.camera_id}, detections={len(detections)}") + + for det in detections: + marker_id = det.get("marker_id") + if marker_id is None: + total_rejected += 1 + continue + + try: + marker_id_int = int(marker_id) + except Exception: + total_rejected += 1 + continue + + confidence = float(det.get("confidence", 1.0)) + if confidence < args.min_confidence: + total_rejected += 1 + continue + + obs = observation_to_world( + camera_pose=cam, + marker_id=marker_id_int, + det=det, + K=K, + D=D, + robot_meta=robot_meta, + default_marker_size_m=default_marker_size_m, + ) + if obs is None: + total_rejected += 1 + continue + + all_observations.append(obs) + + # Group observations by marker id + obs_by_marker: Dict[int, List[MarkerObservation]] = {} + for obs in all_observations: + obs_by_marker.setdefault(obs.marker_id, []).append(obs) + + # Build fused estimates + fused_markers: List[FusedMarkerEstimate] = [] + for mid in sorted(obs_by_marker.keys()): + fused = fuse_marker_observations(mid, obs_by_marker[mid], robot_meta) + # attach source files to metadata for CSV convenience + fused.metadata = dict(fused.metadata) + fused.metadata["source_files"] = sorted({Path(o.source_file).name for o in fused.observations}) + fused_markers.append(fused) + + # CSV rows: cameras + markers + rows: List[Dict[str, Any]] = [] + for cam in cameras: + rows.append(camera_row_from_pose(cam)) + for est in fused_markers: + rows.append(marker_row_from_estimate(est)) + + # Sort: cameras first, then markers by numeric id if possible + def sort_key(row: Dict[str, Any]): + kind = row.get("kind", "") + if kind == "camera": + return (0, str(row.get("id", ""))) + try: + mid = int(row.get("id", 10**9)) + except Exception: + mid = 10**9 + return (1, mid) + + rows.sort(key=sort_key) + + # Output paths + if args.out_csv: + out_csv = args.out_csv + else: + stem = Path(files[0]).stem + if "camera_pose" in stem: + stem = stem.replace(".camera_pose", "") + out_csv = str(Path(files[0]).with_name(f"{stem}_world_markers.csv")) + + if args.out_json: + out_json = args.out_json + else: + out_json = str(Path(out_csv).with_suffix(".json")) + + write_csv(rows, out_csv) + + # Summary JSON: contains the fused marker estimates plus cameras and stats. + summary = { + "summary": { + "input_files": [Path(f).name for f in files], + "num_files": len(files), + "num_cameras": len(cameras), + "num_detections_total": all_detections_count, + "num_valid_observations": len(all_observations), + "num_markers_fused": len(fused_markers), + "num_rejected_detections": total_rejected, + }, + "cameras": [ + { + "camera_id": cam.camera_id, + "source_file": cam.source_file, + "position_m": cam.position_w.tolist(), + "rotation_matrix_world_from_camera": cam.rotation_w_from_c.tolist(), + "orientation_deg": { + "roll": cam.orientation_rpy_deg[0], + "pitch": cam.orientation_rpy_deg[1], + "yaw": cam.orientation_rpy_deg[2], + }, + "quality": cam.quality, + } + for cam in cameras + ], + "markers": [ + { + "marker_id": est.marker_id, + "position_m": est.position_w.tolist(), + "rotation_matrix_world_from_marker": est.rotation_w_from_m.tolist(), + "orientation_deg": { + "roll": est.orientation_rpy_deg[0], + "pitch": est.orientation_rpy_deg[1], + "yaw": est.orientation_rpy_deg[2], + }, + "num_observations": len(est.observations), + "num_cameras": est.num_cameras, + "camera_ids": est.camera_ids, + "weight_sum": est.weight_sum, + "position_std_m": est.position_std_m, + "angular_std_deg": est.angular_std_deg, + "confidence_mean": est.confidence_mean, + "quality_mean": est.quality_mean, + "reprojection_rms_mean_px": est.reproj_rms_mean_px, + "reliability_0_1": est.reliability_0_1, + "metadata": est.metadata, + "observations": [ + { + "camera_id": o.camera_id, + "source_file": o.source_file, + "confidence": o.confidence, + "quality_score": o.quality_score, + "camera_weight": o.camera_weight, + "observation_weight": o.observation_weight, + "position_m": o.position_w.tolist(), + "rotation_matrix_world_from_marker": o.rotation_w_from_m.tolist(), + "reprojection_rms_px": o.reprojection_rms_px, + "reprojection_max_px": o.reprojection_max_px, + "metadata": o.metadata, + } + for o in est.observations + ], + } + for est in fused_markers + ], + } + write_summary_json(summary, out_json) + + print(f"[OK] CSV written: {out_csv}") + print(f"[OK] JSON written: {out_json}") + print(f"[OK] Cameras: {len(cameras)}, markers fused: {len(fused_markers)}, observations: {len(all_observations)}") + + +if __name__ == "__main__": + main() diff --git a/test/2_estimate_camera_pose_from_aruco_json.test.js b/test/2_estimate_camera_pose_from_aruco_json.test.js index d183271..9acab6e 100644 --- a/test/2_estimate_camera_pose_from_aruco_json.test.js +++ b/test/2_estimate_camera_pose_from_aruco_json.test.js @@ -11,7 +11,7 @@ const TEST_SETUP_FILE = path.join(TEST_PATH, 'data', '0_testSetup.json'); const SCRIPT_FILE = path.join(PROJECT_PATH, 'programs', '1_detect_aruco_observations.py'); const ROBOT_PATH = path.join(__dirname, 'data', 'robot', 'robot.json'); const SCRIPT_FILE_2 = path.join(PROJECT_PATH, 'programs', '2_estimate_camera_pose_from_aruco_json.py'); - +const SCRIPT_FILE_3 = path.join(PROJECT_PATH, 'programs', '3_fuse_markers_world.py'); const cam = { id : 'cam1', @@ -19,7 +19,11 @@ const cam = { intrinsics: path.join(PROJECT_PATH, 'data', 'settings','callibration_cam0.npz') }; - +const cam2 = { + id : 'cam1', + image: 'snapshot_video0_1779690911822.jpg', + intrinsics: path.join(PROJECT_PATH, 'data', 'settings','callibration_cam0.npz') +}; describe('Check if Python 2 runs', () => { @@ -61,6 +65,61 @@ describe('Check if Python 2 runs', () => { }); + test('Second File Run of Python second script', () => { + + + console.log('Intrinsics : ', cam.intrinsics); + execFileSync(PYTHON_CMD, [ + SCRIPT_FILE, + '-i', path.join(SOURCE_DIR, cam2.image), + '-npz', cam.intrinsics, + '-robot', ROBOT_PATH, + '-cameraId', cam2.id + + , + '-outDir', TARGET_DIR + ], { + stdio: 'inherit', + cwd: SOURCE_DIR // <- wichtig + }); + + + const resultFile = path.join(TARGET_DIR, 'snapshot_video0_1779690911822_aruco_detection.json'); + + if (!fs.existsSync(resultFile)) { + throw new Error(`Erwartete Datei fehlt: ${resultFile}`); + } + + + console.log('Intrinsics : ', cam.intrinsics); + execFileSync(PYTHON_CMD, [ + SCRIPT_FILE_2, + '--detections' , resultFile, + '--robots', ROBOT_PATH + ], { + stdio: 'inherit', + cwd: SOURCE_DIR // <- wichtig + }); + + }); + + + test('Second File Run of Python second script', () => { + + + console.log('Intrinsics : ', cam.intrinsics); + execFileSync(PYTHON_CMD, [ + SCRIPT_FILE_3, + '--json', path.join(TARGET_DIR, 'snapshot_video0_1779690911822_aruco_detection.camera_pose.json'), + '--json', path.join(TARGET_DIR, 'snapshot_video1_1779690911822_aruco_detection.camera_pose.json'), + '--robots', ROBOT_PATH + ], { + stdio: 'inherit', + cwd: SOURCE_DIR // <- wichtig + }); + }); + + /* // ✅ Cleanup läuft IMMER nach jedem Test afterEach(() => { diff --git a/test/data/screenShots/fused_markers.csv b/test/data/screenShots/fused_markers.csv new file mode 100644 index 0000000..468dad7 --- /dev/null +++ b/test/data/screenShots/fused_markers.csv @@ -0,0 +1,20 @@ +marker_id,x,y,z,num_cameras,spread_m,known_marker,mean_confidence,mean_weight +219,0.43451087900435764,-0.2430617527365844,0.24864745186629233,2,0.049300733586341176,False,0.5277170316988301,0.009300142928461588 +200,0.2883150365803509,0.0027948039097262806,0.09467189774796789,2,0.033606991516837784,False,0.7555202975260764,0.06883103535083403 +210,0.002038147844813181,0.018380350725407422,-0.018394701031480637,2,0.006772066645204387,True,0.6723693051501728,0.0204532377982721 +215,0.21054334774487873,-0.0718736597935183,-0.02391368422209966,2,0.013509208968825837,True,0.7724894180619204,0.08402370302052731 +197,0.30386845803628715,-0.12692615651017353,0.06409248498248943,1,0.0,False,0.6986174216600093,0.14966530971529068 +218,0.43184321660132874,-0.1704819414678139,0.16367009746963013,2,0.03802223210213124,False,0.3413914136453039,0.010365470204791368 +229,0.3602436104705841,-0.11844379401765685,0.08440112143347289,2,0.032107134962667656,False,0.8405383706616931,0.06951698019008724 +243,0.3687471932606844,-0.14650136025597116,0.042188479232535214,1,0.0,False,0.65908988611209,0.10324035134123742 +211,0.2137591400767156,0.026959799238792163,-0.028605385312781718,2,0.010891850650024732,True,0.6444060145125223,0.050073587946979366 +198,0.35259204770580493,-0.030524117439818314,0.08694698191739618,2,0.02706837734419262,False,0.7253533793498493,0.058021822336083224 +201,0.24149429994177674,0.06896595765348834,0.09401141969091542,1,0.0,False,0.4573781640909966,0.04398530324515346 +204,0.27355941290220315,0.13289470613188933,0.1235983427523017,2,0.02985425204964259,False,0.5691140927436947,0.023331477027783525 +217,0.6516780631570386,0.043108222213155606,-0.050180784675989236,2,0.049194700206082534,True,0.5355335672966184,0.014438151705364624 +196,0.3889281825540628,-0.37463423301617327,0.2628466843421774,1,0.0,False,0.9637599331074872,0.012495067650793962 +180,0.42148181203795254,-0.3888496207938902,0.3076404324887513,1,0.0,False,0.6855326216817852,0.003758399623359111 +189,0.39699505778356714,-0.414056777239273,0.2548045860642588,1,0.0,False,0.5680798096818698,0.005206949324425661 +208,0.5002433623385828,-0.10538715198248683,-0.04743817619792867,1,0.0,True,0.7535707616050168,0.006307514070673037 +214,0.41191377730374135,-0.0008334112347655465,-0.03314121580279006,1,0.0,True,0.6847250665842876,0.005021652275542729 +226,0.4275023262853984,-0.13129556163502792,0.04582380048078871,1,0.0,False,0.10322993259729876,0.0003523077820839931