-
Notifications
You must be signed in to change notification settings - Fork 37
ITEP-84336: Fix incorrect camera pose for models generated with VGGT #1139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
039c550
96d26c5
23f8d8d
0968474
491e473
154c85b
4254d2f
90d0488
74adad9
73361cf
54fdfa8
70058d8
aab521e
89f7bf4
3a1e0a7
b449578
7797509
9af0ff3
39f818d
26321bd
a9417db
a41ff1c
6395dd2
0636785
2cb8972
8730e38
d2af6a5
af4b6e6
ecd1077
726e3d4
38d7560
f57e1fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ | |
| from scene_common.mesh_util import mergeMesh | ||
| from scene_common.options import QUATERNION | ||
| from scene_common import log | ||
| from manager.serializers import CamSerializer | ||
|
|
||
| ALLOWED_VIDEO_MIME_TYPES = { | ||
| "video/mp4", | ||
|
|
@@ -157,6 +158,7 @@ def startReconstructMesh( | |
| self, | ||
| images: Dict[str, Dict], | ||
| camera_order: List[str], | ||
| camera_location_order: List, | ||
| mesh_type: str = "mesh", | ||
| uploaded_map=None, | ||
| ): | ||
|
|
@@ -178,6 +180,10 @@ def startReconstructMesh( | |
| "mesh_type": mesh_type, | ||
| } | ||
|
|
||
| camera_loc_by_id = { | ||
| cam_id: cam_loc | ||
| for cam_id, cam_loc in zip(camera_order, camera_location_order) | ||
| } | ||
| log.info(f"Sending {len(images)} images to mapping service for reconstruction") | ||
|
|
||
| files = [] | ||
|
|
@@ -201,6 +207,18 @@ def startReconstructMesh( | |
| ) | ||
| ) | ||
| files.append(("camera_ids", (None, camera_id))) | ||
| cam_loc = camera_loc_by_id.get(camera_id) | ||
| if cam_loc is not None: | ||
| cam_loc = camera_loc_by_id.get(camera_id) | ||
| if cam_loc is not None: | ||
| cam_loc_clean = { | ||
| "translation": list(cam_loc["translation"]), | ||
| "rotation": list(cam_loc["rotation"]), | ||
| "scale": list(cam_loc.get("scale", [1.0, 1.0, 1.0])), | ||
| } | ||
| files.append(("camera_locations", (None, json.dumps(cam_loc_clean)))) | ||
| else: | ||
| log.warning(f"No camera location for {camera_id}") | ||
| else: | ||
| log.warning( | ||
| f"Camera {camera_id} in camera_order but not in images dict" | ||
|
|
@@ -414,9 +432,30 @@ def startMeshGeneration(self, scene, mesh_type='mesh', uploaded_map=None): | |
| log.info(f"Collected {len(images)} images, calling mapping service") | ||
| # Call mapping service to generate mesh | ||
| # Pass camera IDs in order to ensure correct pose association | ||
| camera_order = [camera.sensor_id for camera in cameras] | ||
|
|
||
| camera_location_order = [] | ||
| camera_order = [] | ||
| serializer = CamSerializer() | ||
|
|
||
| for camera in cameras: | ||
| cam_id = camera.sensor_id | ||
| camera_order.append(cam_id) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. camera_order.append(camera.sensor_id) |
||
|
|
||
| t = serializer.get_translation(camera) | ||
| q = serializer.get_rotation(camera) | ||
| s = serializer.get_scale(camera) or [1.0, 1.0, 1.0] | ||
|
|
||
| if t is None or q is None: | ||
| raise ValueError(f"Missing pose for camera {cam_id}: t={t} q={q}") | ||
|
|
||
| camera_location_order.append({ | ||
| "translation": list(t), | ||
| "rotation": list(q), | ||
| "scale": list(s), | ||
| }) | ||
|
|
||
| started = self.mapping_client.startReconstructMesh( | ||
| images, camera_order, mesh_type, uploaded_map_path | ||
| images, camera_order, camera_location_order, mesh_type, uploaded_map_path | ||
| ) | ||
| rid = started.get("request_id") | ||
| if not rid: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |
| from werkzeug.utils import secure_filename | ||
| import uuid | ||
| import threading | ||
| import json | ||
|
|
||
| from flask import Flask, request, jsonify | ||
| from flask_cors import CORS | ||
|
|
@@ -215,6 +216,7 @@ def reconstruct3D(): | |
| image_files = request.files.getlist("images") | ||
| video_file = request.files.get("video") | ||
| camera_ids = request.form.getlist("camera_ids") | ||
| camera_locations = request.form.getlist("camera_locations", None) | ||
|
|
||
| if (not image_files) and (video_file is None): | ||
| set_status(request_id, state="failed", updated_at=time.time(), error="Provide images and/or video") | ||
|
|
@@ -228,17 +230,29 @@ def reconstruct3D(): | |
| images = None | ||
| if image_files: | ||
| images = [] | ||
| pairs = zip(image_files, camera_ids) if camera_ids else [(f, None) for f in image_files] | ||
| for f, cam_id in pairs: | ||
|
|
||
| for idx, f in enumerate(image_files): | ||
| if not f or not f.filename: | ||
| continue | ||
|
|
||
| raw = f.read() | ||
| if not raw: | ||
| continue | ||
|
|
||
| cam_id = camera_ids[idx] if idx < len(camera_ids) else None | ||
|
|
||
| cam_loc = None | ||
| if camera_locations and idx < len(camera_locations): | ||
| try: | ||
| cam_loc = json.loads(camera_locations[idx]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we should log that camera_locations[idx] is not a valid json. Because on runtime we wouldn't know if something was provided but invalid or just empty and everything is fine |
||
| except Exception: | ||
| cam_loc = None | ||
|
|
||
| images.append({ | ||
| "filename": secure_filename(f.filename), | ||
| "camera_id": cam_id, | ||
| "data": base64.b64encode(raw).decode("utf-8"), | ||
| "filename": secure_filename(f.filename), | ||
| "camera_id": cam_id, | ||
| "camera_location": cam_loc, # Only populated if provided | ||
| "data": base64.b64encode(raw).decode("utf-8"), | ||
| }) | ||
|
|
||
| if not images: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant if statement