Browse Source

Add files via upload

Mengqi Lei 2 months ago
parent
commit
6e7ad65c5e
4 changed files with 1190 additions and 0 deletions
  1. 1025 0
      ultralytics/__init__.py
  2. 130 0
      ultralytics/default.yaml
  3. 21 0
      ultralytics/trackers/botsort.yaml
  4. 14 0
      ultralytics/trackers/bytetrack.yaml

+ 1025 - 0
ultralytics/__init__.py

@@ -0,0 +1,1025 @@
+# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
+
+import shutil
+import subprocess
+import sys
+from pathlib import Path
+from types import SimpleNamespace
+from typing import Dict, List, Union
+
+import cv2
+
+from ultralytics.utils import (
+    ASSETS,
+    DEFAULT_CFG,
+    DEFAULT_CFG_DICT,
+    DEFAULT_CFG_PATH,
+    DEFAULT_SOL_DICT,
+    IS_VSCODE,
+    LOGGER,
+    RANK,
+    ROOT,
+    RUNS_DIR,
+    SETTINGS,
+    SETTINGS_FILE,
+    TESTS_RUNNING,
+    IterableSimpleNamespace,
+    __version__,
+    checks,
+    colorstr,
+    deprecation_warn,
+    vscode_msg,
+    yaml_load,
+    yaml_print,
+)
+
+# Define valid solutions
+SOLUTION_MAP = {
+    "count": ("ObjectCounter", "count"),
+    "heatmap": ("Heatmap", "generate_heatmap"),
+    "queue": ("QueueManager", "process_queue"),
+    "speed": ("SpeedEstimator", "estimate_speed"),
+    "workout": ("AIGym", "monitor"),
+    "analytics": ("Analytics", "process_data"),
+    "trackzone": ("TrackZone", "trackzone"),
+    "inference": ("Inference", "inference"),
+    "help": None,
+}
+
+# Define valid tasks and modes
+MODES = {"train", "val", "predict", "export", "track", "benchmark"}
+TASKS = {"detect", "segment", "classify", "pose", "obb"}
+TASK2DATA = {
+    "detect": "coco8.yaml",
+    "segment": "coco8-seg.yaml",
+    "classify": "imagenet10",
+    "pose": "coco8-pose.yaml",
+    "obb": "dota8.yaml",
+}
+TASK2MODEL = {
+    "detect": "yolo11n.pt",
+    "segment": "yolo11n-seg.pt",
+    "classify": "yolo11n-cls.pt",
+    "pose": "yolo11n-pose.pt",
+    "obb": "yolo11n-obb.pt",
+}
+TASK2METRIC = {
+    "detect": "metrics/mAP50-95(B)",
+    "segment": "metrics/mAP50-95(M)",
+    "classify": "metrics/accuracy_top1",
+    "pose": "metrics/mAP50-95(P)",
+    "obb": "metrics/mAP50-95(B)",
+}
+MODELS = {TASK2MODEL[task] for task in TASKS}
+
+ARGV = sys.argv or ["", ""]  # sometimes sys.argv = []
+SOLUTIONS_HELP_MSG = f"""
+    Arguments received: {str(["yolo"] + ARGV[1:])}. Ultralytics 'yolo solutions' usage overview:
+
+        yolo solutions SOLUTION ARGS
+
+        Where SOLUTION (optional) is one of {list(SOLUTION_MAP.keys())[:-1]}
+              ARGS (optional) are any number of custom 'arg=value' pairs like 'show_in=True' that override defaults 
+                  at https://docs.ultralytics.com/usage/cfg
+                
+    1. Call object counting solution
+        yolo solutions count source="path/to/video/file.mp4" region=[(20, 400), (1080, 400), (1080, 360), (20, 360)]
+
+    2. Call heatmaps solution
+        yolo solutions heatmap colormap=cv2.COLORMAP_PARULA model=yolo11n.pt
+
+    3. Call queue management solution
+        yolo solutions queue region=[(20, 400), (1080, 400), (1080, 360), (20, 360)] model=yolo11n.pt
+
+    4. Call workouts monitoring solution for push-ups
+        yolo solutions workout model=yolo11n-pose.pt kpts=[6, 8, 10]
+
+    5. Generate analytical graphs
+        yolo solutions analytics analytics_type="pie"
+    
+    6. Track objects within specific zones
+        yolo solutions trackzone source="path/to/video/file.mp4" region=[(150, 150), (1130, 150), (1130, 570), (150, 570)]
+        
+    7. Streamlit real-time webcam inference GUI
+        yolo streamlit-predict
+    """
+CLI_HELP_MSG = f"""
+    Arguments received: {str(["yolo"] + ARGV[1:])}. Ultralytics 'yolo' commands use the following syntax:
+
+        yolo TASK MODE ARGS
+
+        Where   TASK (optional) is one of {TASKS}
+                MODE (required) is one of {MODES}
+                ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults.
+                    See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg'
+
+    1. Train a detection model for 10 epochs with an initial learning_rate of 0.01
+        yolo train data=coco8.yaml model=yolo11n.pt epochs=10 lr0=0.01
+
+    2. Predict a YouTube video using a pretrained segmentation model at image size 320:
+        yolo predict model=yolo11n-seg.pt source='https://youtu.be/LNwODJXcvt4' imgsz=320
+
+    3. Val a pretrained detection model at batch-size 1 and image size 640:
+        yolo val model=yolo11n.pt data=coco8.yaml batch=1 imgsz=640
+
+    4. Export a YOLO11n classification model to ONNX format at image size 224 by 128 (no TASK required)
+        yolo export model=yolo11n-cls.pt format=onnx imgsz=224,128
+
+    5. Ultralytics solutions usage
+        yolo solutions count or in {list(SOLUTION_MAP.keys())[1:-1]} source="path/to/video/file.mp4"
+
+    6. Run special commands:
+        yolo help
+        yolo checks
+        yolo version
+        yolo settings
+        yolo copy-cfg
+        yolo cfg
+        yolo solutions help
+
+    Docs: https://docs.ultralytics.com
+    Solutions: https://docs.ultralytics.com/solutions/
+    Community: https://community.ultralytics.com
+    GitHub: https://github.com/ultralytics/ultralytics
+    """
+
+# Define keys for arg type checks
+CFG_FLOAT_KEYS = {  # integer or float arguments, i.e. x=2 and x=2.0
+    "warmup_epochs",
+    "box",
+    "cls",
+    "dfl",
+    "degrees",
+    "shear",
+    "time",
+    "workspace",
+    "batch",
+}
+CFG_FRACTION_KEYS = {  # fractional float arguments with 0.0<=values<=1.0
+    "dropout",
+    "lr0",
+    "lrf",
+    "momentum",
+    "weight_decay",
+    "warmup_momentum",
+    "warmup_bias_lr",
+    "hsv_h",
+    "hsv_s",
+    "hsv_v",
+    "translate",
+    "scale",
+    "perspective",
+    "flipud",
+    "fliplr",
+    "bgr",
+    "mosaic",
+    "mixup",
+    "copy_paste",
+    "conf",
+    "iou",
+    "fraction",
+}
+CFG_INT_KEYS = {  # integer-only arguments
+    "epochs",
+    "patience",
+    "workers",
+    "seed",
+    "close_mosaic",
+    "mask_ratio",
+    "max_det",
+    "vid_stride",
+    "line_width",
+    "nbs",
+    "save_period",
+}
+CFG_BOOL_KEYS = {  # boolean-only arguments
+    "save",
+    "exist_ok",
+    "verbose",
+    "deterministic",
+    "single_cls",
+    "rect",
+    "cos_lr",
+    "overlap_mask",
+    "val",
+    "save_json",
+    "save_hybrid",
+    "half",
+    "dnn",
+    "plots",
+    "show",
+    "save_txt",
+    "save_conf",
+    "save_crop",
+    "save_frames",
+    "show_labels",
+    "show_conf",
+    "visualize",
+    "augment",
+    "agnostic_nms",
+    "retina_masks",
+    "show_boxes",
+    "keras",
+    "optimize",
+    "int8",
+    "dynamic",
+    "simplify",
+    "nms",
+    "profile",
+    "multi_scale",
+}
+
+
+def cfg2dict(cfg):
+    """
+    Converts a configuration object to a dictionary.
+
+    Args:
+        cfg (str | Path | Dict | SimpleNamespace): Configuration object to be converted. Can be a file path,
+            a string, a dictionary, or a SimpleNamespace object.
+
+    Returns:
+        (Dict): Configuration object in dictionary format.
+
+    Examples:
+        Convert a YAML file path to a dictionary:
+        >>> config_dict = cfg2dict("config.yaml")
+
+        Convert a SimpleNamespace to a dictionary:
+        >>> from types import SimpleNamespace
+        >>> config_sn = SimpleNamespace(param1="value1", param2="value2")
+        >>> config_dict = cfg2dict(config_sn)
+
+        Pass through an already existing dictionary:
+        >>> config_dict = cfg2dict({"param1": "value1", "param2": "value2"})
+
+    Notes:
+        - If cfg is a path or string, it's loaded as YAML and converted to a dictionary.
+        - If cfg is a SimpleNamespace object, it's converted to a dictionary using vars().
+        - If cfg is already a dictionary, it's returned unchanged.
+    """
+    if isinstance(cfg, (str, Path)):
+        cfg = yaml_load(cfg)  # load dict
+    elif isinstance(cfg, SimpleNamespace):
+        cfg = vars(cfg)  # convert to dict
+    return cfg
+
+
+def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, overrides: Dict = None):
+    """
+    Load and merge configuration data from a file or dictionary, with optional overrides.
+
+    Args:
+        cfg (str | Path | Dict | SimpleNamespace): Configuration data source. Can be a file path, dictionary, or
+            SimpleNamespace object.
+        overrides (Dict | None): Dictionary containing key-value pairs to override the base configuration.
+
+    Returns:
+        (SimpleNamespace): Namespace containing the merged configuration arguments.
+
+    Examples:
+        >>> from ultralytics.cfg import get_cfg
+        >>> config = get_cfg()  # Load default configuration
+        >>> config_with_overrides = get_cfg("path/to/config.yaml", overrides={"epochs": 50, "batch_size": 16})
+
+    Notes:
+        - If both `cfg` and `overrides` are provided, the values in `overrides` will take precedence.
+        - Special handling ensures alignment and correctness of the configuration, such as converting numeric
+          `project` and `name` to strings and validating configuration keys and values.
+        - The function performs type and value checks on the configuration data.
+    """
+    cfg = cfg2dict(cfg)
+
+    # Merge overrides
+    if overrides:
+        overrides = cfg2dict(overrides)
+        if "save_dir" not in cfg:
+            overrides.pop("save_dir", None)  # special override keys to ignore
+        check_dict_alignment(cfg, overrides)
+        cfg = {**cfg, **overrides}  # merge cfg and overrides dicts (prefer overrides)
+
+    # Special handling for numeric project/name
+    for k in "project", "name":
+        if k in cfg and isinstance(cfg[k], (int, float)):
+            cfg[k] = str(cfg[k])
+    if cfg.get("name") == "model":  # assign model to 'name' arg
+        cfg["name"] = str(cfg.get("model", "")).split(".")[0]
+        LOGGER.warning(f"WARNING ⚠️ 'name=model' automatically updated to 'name={cfg['name']}'.")
+
+    # Type and Value checks
+    check_cfg(cfg)
+
+    # Return instance
+    return IterableSimpleNamespace(**cfg)
+
+
+def check_cfg(cfg, hard=True):
+    """
+    Checks configuration argument types and values for the Ultralytics library.
+
+    This function validates the types and values of configuration arguments, ensuring correctness and converting
+    them if necessary. It checks for specific key types defined in global variables such as CFG_FLOAT_KEYS,
+    CFG_FRACTION_KEYS, CFG_INT_KEYS, and CFG_BOOL_KEYS.
+
+    Args:
+        cfg (Dict): Configuration dictionary to validate.
+        hard (bool): If True, raises exceptions for invalid types and values; if False, attempts to convert them.
+
+    Examples:
+        >>> config = {
+        ...     "epochs": 50,  # valid integer
+        ...     "lr0": 0.01,  # valid float
+        ...     "momentum": 1.2,  # invalid float (out of 0.0-1.0 range)
+        ...     "save": "true",  # invalid bool
+        ... }
+        >>> check_cfg(config, hard=False)
+        >>> print(config)
+        {'epochs': 50, 'lr0': 0.01, 'momentum': 1.2, 'save': False}  # corrected 'save' key
+
+    Notes:
+        - The function modifies the input dictionary in-place.
+        - None values are ignored as they may be from optional arguments.
+        - Fraction keys are checked to be within the range [0.0, 1.0].
+    """
+    for k, v in cfg.items():
+        if v is not None:  # None values may be from optional args
+            if k in CFG_FLOAT_KEYS and not isinstance(v, (int, float)):
+                if hard:
+                    raise TypeError(
+                        f"'{k}={v}' is of invalid type {type(v).__name__}. "
+                        f"Valid '{k}' types are int (i.e. '{k}=0') or float (i.e. '{k}=0.5')"
+                    )
+                cfg[k] = float(v)
+            elif k in CFG_FRACTION_KEYS:
+                if not isinstance(v, (int, float)):
+                    if hard:
+                        raise TypeError(
+                            f"'{k}={v}' is of invalid type {type(v).__name__}. "
+                            f"Valid '{k}' types are int (i.e. '{k}=0') or float (i.e. '{k}=0.5')"
+                        )
+                    cfg[k] = v = float(v)
+                if not (0.0 <= v <= 1.0):
+                    raise ValueError(f"'{k}={v}' is an invalid value. Valid '{k}' values are between 0.0 and 1.0.")
+            elif k in CFG_INT_KEYS and not isinstance(v, int):
+                if hard:
+                    raise TypeError(
+                        f"'{k}={v}' is of invalid type {type(v).__name__}. '{k}' must be an int (i.e. '{k}=8')"
+                    )
+                cfg[k] = int(v)
+            elif k in CFG_BOOL_KEYS and not isinstance(v, bool):
+                if hard:
+                    raise TypeError(
+                        f"'{k}={v}' is of invalid type {type(v).__name__}. "
+                        f"'{k}' must be a bool (i.e. '{k}=True' or '{k}=False')"
+                    )
+                cfg[k] = bool(v)
+
+
+def get_save_dir(args, name=None):
+    """
+    Returns the directory path for saving outputs, derived from arguments or default settings.
+
+    Args:
+        args (SimpleNamespace): Namespace object containing configurations such as 'project', 'name', 'task',
+            'mode', and 'save_dir'.
+        name (str | None): Optional name for the output directory. If not provided, it defaults to 'args.name'
+            or the 'args.mode'.
+
+    Returns:
+        (Path): Directory path where outputs should be saved.
+
+    Examples:
+        >>> from types import SimpleNamespace
+        >>> args = SimpleNamespace(project="my_project", task="detect", mode="train", exist_ok=True)
+        >>> save_dir = get_save_dir(args)
+        >>> print(save_dir)
+        my_project/detect/train
+    """
+    if getattr(args, "save_dir", None):
+        save_dir = args.save_dir
+    else:
+        from ultralytics.utils.files import increment_path
+
+        project = args.project or (ROOT.parent / "tests/tmp/runs" if TESTS_RUNNING else RUNS_DIR) / args.task
+        name = name or args.name or f"{args.mode}"
+        save_dir = increment_path(Path(project) / name, exist_ok=args.exist_ok if RANK in {-1, 0} else True)
+
+    return Path(save_dir)
+
+
+def _handle_deprecation(custom):
+    """
+    Handles deprecated configuration keys by mapping them to current equivalents with deprecation warnings.
+
+    Args:
+        custom (Dict): Configuration dictionary potentially containing deprecated keys.
+
+    Examples:
+        >>> custom_config = {"boxes": True, "hide_labels": "False", "line_thickness": 2}
+        >>> _handle_deprecation(custom_config)
+        >>> print(custom_config)
+        {'show_boxes': True, 'show_labels': True, 'line_width': 2}
+
+    Notes:
+        This function modifies the input dictionary in-place, replacing deprecated keys with their current
+        equivalents. It also handles value conversions where necessary, such as inverting boolean values for
+        'hide_labels' and 'hide_conf'.
+    """
+    for key in custom.copy().keys():
+        if key == "boxes":
+            deprecation_warn(key, "show_boxes")
+            custom["show_boxes"] = custom.pop("boxes")
+        if key == "hide_labels":
+            deprecation_warn(key, "show_labels")
+            custom["show_labels"] = custom.pop("hide_labels") == "False"
+        if key == "hide_conf":
+            deprecation_warn(key, "show_conf")
+            custom["show_conf"] = custom.pop("hide_conf") == "False"
+        if key == "line_thickness":
+            deprecation_warn(key, "line_width")
+            custom["line_width"] = custom.pop("line_thickness")
+        if key == "label_smoothing":
+            deprecation_warn(key)
+            custom.pop("label_smoothing")
+
+    return custom
+
+
+def check_dict_alignment(base: Dict, custom: Dict, e=None):
+    """
+    Checks alignment between custom and base configuration dictionaries, handling deprecated keys and providing error
+    messages for mismatched keys.
+
+    Args:
+        base (Dict): The base configuration dictionary containing valid keys.
+        custom (Dict): The custom configuration dictionary to be checked for alignment.
+        e (Exception | None): Optional error instance passed by the calling function.
+
+    Raises:
+        SystemExit: If mismatched keys are found between the custom and base dictionaries.
+
+    Examples:
+        >>> base_cfg = {"epochs": 50, "lr0": 0.01, "batch_size": 16}
+        >>> custom_cfg = {"epoch": 100, "lr": 0.02, "batch_size": 32}
+        >>> try:
+        ...     check_dict_alignment(base_cfg, custom_cfg)
+        ... except SystemExit:
+        ...     print("Mismatched keys found")
+
+    Notes:
+        - Suggests corrections for mismatched keys based on similarity to valid keys.
+        - Automatically replaces deprecated keys in the custom configuration with updated equivalents.
+        - Prints detailed error messages for each mismatched key to help users correct their configurations.
+    """
+    custom = _handle_deprecation(custom)
+    base_keys, custom_keys = (set(x.keys()) for x in (base, custom))
+    if mismatched := [k for k in custom_keys if k not in base_keys]:
+        from difflib import get_close_matches
+
+        string = ""
+        for x in mismatched:
+            matches = get_close_matches(x, base_keys)  # key list
+            matches = [f"{k}={base[k]}" if base.get(k) is not None else k for k in matches]
+            match_str = f"Similar arguments are i.e. {matches}." if matches else ""
+            string += f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}\n"
+        raise SyntaxError(string + CLI_HELP_MSG) from e
+
+
+def merge_equals_args(args: List[str]) -> List[str]:
+    """
+    Merges arguments around isolated '=' in a list of strings and joins fragments with brackets.
+
+    This function handles the following cases:
+    1. ['arg', '=', 'val'] becomes ['arg=val']
+    2. ['arg=', 'val'] becomes ['arg=val']
+    3. ['arg', '=val'] becomes ['arg=val']
+    4. Joins fragments with brackets, e.g., ['imgsz=[3,', '640,', '640]'] becomes ['imgsz=[3,640,640]']
+
+    Args:
+        args (List[str]): A list of strings where each element represents an argument or fragment.
+
+    Returns:
+        List[str]: A list of strings where the arguments around isolated '=' are merged and fragments with brackets are joined.
+
+    Examples:
+        >>> args = ["arg1", "=", "value", "arg2=", "value2", "arg3", "=value3", "imgsz=[3,", "640,", "640]"]
+        >>> merge_and_join_args(args)
+        ['arg1=value', 'arg2=value2', 'arg3=value3', 'imgsz=[3,640,640]']
+    """
+    new_args = []
+    current = ""
+    depth = 0
+
+    i = 0
+    while i < len(args):
+        arg = args[i]
+
+        # Handle equals sign merging
+        if arg == "=" and 0 < i < len(args) - 1:  # merge ['arg', '=', 'val']
+            new_args[-1] += f"={args[i + 1]}"
+            i += 2
+            continue
+        elif arg.endswith("=") and i < len(args) - 1 and "=" not in args[i + 1]:  # merge ['arg=', 'val']
+            new_args.append(f"{arg}{args[i + 1]}")
+            i += 2
+            continue
+        elif arg.startswith("=") and i > 0:  # merge ['arg', '=val']
+            new_args[-1] += arg
+            i += 1
+            continue
+
+        # Handle bracket joining
+        depth += arg.count("[") - arg.count("]")
+        current += arg
+        if depth == 0:
+            new_args.append(current)
+            current = ""
+
+        i += 1
+
+    # Append any remaining current string
+    if current:
+        new_args.append(current)
+
+    return new_args
+
+
+def handle_yolo_hub(args: List[str]) -> None:
+    """
+    Handles Ultralytics HUB command-line interface (CLI) commands for authentication.
+
+    This function processes Ultralytics HUB CLI commands such as login and logout. It should be called when executing a
+    script with arguments related to HUB authentication.
+
+    Args:
+        args (List[str]): A list of command line arguments. The first argument should be either 'login'
+            or 'logout'. For 'login', an optional second argument can be the API key.
+
+    Examples:
+        ```bash
+        yolo login YOUR_API_KEY
+        ```
+
+    Notes:
+        - The function imports the 'hub' module from ultralytics to perform login and logout operations.
+        - For the 'login' command, if no API key is provided, an empty string is passed to the login function.
+        - The 'logout' command does not require any additional arguments.
+    """
+    from ultralytics import hub
+
+    if args[0] == "login":
+        key = args[1] if len(args) > 1 else ""
+        # Log in to Ultralytics HUB using the provided API key
+        hub.login(key)
+    elif args[0] == "logout":
+        # Log out from Ultralytics HUB
+        hub.logout()
+
+
+def handle_yolo_settings(args: List[str]) -> None:
+    """
+    Handles YOLO settings command-line interface (CLI) commands.
+
+    This function processes YOLO settings CLI commands such as reset and updating individual settings. It should be
+    called when executing a script with arguments related to YOLO settings management.
+
+    Args:
+        args (List[str]): A list of command line arguments for YOLO settings management.
+
+    Examples:
+        >>> handle_yolo_settings(["reset"])  # Reset YOLO settings
+        >>> handle_yolo_settings(["default_cfg_path=yolo11n.yaml"])  # Update a specific setting
+
+    Notes:
+        - If no arguments are provided, the function will display the current settings.
+        - The 'reset' command will delete the existing settings file and create new default settings.
+        - Other arguments are treated as key-value pairs to update specific settings.
+        - The function will check for alignment between the provided settings and the existing ones.
+        - After processing, the updated settings will be displayed.
+        - For more information on handling YOLO settings, visit:
+          https://docs.ultralytics.com/quickstart/#ultralytics-settings
+    """
+    url = "https://docs.ultralytics.com/quickstart/#ultralytics-settings"  # help URL
+    try:
+        if any(args):
+            if args[0] == "reset":
+                SETTINGS_FILE.unlink()  # delete the settings file
+                SETTINGS.reset()  # create new settings
+                LOGGER.info("Settings reset successfully")  # inform the user that settings have been reset
+            else:  # save a new setting
+                new = dict(parse_key_value_pair(a) for a in args)
+                check_dict_alignment(SETTINGS, new)
+                SETTINGS.update(new)
+
+        print(SETTINGS)  # print the current settings
+        LOGGER.info(f"💡 Learn more about Ultralytics Settings at {url}")
+    except Exception as e:
+        LOGGER.warning(f"WARNING ⚠️ settings error: '{e}'. Please see {url} for help.")
+
+
+def handle_yolo_solutions(args: List[str]) -> None:
+    """
+    Processes YOLO solutions arguments and runs the specified computer vision solutions pipeline.
+
+    Args:
+        args (List[str]): Command-line arguments for configuring and running the Ultralytics YOLO
+            solutions: https://docs.ultralytics.com/solutions/, It can include solution name, source,
+            and other configuration parameters.
+
+    Returns:
+        None: The function processes video frames and saves the output but doesn't return any value.
+
+    Examples:
+        Run people counting solution with default settings:
+        >>> handle_yolo_solutions(["count"])
+
+        Run analytics with custom configuration:
+        >>> handle_yolo_solutions(["analytics", "conf=0.25", "source=path/to/video/file.mp4"])
+
+        Run inference with custom configuration, requires Streamlit version 1.29.0 or higher.
+        >>> handle_yolo_solutions(["inference", "model=yolo11n.pt"])
+
+    Notes:
+        - Default configurations are merged from DEFAULT_SOL_DICT and DEFAULT_CFG_DICT
+        - Arguments can be provided in the format 'key=value' or as boolean flags
+        - Available solutions are defined in SOLUTION_MAP with their respective classes and methods
+        - If an invalid solution is provided, defaults to 'count' solution
+        - Output videos are saved in 'runs/solution/{solution_name}' directory
+        - For 'analytics' solution, frame numbers are tracked for generating analytical graphs
+        - Video processing can be interrupted by pressing 'q'
+        - Processes video frames sequentially and saves output in .avi format
+        - If no source is specified, downloads and uses a default sample video\
+        - The inference solution will be launched using the 'streamlit run' command.
+        - The Streamlit app file is located in the Ultralytics package directory.
+    """
+    full_args_dict = {**DEFAULT_SOL_DICT, **DEFAULT_CFG_DICT}  # arguments dictionary
+    overrides = {}
+
+    # check dictionary alignment
+    for arg in merge_equals_args(args):
+        arg = arg.lstrip("-").rstrip(",")
+        if "=" in arg:
+            try:
+                k, v = parse_key_value_pair(arg)
+                overrides[k] = v
+            except (NameError, SyntaxError, ValueError, AssertionError) as e:
+                check_dict_alignment(full_args_dict, {arg: ""}, e)
+        elif arg in full_args_dict and isinstance(full_args_dict.get(arg), bool):
+            overrides[arg] = True
+    check_dict_alignment(full_args_dict, overrides)  # dict alignment
+
+    # Get solution name
+    if args and args[0] in SOLUTION_MAP:
+        if args[0] != "help":
+            s_n = args.pop(0)  # Extract the solution name directly
+        else:
+            LOGGER.info(SOLUTIONS_HELP_MSG)
+    else:
+        LOGGER.warning(
+            f"⚠️ No valid solution provided. Using default 'count'. Available: {', '.join(SOLUTION_MAP.keys())}"
+        )
+        s_n = "count"  # Default solution if none provided
+
+    if args and args[0] == "help":  # Add check for return if user call `yolo solutions help`
+        return
+
+    if s_n == "inference":
+        checks.check_requirements("streamlit>=1.29.0")
+        LOGGER.info("💡 Loading Ultralytics live inference app...")
+        subprocess.run(
+            [  # Run subprocess with Streamlit custom argument
+                "streamlit",
+                "run",
+                str(ROOT / "solutions/streamlit_inference.py"),
+                "--server.headless",
+                "true",
+                overrides.pop("model", "yolo11n.pt"),
+            ]
+        )
+    else:
+        cls, method = SOLUTION_MAP[s_n]  # solution class name, method name and default source
+
+        from ultralytics import solutions  # import ultralytics solutions
+
+        solution = getattr(solutions, cls)(IS_CLI=True, **overrides)  # get solution class i.e ObjectCounter
+        process = getattr(
+            solution, method
+        )  # get specific function of class for processing i.e, count from ObjectCounter
+
+        cap = cv2.VideoCapture(solution.CFG["source"])  # read the video file
+
+        # extract width, height and fps of the video file, create save directory and initialize video writer
+        import os  # for directory creation
+        from pathlib import Path
+
+        from ultralytics.utils.files import increment_path  # for output directory path update
+
+        w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
+        if s_n == "analytics":  # analytical graphs follow fixed shape for output i.e w=1920, h=1080
+            w, h = 1920, 1080
+        save_dir = increment_path(Path("runs") / "solutions" / "exp", exist_ok=False)
+        save_dir.mkdir(parents=True, exist_ok=True)  # create the output directory
+        vw = cv2.VideoWriter(os.path.join(save_dir, "solution.avi"), cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
+
+        try:  # Process video frames
+            f_n = 0  # frame number, required for analytical graphs
+            while cap.isOpened():
+                success, frame = cap.read()
+                if not success:
+                    break
+                frame = process(frame, f_n := f_n + 1) if s_n == "analytics" else process(frame)
+                vw.write(frame)
+                if cv2.waitKey(1) & 0xFF == ord("q"):
+                    break
+        finally:
+            cap.release()
+
+
+def parse_key_value_pair(pair: str = "key=value"):
+    """
+    Parses a key-value pair string into separate key and value components.
+
+    Args:
+        pair (str): A string containing a key-value pair in the format "key=value".
+
+    Returns:
+        key (str): The parsed key.
+        value (str): The parsed value.
+
+    Raises:
+        AssertionError: If the value is missing or empty.
+
+    Examples:
+        >>> key, value = parse_key_value_pair("model=yolo11n.pt")
+        >>> print(f"Key: {key}, Value: {value}")
+        Key: model, Value: yolo11n.pt
+
+        >>> key, value = parse_key_value_pair("epochs=100")
+        >>> print(f"Key: {key}, Value: {value}")
+        Key: epochs, Value: 100
+
+    Notes:
+        - The function splits the input string on the first '=' character.
+        - Leading and trailing whitespace is removed from both key and value.
+        - An assertion error is raised if the value is empty after stripping.
+    """
+    k, v = pair.split("=", 1)  # split on first '=' sign
+    k, v = k.strip(), v.strip()  # remove spaces
+    assert v, f"missing '{k}' value"
+    return k, smart_value(v)
+
+
+def smart_value(v):
+    """
+    Converts a string representation of a value to its appropriate Python type.
+
+    This function attempts to convert a given string into a Python object of the most appropriate type. It handles
+    conversions to None, bool, int, float, and other types that can be evaluated safely.
+
+    Args:
+        v (str): The string representation of the value to be converted.
+
+    Returns:
+        (Any): The converted value. The type can be None, bool, int, float, or the original string if no conversion
+            is applicable.
+
+    Examples:
+        >>> smart_value("42")
+        42
+        >>> smart_value("3.14")
+        3.14
+        >>> smart_value("True")
+        True
+        >>> smart_value("None")
+        None
+        >>> smart_value("some_string")
+        'some_string'
+
+    Notes:
+        - The function uses a case-insensitive comparison for boolean and None values.
+        - For other types, it attempts to use Python's eval() function, which can be unsafe if used on untrusted input.
+        - If no conversion is possible, the original string is returned.
+    """
+    v_lower = v.lower()
+    if v_lower == "none":
+        return None
+    elif v_lower == "true":
+        return True
+    elif v_lower == "false":
+        return False
+    else:
+        try:
+            return eval(v)
+        except Exception:
+            return v
+
+
+def entrypoint(debug=""):
+    """
+    Ultralytics entrypoint function for parsing and executing command-line arguments.
+
+    This function serves as the main entry point for the Ultralytics CLI, parsing command-line arguments and
+    executing the corresponding tasks such as training, validation, prediction, exporting models, and more.
+
+    Args:
+        debug (str): Space-separated string of command-line arguments for debugging purposes.
+
+    Examples:
+        Train a detection model for 10 epochs with an initial learning_rate of 0.01:
+        >>> entrypoint("train data=coco8.yaml model=yolo11n.pt epochs=10 lr0=0.01")
+
+        Predict a YouTube video using a pretrained segmentation model at image size 320:
+        >>> entrypoint("predict model=yolo11n-seg.pt source='https://youtu.be/LNwODJXcvt4' imgsz=320")
+
+        Validate a pretrained detection model at batch-size 1 and image size 640:
+        >>> entrypoint("val model=yolo11n.pt data=coco8.yaml batch=1 imgsz=640")
+
+    Notes:
+        - If no arguments are passed, the function will display the usage help message.
+        - For a list of all available commands and their arguments, see the provided help messages and the
+          Ultralytics documentation at https://docs.ultralytics.com.
+    """
+    args = (debug.split(" ") if debug else ARGV)[1:]
+    if not args:  # no arguments passed
+        LOGGER.info(CLI_HELP_MSG)
+        return
+
+    special = {
+        "help": lambda: LOGGER.info(CLI_HELP_MSG),
+        "checks": checks.collect_system_info,
+        "version": lambda: LOGGER.info(__version__),
+        "settings": lambda: handle_yolo_settings(args[1:]),
+        "cfg": lambda: yaml_print(DEFAULT_CFG_PATH),
+        "hub": lambda: handle_yolo_hub(args[1:]),
+        "login": lambda: handle_yolo_hub(args),
+        "logout": lambda: handle_yolo_hub(args),
+        "copy-cfg": copy_default_cfg,
+        "solutions": lambda: handle_yolo_solutions(args[1:]),
+    }
+    full_args_dict = {**DEFAULT_CFG_DICT, **{k: None for k in TASKS}, **{k: None for k in MODES}, **special}
+
+    # Define common misuses of special commands, i.e. -h, -help, --help
+    special.update({k[0]: v for k, v in special.items()})  # singular
+    special.update({k[:-1]: v for k, v in special.items() if len(k) > 1 and k.endswith("s")})  # singular
+    special = {**special, **{f"-{k}": v for k, v in special.items()}, **{f"--{k}": v for k, v in special.items()}}
+
+    overrides = {}  # basic overrides, i.e. imgsz=320
+    for a in merge_equals_args(args):  # merge spaces around '=' sign
+        if a.startswith("--"):
+            LOGGER.warning(f"WARNING ⚠️ argument '{a}' does not require leading dashes '--', updating to '{a[2:]}'.")
+            a = a[2:]
+        if a.endswith(","):
+            LOGGER.warning(f"WARNING ⚠️ argument '{a}' does not require trailing comma ',', updating to '{a[:-1]}'.")
+            a = a[:-1]
+        if "=" in a:
+            try:
+                k, v = parse_key_value_pair(a)
+                if k == "cfg" and v is not None:  # custom.yaml passed
+                    LOGGER.info(f"Overriding {DEFAULT_CFG_PATH} with {v}")
+                    overrides = {k: val for k, val in yaml_load(checks.check_yaml(v)).items() if k != "cfg"}
+                else:
+                    overrides[k] = v
+            except (NameError, SyntaxError, ValueError, AssertionError) as e:
+                check_dict_alignment(full_args_dict, {a: ""}, e)
+
+        elif a in TASKS:
+            overrides["task"] = a
+        elif a in MODES:
+            overrides["mode"] = a
+        elif a.lower() in special:
+            special[a.lower()]()
+            return
+        elif a in DEFAULT_CFG_DICT and isinstance(DEFAULT_CFG_DICT[a], bool):
+            overrides[a] = True  # auto-True for default bool args, i.e. 'yolo show' sets show=True
+        elif a in DEFAULT_CFG_DICT:
+            raise SyntaxError(
+                f"'{colorstr('red', 'bold', a)}' is a valid YOLO argument but is missing an '=' sign "
+                f"to set its value, i.e. try '{a}={DEFAULT_CFG_DICT[a]}'\n{CLI_HELP_MSG}"
+            )
+        else:
+            check_dict_alignment(full_args_dict, {a: ""})
+
+    # Check keys
+    check_dict_alignment(full_args_dict, overrides)
+
+    # Mode
+    mode = overrides.get("mode")
+    if mode is None:
+        mode = DEFAULT_CFG.mode or "predict"
+        LOGGER.warning(f"WARNING ⚠️ 'mode' argument is missing. Valid modes are {MODES}. Using default 'mode={mode}'.")
+    elif mode not in MODES:
+        raise ValueError(f"Invalid 'mode={mode}'. Valid modes are {MODES}.\n{CLI_HELP_MSG}")
+
+    # Task
+    task = overrides.pop("task", None)
+    if task:
+        if task == "classify" and mode == "track":
+            raise ValueError(
+                f"❌ Classification doesn't support 'mode=track'. Valid modes for classification are"
+                f" {MODES - {'track'}}.\n{CLI_HELP_MSG}"
+            )
+        elif task not in TASKS:
+            if task == "track":
+                LOGGER.warning(
+                    "WARNING ⚠️ invalid 'task=track', setting 'task=detect' and 'mode=track'. Valid tasks are {TASKS}.\n{CLI_HELP_MSG}."
+                )
+                task, mode = "detect", "track"
+            else:
+                raise ValueError(f"Invalid 'task={task}'. Valid tasks are {TASKS}.\n{CLI_HELP_MSG}")
+        if "model" not in overrides:
+            overrides["model"] = TASK2MODEL[task]
+
+    # Model
+    model = overrides.pop("model", DEFAULT_CFG.model)
+    if model is None:
+        model = "yolo11n.pt"
+        LOGGER.warning(f"WARNING ⚠️ 'model' argument is missing. Using default 'model={model}'.")
+    overrides["model"] = model
+    stem = Path(model).stem.lower()
+    if "rtdetr" in stem:  # guess architecture
+        from ultralytics import RTDETR
+
+        model = RTDETR(model)  # no task argument
+    elif "fastsam" in stem:
+        from ultralytics import FastSAM
+
+        model = FastSAM(model)
+    elif "sam_" in stem or "sam2_" in stem or "sam2.1_" in stem:
+        from ultralytics import SAM
+
+        model = SAM(model)
+    else:
+        from ultralytics import YOLO
+
+        model = YOLO(model, task=task)
+    if isinstance(overrides.get("pretrained"), str):
+        model.load(overrides["pretrained"])
+
+    # Task Update
+    if task != model.task:
+        if task:
+            LOGGER.warning(
+                f"WARNING ⚠️ conflicting 'task={task}' passed with 'task={model.task}' model. "
+                f"Ignoring 'task={task}' and updating to 'task={model.task}' to match model."
+            )
+        task = model.task
+
+    # Mode
+    if mode in {"predict", "track"} and "source" not in overrides:
+        overrides["source"] = (
+            "https://ultralytics.com/images/boats.jpg" if task == "obb" else DEFAULT_CFG.source or ASSETS
+        )
+        LOGGER.warning(f"WARNING ⚠️ 'source' argument is missing. Using default 'source={overrides['source']}'.")
+    elif mode in {"train", "val"}:
+        if "data" not in overrides and "resume" not in overrides:
+            overrides["data"] = DEFAULT_CFG.data or TASK2DATA.get(task or DEFAULT_CFG.task, DEFAULT_CFG.data)
+            LOGGER.warning(f"WARNING ⚠️ 'data' argument is missing. Using default 'data={overrides['data']}'.")
+    elif mode == "export":
+        if "format" not in overrides:
+            overrides["format"] = DEFAULT_CFG.format or "torchscript"
+            LOGGER.warning(f"WARNING ⚠️ 'format' argument is missing. Using default 'format={overrides['format']}'.")
+
+    # Run command in python
+    getattr(model, mode)(**overrides)  # default args from model
+
+    # Show help
+    LOGGER.info(f"💡 Learn more at https://docs.ultralytics.com/modes/{mode}")
+
+    # Recommend VS Code extension
+    if IS_VSCODE and SETTINGS.get("vscode_msg", True):
+        LOGGER.info(vscode_msg())
+
+
+# Special modes --------------------------------------------------------------------------------------------------------
+def copy_default_cfg():
+    """
+    Copies the default configuration file and creates a new one with '_copy' appended to its name.
+
+    This function duplicates the existing default configuration file (DEFAULT_CFG_PATH) and saves it
+    with '_copy' appended to its name in the current working directory. It provides a convenient way
+    to create a custom configuration file based on the default settings.
+
+    Examples:
+        >>> copy_default_cfg()
+        # Output: default.yaml copied to /path/to/current/directory/default_copy.yaml
+        # Example YOLO command with this new custom cfg:
+        #   yolo cfg='/path/to/current/directory/default_copy.yaml' imgsz=320 batch=8
+
+    Notes:
+        - The new configuration file is created in the current working directory.
+        - After copying, the function prints a message with the new file's location and an example
+          YOLO command demonstrating how to use the new configuration file.
+        - This function is useful for users who want to modify the default configuration without
+          altering the original file.
+    """
+    new_file = Path.cwd() / DEFAULT_CFG_PATH.name.replace(".yaml", "_copy.yaml")
+    shutil.copy2(DEFAULT_CFG_PATH, new_file)
+    LOGGER.info(
+        f"{DEFAULT_CFG_PATH} copied to {new_file}\n"
+        f"Example YOLO command with this new custom cfg:\n    yolo cfg='{new_file}' imgsz=320 batch=8"
+    )
+
+
+if __name__ == "__main__":
+    # Example: entrypoint(debug='yolo predict model=yolo11n.pt')
+    entrypoint(debug="")

+ 130 - 0
ultralytics/default.yaml

@@ -0,0 +1,130 @@
+# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
+
+# Global configuration YAML with settings and hyperparameters for YOLO training, validation, prediction and export
+# For documentation see https://docs.ultralytics.com/usage/cfg/
+
+task: detect # (str) YOLO task, i.e. detect, segment, classify, pose, obb
+mode: train # (str) YOLO mode, i.e. train, val, predict, export, track, benchmark
+
+# Train settings -------------------------------------------------------------------------------------------------------
+model: # (str, optional) path to model file, i.e. yolov8n.pt, yolov8n.yaml
+data: # (str, optional) path to data file, i.e. coco8.yaml
+epochs: 100 # (int) number of epochs to train for
+time: # (float, optional) number of hours to train for, overrides epochs if supplied
+patience: 100 # (int) epochs to wait for no observable improvement for early stopping of training
+batch: 16 # (int) number of images per batch (-1 for AutoBatch)
+imgsz: 640 # (int | list) input images size as int for train and val modes, or list[h,w] for predict and export modes
+save: True # (bool) save train checkpoints and predict results
+save_period: -1 # (int) Save checkpoint every x epochs (disabled if < 1)
+cache: False # (bool) True/ram, disk or False. Use cache for data loading
+device: # (int | str | list, optional) device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu
+workers: 8 # (int) number of worker threads for data loading (per RANK if DDP)
+project: # (str, optional) project name
+name: # (str, optional) experiment name, results saved to 'project/name' directory
+exist_ok: False # (bool) whether to overwrite existing experiment
+pretrained: True # (bool | str) whether to use a pretrained model (bool) or a model to load weights from (str)
+optimizer: auto # (str) optimizer to use, choices=[SGD, Adam, Adamax, AdamW, NAdam, RAdam, RMSProp, auto]
+verbose: True # (bool) whether to print verbose output
+seed: 0 # (int) random seed for reproducibility
+deterministic: True # (bool) whether to enable deterministic mode
+single_cls: False # (bool) train multi-class data as single-class
+rect: False # (bool) rectangular training if mode='train' or rectangular validation if mode='val'
+cos_lr: False # (bool) use cosine learning rate scheduler
+close_mosaic: 10 # (int) disable mosaic augmentation for final epochs (0 to disable)
+resume: False # (bool) resume training from last checkpoint
+amp: True # (bool) Automatic Mixed Precision (AMP) training, choices=[True, False], True runs AMP check
+fraction: 1.0 # (float) dataset fraction to train on (default is 1.0, all images in train set)
+profile: False # (bool) profile ONNX and TensorRT speeds during training for loggers
+freeze: None # (int | list, optional) freeze first n layers, or freeze list of layer indices during training
+multi_scale: False # (bool) Whether to use multiscale during training
+# Segmentation
+overlap_mask: True # (bool) merge object masks into a single image mask during training (segment train only)
+mask_ratio: 4 # (int) mask downsample ratio (segment train only)
+# Classification
+dropout: 0.0 # (float) use dropout regularization (classify train only)
+
+# Val/Test settings ----------------------------------------------------------------------------------------------------
+val: True # (bool) validate/test during training
+split: val # (str) dataset split to use for validation, i.e. 'val', 'test' or 'train'
+save_json: False # (bool) save results to JSON file
+save_hybrid: False # (bool) save hybrid version of labels (labels + additional predictions)
+conf: # (float, optional) object confidence threshold for detection (default 0.25 predict, 0.001 val)
+iou: 0.7 # (float) intersection over union (IoU) threshold for NMS
+max_det: 300 # (int) maximum number of detections per image
+half: False # (bool) use half precision (FP16)
+dnn: False # (bool) use OpenCV DNN for ONNX inference
+plots: True # (bool) save plots and images during train/val
+
+# Predict settings -----------------------------------------------------------------------------------------------------
+source: # (str, optional) source directory for images or videos
+vid_stride: 1 # (int) video frame-rate stride
+stream_buffer: False # (bool) buffer all streaming frames (True) or return the most recent frame (False)
+visualize: False # (bool) visualize model features
+augment: False # (bool) apply image augmentation to prediction sources
+agnostic_nms: False # (bool) class-agnostic NMS
+classes: # (int | list[int], optional) filter results by class, i.e. classes=0, or classes=[0,2,3]
+retina_masks: False # (bool) use high-resolution segmentation masks
+embed: # (list[int], optional) return feature vectors/embeddings from given layers
+
+# Visualize settings ---------------------------------------------------------------------------------------------------
+show: False # (bool) show predicted images and videos if environment allows
+save_frames: False # (bool) save predicted individual video frames
+save_txt: False # (bool) save results as .txt file
+save_conf: False # (bool) save results with confidence scores
+save_crop: False # (bool) save cropped images with results
+show_labels: True # (bool) show prediction labels, i.e. 'person'
+show_conf: True # (bool) show prediction confidence, i.e. '0.99'
+show_boxes: True # (bool) show prediction boxes
+line_width: # (int, optional) line width of the bounding boxes. Scaled to image size if None.
+
+# Export settings ------------------------------------------------------------------------------------------------------
+format: torchscript # (str) format to export to, choices at https://docs.ultralytics.com/modes/export/#export-formats
+keras: False # (bool) use Kera=s
+optimize: False # (bool) TorchScript: optimize for mobile
+int8: False # (bool) CoreML/TF INT8 quantization
+dynamic: False # (bool) ONNX/TF/TensorRT: dynamic axes
+simplify: True # (bool) ONNX: simplify model using `onnxslim`
+opset: # (int, optional) ONNX: opset version
+workspace: None # (float, optional) TensorRT: workspace size (GiB), `None` will let TensorRT auto-allocate memory
+nms: False # (bool) CoreML: add NMS
+
+# Hyperparameters ------------------------------------------------------------------------------------------------------
+lr0: 0.01 # (float) initial learning rate (i.e. SGD=1E-2, Adam=1E-3)
+lrf: 0.01 # (float) final learning rate (lr0 * lrf)
+momentum: 0.937 # (float) SGD momentum/Adam beta1
+weight_decay: 0.0005 # (float) optimizer weight decay 5e-4
+warmup_epochs: 3.0 # (float) warmup epochs (fractions ok)
+warmup_momentum: 0.8 # (float) warmup initial momentum
+warmup_bias_lr: 0.0 # 0.1 # (float) warmup initial bias lr
+box: 7.5 # (float) box loss gain
+cls: 0.5 # (float) cls loss gain (scale with pixels)
+dfl: 1.5 # (float) dfl loss gain
+pose: 12.0 # (float) pose loss gain
+kobj: 1.0 # (float) keypoint obj loss gain
+nbs: 64 # (int) nominal batch size
+hsv_h: 0.015 # (float) image HSV-Hue augmentation (fraction)
+hsv_s: 0.7 # (float) image HSV-Saturation augmentation (fraction)
+hsv_v: 0.4 # (float) image HSV-Value augmentation (fraction)
+degrees: 0.0 # (float) image rotation (+/- deg)
+translate: 0.1 # (float) image translation (+/- fraction)
+scale: 0.5 # (float) image scale (+/- gain)
+shear: 0.0 # (float) image shear (+/- deg)
+perspective: 0.0 # (float) image perspective (+/- fraction), range 0-0.001
+flipud: 0.0 # (float) image flip up-down (probability)
+fliplr: 0.5 # (float) image flip left-right (probability)
+bgr: 0.0 # (float) image channel BGR (probability)
+
+mosaic: 1.0 # (float) image mosaic (probability)
+mixup: 0.0 # (float) image mixup (probability)
+copy_paste: 0.1 # (float) segment copy-paste (probability)
+
+copy_paste_mode: "flip" # (str) the method to do copy_paste augmentation (flip, mixup)
+auto_augment: randaugment # (str) auto augmentation policy for classification (randaugment, autoaugment, augmix)
+erasing: 0.4 # (float) probability of random erasing during classification training (0-0.9), 0 means no erasing, must be less than 1.0.
+crop_fraction: 1.0 # (float) image crop fraction for classification (0.1-1), 1.0 means no crop, must be greater than 0.
+
+# Custom config.yaml ---------------------------------------------------------------------------------------------------
+cfg: # (str, optional) for overriding defaults.yaml
+
+# Tracker settings ------------------------------------------------------------------------------------------------------
+tracker: botsort.yaml # (str) tracker type, choices=[botsort.yaml, bytetrack.yaml]

+ 21 - 0
ultralytics/trackers/botsort.yaml

@@ -0,0 +1,21 @@
+# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
+
+# Default Ultralytics settings for BoT-SORT tracker when using mode="track"
+# For documentation and examples see https://docs.ultralytics.com/modes/track/
+# For BoT-SORT source code see https://github.com/NirAharon/BoT-SORT
+
+tracker_type: botsort # tracker type, ['botsort', 'bytetrack']
+track_high_thresh: 0.25 # threshold for the first association
+track_low_thresh: 0.1 # threshold for the second association
+new_track_thresh: 0.25 # threshold for init new track if the detection does not match any tracks
+track_buffer: 30 # buffer to calculate the time when to remove tracks
+match_thresh: 0.8 # threshold for matching tracks
+fuse_score: True # Whether to fuse confidence scores with the iou distances before matching
+# min_box_area: 10  # threshold for min box areas(for tracker evaluation, not used for now)
+
+# BoT-SORT settings
+gmc_method: sparseOptFlow # method of global motion compensation
+# ReID model related thresh (not supported yet)
+proximity_thresh: 0.5
+appearance_thresh: 0.25
+with_reid: False

+ 14 - 0
ultralytics/trackers/bytetrack.yaml

@@ -0,0 +1,14 @@
+# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
+
+# Default Ultralytics settings for ByteTrack tracker when using mode="track"
+# For documentation and examples see https://docs.ultralytics.com/modes/track/
+# For ByteTrack source code see https://github.com/ifzhang/ByteTrack
+
+tracker_type: bytetrack # tracker type, ['botsort', 'bytetrack']
+track_high_thresh: 0.25 # threshold for the first association
+track_low_thresh: 0.1 # threshold for the second association
+new_track_thresh: 0.25 # threshold for init new track if the detection does not match any tracks
+track_buffer: 30 # buffer to calculate the time when to remove tracks
+match_thresh: 0.8 # threshold for matching tracks
+fuse_score: True # Whether to fuse confidence scores with the iou distances before matching
+# min_box_area: 10  # threshold for min box areas(for tracker evaluation, not used for now)