LeviTor: 3D Trajectory-Oriented Image-to-Video Synthesis

repository·main·Indexed 41 days ago

https://github.com/ant-research/levitor

A 3D trajectory-oriented image-to-video synthesis framework (CVPR 2025 Highlight) that enables video generation control via 2D trajectories and relative depth values to simulate 3D motion. The project integrates CoTracker for point tracking, Depth Anything V2 for metric depth estimation, Segment Anything (SAM), and Stable Video Diffusion (SVD).

Tokens
4.8K
Snippets
14
Records
18
Agent score
51%

What's inside LeviTor

  1. How CoTracker tracking modes work

    main

    CoTracker is a transformer-based model capable of tracking points in a video using two primary approaches:

    1. Grid Sampling: Points are sampled on a regular grid (e.g., grid_size=10 creates a 10x10 grid) on the first frame.
    2. Manual/Quasi-dense Selection: The model can track any specific pixel or a quasi-dense set of pixels selected by the user.

    It provides benefits similar to Optical Flow but allows for tracking specific, long-term trajectories across frames.

  2. Download required checkpoints

    main

    LeviTor requires several external and project-specific checkpoints. Create a checkpoints directory and organize them as follows:

    1. Depth Anything V2: Download depth_anything_v2_vitl.pth from Depth Anything V2.
    2. Segment Anything (SAM): Download sam_vit_h_4b8939.pth from Segment Anything.
    3. Stable Video Diffusion (SVD): Download stable-video-diffusion-img2vid-xt from stabilityai.
    4. LeviTor Checkpoints: Create a LeviTor subdirectory inside checkpoints and download the weights from LeviTor Hugging Face.

    Required Directory Structure:

    checkpoints/
     |-- sam_vit_h_4b8939.pth
     |-- depth_anything_v2_vitl.pth
     |-- stable-video-diffusion-img2vid-xt/
     |-- LeviTor/
         |-- random_states_0.pkl
         |-- scaler.pt
         |-- scheduler.bin
         |-- controlnet/
         |-- unet/
  3. Install CoTracker locally

    main

    To run local demos, evaluate, or train the model, install CoTracker from the GitHub repository. Ensure you have PyTorch and TorchVision installed (ideally with CUDA support).

    git clone https://github.com/facebookresearch/co-tracker
    cd co-tracker
    pip install -e .
    pip install matplotlib flow_vis tqdm tensorboard imageio[ffmpeg]
  4. How to use the LeviTor interactive demo

    main

    The Gradio interface allows for 3D trajectory-oriented video synthesis through the following workflow:

    1. Upload Start Image: Use the Upload Start Image button to provide your source image.
    2. Select Area (SAM):
      • Click Select Area with SAM and click on the image.
      • Use the Add SAM Point? box: Input 1 if the clicked point is inside the target area, or 0 if it is outside (to define the background/uninterested area).
    3. Draw 3D Trajectory:
      • Click Add New Drag Trajectory and click a series of points to draw a 2D path.
      • Observe the Depths for reference box to see the depth values of your clicked points.
      • In the Input depth values here box, enter normalized depth values (range 0 to 1).
        • Note: These are relative depths. Smaller values move the area closer to the camera; larger values move it further away.
        • The number of input values must match the number of points in the reference box.
    4. Configure Inference:
      • In Input number of points for inference here, enter a ratio.
        • Small ratio: Better for non-rigid body motion.
        • Large ratio: Better for rigid body motion.
    5. Generate: Click Run to synthesize the video.

    Pro-tips:

    • Multiple Trajectories: You can draw multiple trajectories to control different parts of the scene.
    • Orbiting Effects: To create an orbiting effect, select a reference object and create a stationary path for it. Set its depth (e.g., 0.1). Then, adjust the orbiting object's depth values relative to that: values > 0.1 move it behind the reference, and values < 0.1 move it in front.
  5. Setup LeviTor environment

    main

    Follow these steps to install LeviTor and its dependencies. This requires conda and pip.

    1. Clone the repository:

      git clone https://github.com/qiuyu96/LeviTor.git
      cd LeviTor
    2. Create the Conda environment:

      conda create -n LeviTor python=3.9 -y
      conda activate LeviTor
    3. Install dependencies:

      pip install -r requirements.txt
      pip install "git+https://github.com/facebookresearch/pytorch3d.git"
      pip install gradio==4.36.1
    git clone https://github.com/qiuyu96/LeviTor.git
    cd LeviTor
    conda create -n LeviTor python=3.9 -y
    conda activate LeviTor
    pip install -r requirements.txt
    pip install "git+https://github.com/facebookresearch/pytorch3d.git"
    pip install gradio==4.36.1
  6. Use CoTracker in Offline mode via PyTorch Hub

    main

    The easiest way to use CoTracker is to load a pretrained model from torch.hub. In offline mode, you pass the entire video tensor to the model at once. This is suitable for videos where the full content is available.

    Requirements:

    • pip install imageio[ffmpeg]
    • A video loaded as a tensor with shape [B, T, C, H, W] (Batch, Time, Channels, Height, Width).
    import torch
    import imageio.v3 as iio
    
    # Load video
    url = 'https://github.com/facebookresearch/co-tracker/blob/main/assets/apple.mp4'
    frames = iio.imread(url, plugin="FFMPEG")
    
    device = 'cuda'
    grid_size = 10
    # Prepare video tensor: B T C H W
    video = torch.tensor(frames).permute(0, 3, 1, 2)[None].float().to(device)
    
    # Load and run CoTracker2
    cotracker = torch.hub.load("facebookresearch/co-tracker", "cotracker2").to(device)
    pred_tracks, pred_visibility = cotracker(video, grid_size=grid_size)
    # pred_tracks shape: [B, T, N, 2]
    # pred_visibility shape: [B, T, N, 1]
  7. Use CoTracker in Online mode via PyTorch Hub

    main

    Online mode uses a different API designed for memory efficiency and processing longer videos or streams. It processes the video in chunks.

    Workflow:

    1. Load the cotracker2_online model.
    2. Initialize processing with the first chunk using is_first_step=True.
    3. Iterate through subsequent video chunks using the model's step attribute to determine chunk size.
    import torch
    
    device = 'cuda'
    grid_size = 10
    # video tensor shape: [B, T, C, H, W]
    
    cotracker = torch.hub.load("facebookresearch/co-tracker", "cotracker2_online").to(device)
    
    # Initialize online processing
    cotracker(video_chunk=video, is_first_step=True, grid_size=grid_size)
    
    # Process the video in chunks
    for ind in range(0, video.shape[1] - cotracker.step, cotracker.step):
        pred_tracks, pred_visibility = cotracker(
            video_chunk=video[:, ind : ind + cotracker.step * 2]
        )
  8. Setup Depth Anything V2 for Metric Depth Estimation

    main

    To use the metric depth estimation codebase, clone the repository, navigate to the metric_depth directory, and install the required dependencies.

    Note: You must download the pre-trained checkpoints and place them in a checkpoints directory within the metric_depth folder.

    git clone https://github.com/DepthAnything/Depth-Anything-V2
    cd Depth-Anything-V2/metric_depth
    pip install -r requirements.txt
  9. Use the CoTracker Gradio web interface

    main

    The project includes a Gradio-based web application for interactive video tracking. When launched, it provides a UI with the following controls:

    • Input video: Upload a .mp4 video (landscape orientation recommended, 2-7 seconds for optimal speed).
    • Grid Size: A slider (1-30) to set the square grid dimension.
    • Grid Query Frame: A slider (0-30) to specify the starting frame for tracking.
    • Visualize Track Traces: A checkbox to enable/disable the visualization of point paths.

    Running the script app.py will launch the interface locally and provide a shareable URL.

    python cotracker/project/gradio_demo/app.py
  10. Run the LeviTor Gradio demo

    main

    Execute the interactive Gradio demo using the following command. Ensure you are in the LeviTor root directory and have the checkpoints folder populated.

    Command Arguments:

    • --frame_interval: Interval between frames.
    • --num_frames: Total number of frames to generate.
    • --pretrained_model_name_or_path: Path to the SVD checkpoint.
    • --resume_from_checkpoint: Path to the LeviTor checkpoint directory.
    • --width / --height: Output resolution.
    • --seed: Random seed for reproducibility.
    • --mixed_precision: Precision mode (e.g., fp16).
    • --enable_xformers_memory_efficient_attention: Enables memory-efficient attention via xformers.
    • --output_dir: Directory to save generated videos.
    • --gaussian_r: Gaussian radius parameter.
    • --sam_path: Path to the SAM checkpoint.
    • --depthanything_path: Path to the Depth Anything V2 checkpoint.
    python gradio_demo/gradio_run.py --frame_interval 1 --num_frames 16 --pretrained_model_name_or_path checkpoints/stable-video-diffusion-img2vid-xt --resume_from_checkpoint checkpoints/LeviTor --width 288 --height 512 --seed 217113 --mixed_precision fp16 --enable_xformers_memory_efficient_attention --output_dir ./outputs --gaussian_r 10 --sam_path checkpoints/sam_vit_h_4b8939.pth --depthanything_path checkpoints/depth_anything_v2_vitl.pth
  11. Use DepthAnythingV2 in Python API

    main

    You can integrate the metric depth model into your Python workflows using the DepthAnythingV2 class.

    Key Parameters:

    • encoder: One of 'vits', 'vitb', or 'vitl'.
    • max_depth: Set to 20 for indoor (Hypersim) models and 80 for outdoor (Virtual KITTI 2) models.

    Method:

    • infer_image(raw_img): Takes a numpy image and returns an $H imes W$ depth map in meters as a numpy array.
    import cv2
    import torch
    from depth_anything_v2.dpt import DepthAnythingV2
    
    model_configs = {
        'vits': {'encoder': 'vits', 'features': 64, 'out_channels': [48, 96, 192, 384]},
        'vitb': {'encoder': 'vitb', 'features': 128, 'out_channels': [96, 192, 384, 768]},
        'vitl': {'encoder': 'vitl', 'features': 256, 'out_channels': [256, 512, 1024, 1024]}
    }
    
    encoder = 'vitl' # or 'vits', 'vitb'
    dataset = 'hypersim' # 'hypersim' for indoor model, 'vkitti' for outdoor model
    max_depth = 20 # 20 for indoor model, 80 for outdoor model
    
    model = DepthAnythingV2(**{**model_configs[encoder], 'max_depth': max_depth})
    model.load_state_dict(torch.load(f'checkpoints/depth_anything_v2_metric_{dataset}_{encoder}.pth', map_location='cpu'))
    model.eval()
    
    raw_img = cv2.imread('your/image/path')
    depth = model.infer_image(raw_img) # HxW depth map in meters in numpy