> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/datadesigner/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/datadesigner/_mcp/server.

# Autonomous Vehicle Traffic Scenarios

> Generate synthetic autonomous-vehicle ego-camera images with controlled road, weather, lighting, and long-tail hazard variation.

[Download the complete recipe script](https://github.com/NVIDIA-NeMo/DataDesigner/blob/main/fern/assets/recipes/image_generation/traffic_scenarios.py)

```python
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "data-designer",
# ]
# ///
"""Autonomous Vehicle Traffic Scenario Image Generation Recipe

Generate synthetic autonomous-vehicle ego-camera images with controlled
variation over region, road type, weather, time of day, traffic density,
surface condition, traffic controls, and long-tail scenario elements. Use the
generated images for perception review sets, visual QA, or
simulator-validation prompts.

Synthetic images are not a replacement for real sensor logs, simulator runs, or
safety validation. They are useful for rapidly creating controlled visual
examples around rare or hazardous conditions.

Prerequisites:
    - An image-generation provider key for the selected model. The defaults use
      OpenRouter, so set OPENROUTER_API_KEY before running.

Run:
    uv run traffic_scenarios.py --num-records 10
"""

from __future__ import annotations

import argparse
from pathlib import Path

import data_designer.config as dd
from data_designer.interface import DataDesigner, DatasetCreationResults

DEFAULT_MODEL_PROVIDER = "openrouter"
DEFAULT_MODEL_ID = "google/gemini-3.1-flash-image-preview"
DEFAULT_MODEL_ALIAS = "traffic-scene-model"


def build_model_configs(
    *,
    model_provider: str,
    model_id: str,
    model_alias: str,
    image_size: str,
    aspect_ratio: str,
    max_parallel_requests: int,
) -> list[dd.ModelConfig]:
    """Build a provider-agnostic image-generation model config."""
    return [
        dd.ModelConfig(
            alias=model_alias,
            model=model_id,
            provider=model_provider,
            inference_parameters=dd.ImageInferenceParams(
                extra_body={
                    "modalities": ["image", "text"],
                    "image_config": {
                        "aspect_ratio": aspect_ratio,
                        "image_size": image_size,
                    },
                },
                max_parallel_requests=max_parallel_requests,
            ),
            skip_health_check=True,
        )
    ]


def add_category(config_builder: dd.DataDesignerConfigBuilder, name: str, values: list[str]) -> None:
    """Add a categorical sampler column."""
    config_builder.add_column(
        dd.SamplerColumnConfig(
            name=name,
            sampler_type=dd.SamplerType.CATEGORY,
            params=dd.CategorySamplerParams(values=values),
        )
    )


def build_config(
    *,
    model_provider: str = DEFAULT_MODEL_PROVIDER,
    model_id: str = DEFAULT_MODEL_ID,
    model_alias: str = DEFAULT_MODEL_ALIAS,
    image_size: str = "1K",
    aspect_ratio: str = "16:9",
    max_parallel_requests: int = 10,
) -> dd.DataDesignerConfigBuilder:
    """Build an autonomous-vehicle ego-camera image-generation pipeline."""
    model_configs = build_model_configs(
        model_provider=model_provider,
        model_id=model_id,
        model_alias=model_alias,
        image_size=image_size,
        aspect_ratio=aspect_ratio,
        max_parallel_requests=max_parallel_requests,
    )
    config_builder = dd.DataDesignerConfigBuilder(model_configs=model_configs)

    add_category(
        config_builder,
        "geographic_region",
        [
            "US - dense urban (NYC-style)",
            "US - sprawling suburban (Los Angeles-style)",
            "US - rural Midwest",
            "Europe - narrow streets (Italian/French town)",
            "Europe - orderly infrastructure (German autobahn)",
            "Asia - mixed traffic (India/Thailand)",
            "Asia - modern cityscape (Singapore/Tokyo)",
        ],
    )

    add_category(
        config_builder,
        "road_type",
        [
            "urban city street with tall buildings",
            "urban street with mixed retail/residential",
            "suburban residential street with trees",
            "suburban commercial strip with parking lots",
            "highway - 3 lanes each direction",
            "highway - 5 lanes each direction with HOV",
            "rural two-lane country road",
            "rural highway with sparse markings",
            "mountain road with curves and guardrails",
            "coastal road with scenic views",
            "bridge - suspension or arch style",
            "bridge - concrete overpass",
            "tunnel - well-lit with ceiling lights",
            "tunnel - dim lighting",
            "parking lot - shopping center",
            "parking garage - multi-level",
            "intersection - 4-way with traffic lights",
            "intersection - complex 6-way",
            "roundabout - single lane",
            "roundabout - multi-lane",
            "construction zone with detour",
            "school zone with crossing",
        ],
    )

    add_category(
        config_builder,
        "weather",
        [
            "clear sunny day",
            "partly cloudy",
            "overcast with gray skies",
            "light rain - misty windshield",
            "moderate rain - active wipers",
            "heavy rain - reduced visibility under 100ft",
            "light fog - moderate visibility",
            "dense fog - visibility under 50ft",
            "light snow - flurries",
            "moderate snow - accumulating on road",
            "heavy snow - whiteout conditions",
            "sleet/freezing rain",
            "dust storm - desert conditions",
            "high winds - debris visible",
        ],
    )

    add_category(
        config_builder,
        "time_of_day",
        [
            "dawn - pre-sunrise twilight",
            "early morning - golden hour light",
            "mid-morning - bright sun, long shadows",
            "midday - overhead sun, minimal shadows",
            "afternoon - sun starting to lower",
            "late afternoon - golden hour",
            "dusk - post-sunset twilight",
            "night - well-lit with streetlights",
            "night - moderately lit urban",
            "night - poorly lit rural",
            "night - headlights only, no street lighting",
        ],
    )

    add_category(
        config_builder,
        "traffic_density",
        [
            "empty - no other vehicles visible",
            "sparse - 1-2 vehicles in distance",
            "light - 3-5 vehicles visible",
            "moderate - steady flow of traffic",
            "heavy - congested, slow-moving",
            "stop-and-go - bumper-to-bumper",
        ],
    )

    sparse_vehicle_mix = [
        "sedans and compact cars",
        "mix of cars and SUVs",
        "includes large trucks/semi-trailers",
        "includes buses",
        "includes motorcycles and scooters",
        "includes bicycles and e-bikes",
        "includes delivery vans/box trucks",
    ]
    flowing_vehicle_mix = [*sparse_vehicle_mix, "mixed vehicle types - diverse traffic"]
    config_builder.add_column(
        dd.SamplerColumnConfig(
            name="vehicle_mix",
            sampler_type=dd.SamplerType.SUBCATEGORY,
            params=dd.SubcategorySamplerParams(
                category="traffic_density",
                values={
                    "empty - no other vehicles visible": ["no other vehicles visible"],
                    "sparse - 1-2 vehicles in distance": sparse_vehicle_mix,
                    "light - 3-5 vehicles visible": flowing_vehicle_mix,
                    "moderate - steady flow of traffic": flowing_vehicle_mix,
                    "heavy - congested, slow-moving": flowing_vehicle_mix,
                    "stop-and-go - bumper-to-bumper": flowing_vehicle_mix,
                },
            ),
        )
    )

    add_category(
        config_builder,
        "scenario_element",
        [
            "pedestrian crossing at marked crosswalk",
            "pedestrian jaywalking mid-block",
            "pedestrian with stroller/wheelchair",
            "group of pedestrians crossing",
            "child chasing ball toward street",
            "jogger/runner on shoulder",
            "pedestrian wearing dark clothing at night",
            "pedestrian with umbrella obscuring face in rain",
            "elderly pedestrian crossing slowly with walker",
            "pedestrian distracted by phone while crossing",
            "pedestrians exiting parked bus on roadside",
            "crowd spilling onto road from sidewalk event",
            "cyclist in dedicated bike lane",
            "cyclist merging into traffic lane",
            "cyclist making left turn",
            "cyclist riding against traffic on wrong side",
            "e-scooter rider weaving between cars",
            "e-scooter rider on sidewalk entering crosswalk",
            "group of cyclists in paceline on shoulder",
            "cyclist with cargo trailer taking full lane",
            "motorcycle lane splitting",
            "motorcycle filtering through stopped traffic",
            "motorcycle approaching from blind spot",
            "school bus with stop sign extended and flashing",
            "ambulance approaching with lights and sirens",
            "police vehicle with lights activated",
            "fire truck in oncoming lane",
            "emergency vehicle approaching from behind in mirror",
            "tow truck loading vehicle on roadside",
            "construction zone - workers present with cones",
            "construction zone - lane closure with signs",
            "road crew filling potholes with equipment in lane",
            "utility workers with cherry picker blocking lane",
            "temporary steel plates covering road excavation",
            "stopped vehicle - hazard lights on shoulder",
            "vehicle broken down in lane",
            "disabled vehicle in lane with warning triangle",
            "vehicle stalled in intersection",
            "vehicle with open hood - person inspecting engine",
            "vehicle suddenly braking ahead",
            "vehicle making unexpected lane change without signal",
            "vehicle backing out of parking spot",
            "vehicle running red light from cross street",
            "vehicle driving wrong way on one-way street",
            "vehicle making illegal U-turn",
            "vehicle swerving to avoid pothole",
            "vehicle drifting out of lane (distracted driver)",
            "vehicle cutting in from merging lane aggressively",
            "slow-moving vehicle (farm equipment/golf cart) on road",
            "delivery truck double-parked with flashers",
            "garbage truck with crew working",
            "parked car door opening into traffic",
            "semi-truck jackknifed across lanes",
            "wide-load vehicle with escort car",
            "ice cream truck stopped with children nearby",
            "ride-share vehicle stopped abruptly for pickup",
            "moving truck partially blocking lane while loading",
            "food truck parked on street with customer queue",
            "animal (deer) on roadside",
            "animal (dog) loose on road",
            "flock of birds on road surface",
            "animal (coyote/fox) darting across road",
            "fallen tree branch partially blocking lane",
            "debris/cargo on road surface",
            "large pothole in driving lane",
            "standing water/flooded section of road",
            "oil spill or fluid on road surface",
            "tire tread/retread debris on highway",
            "mattress or furniture fallen from truck on road",
            "manhole cover missing or displaced",
            "traffic cone or barrel knocked into lane",
            "sun glare directly ahead through windshield",
            "headlight glare from oncoming vehicle at night",
            "spray/mist from vehicle ahead on wet road",
            "shadow from overpass creating sudden darkness",
            "smoke from nearby fire drifting across road",
            "reflection of wet road creating mirror effect",
            "traffic light malfunctioning - flashing red",
            "obscured traffic sign by overgrown vegetation",
            "contradictory road signs at intersection",
            "pedestrian signal countdown with people still crossing",
            "railroad crossing with gates descending and lights flashing",
            "toll booth approach with lanes merging",
        ],
    )

    add_category(
        config_builder,
        "road_surface",
        [
            "dry asphalt - good condition",
            "dry asphalt - faded lane markings",
            "wet reflective surface",
            "wet with puddles",
            "icy patches visible",
            "black ice conditions",
            "snow-covered - lane markings obscured",
            "gravel surface",
            "unpaved dirt road",
            "potholes and road damage visible",
            "recent patching - uneven surface",
            "construction - temporary markings",
        ],
    )

    add_category(
        config_builder,
        "traffic_control",
        [
            "traffic light - green",
            "traffic light - yellow/amber",
            "traffic light - red",
            "stop sign clearly visible",
            "yield sign",
            "speed limit sign - 25 mph",
            "speed limit sign - 55 mph",
            "no traffic control - uncontrolled intersection",
            "construction signage and cones",
            "temporary traffic lights",
        ],
    )

    config_builder.add_column(
        dd.ImageColumnConfig(
            name="traffic_scene",
            prompt=TRAFFIC_SCENE_PROMPT,
            model_alias=model_alias,
        )
    )

    return config_builder


def create_dataset(
    config_builder: dd.DataDesignerConfigBuilder,
    *,
    num_records: int,
    dataset_name: str,
    artifact_path: Path | str | None = None,
) -> DatasetCreationResults:
    data_designer = DataDesigner(artifact_path=artifact_path)
    data_designer.validate(config_builder)
    return data_designer.create(config_builder, num_records=num_records, dataset_name=dataset_name)


TRAFFIC_SCENE_PROMPT = """\
Create a photorealistic autonomous-vehicle ego-camera perception scene.

The image must look like it was captured by a camera mounted on the self-driving
ego vehicle, not by a roadside camera, drone, or cinematic photographer. Keep
the viewpoint physically plausible for an AV sensor. When appropriate, show a
subtle hood edge, windshield edge, or bumper edge, but do not show a full car
interior or dashboard UI.

Scene requirements:
- Geographic region: {{ geographic_region }}
- Road type: {{ road_type }}
- Weather: {{ weather }}
- Time of day: {{ time_of_day }}
- Traffic density: {{ traffic_density }}
- Vehicle mix: {{ vehicle_mix }}
- Key scenario element: {{ scenario_element }}
- Road surface: {{ road_surface }}
- Traffic control: {{ traffic_control }}

The scene should clearly show road geometry, lane markings, traffic signs,
traffic control devices, surrounding vehicles, vulnerable road users when
requested, and the key scenario element from the ego vehicle's camera. Preserve
regional driving characteristics such as road width, side of road, sign style,
and lane markings. Use realistic lighting, lens geometry, motion perspective,
weather effects, and visibility. Generate exactly one final ego-camera image
for this row. Do not return alternate versions, a grid, a pair of examples,
before/after panels, or multiple camera frames. Do not include text overlays,
labels, watermarks, dashcam timestamps, bounding boxes, sensor UI, or navigation
UI.
"""


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Generate synthetic autonomous-vehicle traffic scenes.")
    parser.add_argument("--num-records", type=int, default=10, help="Number of traffic scenes to generate.")
    parser.add_argument("--dataset-name", default="synthetic-traffic-scenarios", help="Output dataset name.")
    parser.add_argument("--artifact-path", type=Path, default=None, help="Optional Data Designer artifact directory.")
    parser.add_argument("--model-provider", default=DEFAULT_MODEL_PROVIDER, help="Image model provider name.")
    parser.add_argument("--model-id", default=DEFAULT_MODEL_ID, help="Provider model ID.")
    parser.add_argument("--model-alias", default=DEFAULT_MODEL_ALIAS, help="Alias used by image columns.")
    parser.add_argument("--image-size", default="1K", help="OpenRouter image size tier, such as 1K, 2K, or 4K.")
    parser.add_argument("--aspect-ratio", default="16:9", help="Provider-specific aspect ratio value.")
    parser.add_argument("--max-parallel-requests", type=int, default=10, help="Maximum parallel image requests.")
    return parser.parse_args()


def main() -> None:
    args = parse_args()
    config_builder = build_config(
        model_provider=args.model_provider,
        model_id=args.model_id,
        model_alias=args.model_alias,
        image_size=args.image_size,
        aspect_ratio=args.aspect_ratio,
        max_parallel_requests=args.max_parallel_requests,
    )
    results = create_dataset(
        config_builder,
        num_records=args.num_records,
        dataset_name=args.dataset_name,
        artifact_path=args.artifact_path,
    )
    dataset = results.load_dataset()
    print(f"Generated {len(dataset)} synthetic traffic-scene rows.")
    print(f"Dataset artifacts: {results.artifact_storage.base_dataset_path}")


if __name__ == "__main__":
    main()
```