WildDet3D

repository·main·Indexed 20 days ago

https://github.com/allenai/wilddet3d

A project for scaling promptable 3D detection in the wild, providing models, datasets, and tools for 3D object detection using text, point, and box prompts. It includes an end-to-end integration with Meta FAIR's Boxer framework for indoor labeling, a zero-shot 3D object tracking pipeline, a Gradio-based interactive demo, and an iPhone app supporting real-time on-device detection via ARKit and LiDAR.

Tokens
24.3K
Snippets
72
Records
98
Agent score
65%

What's inside WildDet3D

  1. WildDet3D iPhone App Features

    main

    The WildDet3D iPhone app provides real-time on-device 3D object detection using ARKit and LiDAR depth. Key features include:

    • Camera mode: AR-based 3D detection with LiDAR depth alignment.
    • Upload mode: Detect objects in existing photos from your library.
    • RGB / RGBD modes: Supports both monocular (RGB) and depth-enhanced (RGBD) detection.
    • Interactive boxes: Allows you to tap to select, view dimensions, or delete individual detections.
    • Open-vocabulary: Enables detection of any object category via text prompts.
  2. Understand WildDet3D evaluation metrics

    main

    The evaluation reports several key metrics to assess 3D detection performance:

    • AP (Average Precision): COCO-style 3D IoU. For ScanNet, Argoverse2, In-the-Wild, and DROID, the evaluator uses center-distance (dist / prox) matching.
    • ATE / ASE / AOE: Mean translation, scale, and orientation error of matched detections.
    • ODS / ODS_Sym / ODS_Canonical: nuScenes-style Open Detection Score. ODS_Canonical uses canonical-rotation AOE and is the primary ranking metric for open-vocabulary benchmarks.
    • AP_<Subset>: Specific AP reported for Omni3D sub-datasets (e.g., KITTI, nuScenes, SUNRGBD, etc.).
    • Base / Novel Split: Evaluators distinguish between 'Base' (canonical categories like the 15 SUNRGBD indoor categories or 11 AV2 driving categories) and 'Novel' (everything else).
  3. How temporal smoothing works in the tracking pipeline

    main

    To ensure smooth trajectories, the pipeline applies two different smoothing techniques:

    1. Kalman Filter: Applied to the 3D center position and dimensions. The state vector is [cx, cy, cz, w, l, h, vx, vy, vz] (position + dimensions + velocity), and the observation is [cx, cy, cz, w, l, h] from WildDet3D.
    2. Exponential Moving Average (EMA): Applied separately to rotation quaternions.

    Post-processing steps:

    • Yaw normalization: Quaternion yaw is normalized to [0, pi) to resolve 180-degree ambiguity.
    • 90-degree flip fix: For near-square objects (where $w/l > 0.7$), the pipeline resolves 90-degree symmetry ambiguity to ensure temporal yaw consistency.
  4. Understand WildDet3D Prompt Modes

    main

    WildDet3D supports 5 distinct prompt modes for 3D object detection. Note that input_boxes and input_points must be provided in original-image pixel coordinates.

    ModePrompt InputBehaviorUse Case
    Textinput_textsDetect all instances of given categoriesOpen-vocabulary
    Visualinput_boxes + prompt_text="visual"Use box as visual example, find similar objectsOne-to-many matching
    Visual+Labelinput_boxes + prompt_text="visual: <label>"Visual example with category constraintFiltered one-to-many
    Geometricinput_boxes + prompt_text="geometric"Lift the given 2D box to 3DOne-to-one
    Geometric+Labelinput_boxes + prompt_text="geometric: <label>"Lift 2D box to 3D with category labelOne-to-one with label

    Point Prompts: input_points (format (x, y, label) where label=1 is positive) work with any prompt_text. In geometric mode, they are also one-to-one (returns the proposal containing the most positive points).

  5. WildDet3D to Boxer OBB Adapter implementation details

    main

    The integration relies on the wilddet3d_to_obb() adapter in run_wilddet3d.py to align WildDet3D outputs with Boxer's ObbTW requirements. Two key alignments are performed:

    1. Pose Chain: WildDet3D returns 3D boxes in the camera frame. Boxer expects them in the world frame. The transformation used is: T_world_camera = T_world_rig @ T_camera_rig.inverse(), utilizing Boxer's cam.T_camera_rig attribute.

    2. Axis Convention: WildDet3D's RoI2Det3D outputs [center(3), dims=(W,L,H)(3), quat_wxyz(4)] with a local box frame of x=L, y=H, z=W. Boxer's bb3_object keeps the vertical axis on z. To align them, the adapter rotates the box 90 degrees around z and maps dimensions as bb3 = (L=x, W=y, H=z). This allows the quaternion to be used as-is without extra rotation, ensuring boxes align correctly with vertical objects like walls or paintings.

  6. Unprojection and Projection in FoundationPose GSO

    main

    Because the dataset uses OpenGL convention, use the following formulas for coordinate transformations.

    Unprojection (pixel + depth $\rightarrow$ 3D)

    To convert pixel coordinates (px, py) and metric depth d to OpenGL camera space:

    • $X_{gl} = (px - cx) \cdot d / fx$
    • $Y_{gl} = -(py - cy) \cdot d / fy$ (negated because pixel Y is down, OpenGL Y is up)
    • $Z_{gl} = -d$ (camera looks along -Z)

    To convert to OpenCV camera space (X-right, Y-down, Z-forward):

    • $X_{cv} = X_{gl}$
    • $Y_{cv} = -Y_{gl}$
    • $Z_{cv} = -Z_{gl}$

    Projection (world $\rightarrow$ pixel)

    Using row-vector convention:

    1. p_clip = p_world @ V @ P
    2. ndc = p_clip[:2] / p_clip[3] (where p_clip[3] is clip_w, which is -z_eye in OpenGL)
    3. px = (ndc[0] + 1) / 2 * width
    4. py = (1 - ndc[1]) / 2 * height (flip Y: NDC Y-up $\rightarrow$ pixel Y-down)
    # Unprojection to OpenCV
    X_cv = X_gl
    Y_cv = -Y_gl
    Z_cv = -Z_gl
    
    # Projection
    p_clip = p_world @ V @ P
    dc = p_clip[:2] / p_clip[3]
    px = (ndc[0] + 1) / 2 * width
    py = (1 - ndc[1]) / 2 * height
  7. Understand VLM modes for 3D object detection

    main

    The VLM-driven demo uses a Vision-Language Model to translate natural language queries (e.g., "Detect all the sheep in this image") into spatial prompts that guide WildDet3D. There are two supported modes based on the VLM used:

    • box mode: Uses Qwen3-VL-8B to generate 2D bounding boxes via tool calling.
    • point mode: Uses Molmo2-8B to generate 2D points via native pointing.
  8. Naming Convention for FoundationPose GSO Dataset Files

    main

    Files in the FoundationPose GSO dataset follow specific naming patterns based on whether they are per-view (camera-specific) or per-scene.

    Per-view files: {group_id}_scene_{scene_id:08d}_cam_{cam_id}.{ext}

    • group_id: Numeric scene group identifier (e.g., 1004491151)
    • scene_id: 8-digit zero-padded scene index (e.g., 00000412)
    • cam_id: Camera index (0 or 1)
    • Example: 4280099961_scene_00000412_cam_1.png

    Per-scene files: {group_id}_scene_{scene_id:08d}_states.json

    4280099961_scene_00000412_cam_1.png
  9. Understand the WildDet3D 3-Stage Training Pipeline

    main

    WildDet3D uses a progressive 3-stage training pipeline to scale from indoor/outdoor benchmarks to diverse in-the-wild data:

    1. Stage 1: Omni3D Canonical (12 epochs): Trains on Omni3D with canonical rotation using a 5-mode collator (text + box geometry prompts).
    2. Stage 2: All-Data Dense Finetune (12 epochs): Uses the Stage 1 checkpoint to train on 8 datasets (human-only ITW + V3Det) using the 5-mode collator (text + box geometry prompts; no mask).
    3. Stage 3: High-Quality Mix-Prompt Finetune (3 epochs): Uses the Stage 2 checkpoint to finetune on a high-quality mix (90% Omni3D + 10% ITW human) using the mask_pt collator (text + box + point prompts; points sampled from masks).
  10. FoundationPose GSO Instance Mappings

    main

    To link semantic IDs from masks to actual objects, use the files in annotations/instance_mappings/gso/.

    • mapping.json: Maps semantic IDs (from mask pixels) to USD prim paths.
    • semantics.json: Maps semantic IDs to lowercased class names.

    Example Mapping:

    • Mask pixel 10 $\rightarrow$ mapping.json $\rightarrow$ /World/objects/gso_Perricone_MD_Nutritive_Cleanser/model/mesh.
    // mapping.json
    {
      "0": "BACKGROUND",
      "10": "/World/objects/gso_Perricone_MD_Nutritive_Cleanser/model/mesh"
    }
  11. Expected data layout under `data/`

    main

    WildDet3D expects a specific directory structure under the data/ root for various datasets. Most datasets require an annotations/ subdirectory containing JSON files and .hdf5 archives for images and depth.

    Key layout patterns:

    • Omni3D: data/omni3d/annotations/*.json and data/cache_omni3d50/.
    • CubifyAnything: data/cubifyanything/annotations/*.json, data/cubifyanything/data.hdf5, and data/cubifyanything/depth_gt.hdf5.
    • Waymo: data/waymo/annotations/*.json, data/waymo/images.hdf5, and data/waymo/depth.hdf5.
    • 3EED: data/3eed/annotations/*.json, data/3eed/3eed_dataset.hdf5, and data/3eed/depth/.
    • FoundationPose: data/foundationpose/annotations/*.json, data/foundationpose/images_jpg.hdf5, and data/foundationpose/depth.hdf5.
    • In-the-Wild: data/in_the_wild/annotations/*.json and data/in_the_wild/images/.
    • Masks (Stage 3 only): data/masks/{lvis,coco,obj365,v3det}/.
    • Pretrained: pretrained/sam3/sam3_detector.pt.
    data/
    ├── omni3d/
    │   ├── annotations/                # KITTI / nuScenes / SUNRGBD / Hypersim / ARKitScenes / Objectron _{train,val,test}.json
    │   └── cache_omni3d50/              # auto-built on first run
    ├── KITTI_object/
    ├── KITTI_object.hdf5
    ├── KITTI_object_depth.hdf5
    ├── nuscenes/
    ├── nuscenes.hdf5
    ├── nuscenes_depth.hdf5
    ├── SUNRGBD/
    ├── hypersim/
    ├── hypersim.hdf5
    ├── hypersim_depth.hdf5
    ├── ARKitScenes/
    ├── ARKitScenes.hdf5
    ├── ARKitScenes_depth.hdf5
    ├── objectron/
    ├── objectron.hdf5
    ├── objectron_depth.hdf5
    ├── cubifyanything/
    │   ├── annotations/                # CubifyAnything_{train,val}.json
    │   ├── data.hdf5
    │   └── depth_gt.hdf5
    ├── waymo/
    │   ├── annotations/                # Waymo_{train,val}.json
    │   ├── images.hdf5
    │   └── depth.hdf5
    ├── 3eed/
    │   ├── annotations/                # 3EED_{det,ref}_{train,val}.json
    │   ├── 3eed_dataset.hdf5
    │   └── depth/
    ├── foundationpose/
    │   ├── annotations/                # FoundationPose_{train,val}.json
    │   ├── images_jpg.hdf5
    │   └── depth.hdf5
    ├── in_the_wild/
    │   ├── annotations/                # InTheWild_v3_{train,val,test,...}.json
    │   └── images/
    ├── masks/                           # Stage 3 only
    │   ├── lvis/
    │   ├── coco/
    │   ├── obj365/
    │   └── v3det/
    └── pretrained/
        └── sam3/
            └── sam3_detector.pt
  12. Run WildDet3D evaluation via vis4d

    main

    WildDet3D evaluation is performed using the vis4d framework. To run an evaluation, use the vis4d test command, specifying the benchmark configuration file and your model checkpoint.

    General Command Format:

    vis4d test --config configs/eval/<benchmark>/<mode>.py --gpus 1 --ckpt <path_to_checkpoint>
    vis4d test --config configs/eval/<benchmark>/<mode>.py \
        --gpus 1 --ckpt ckpt/wilddet3d.pt