Forráskód Böngészése

Delete ultralytics/__init__.py

Mengqi Lei 2 hónapja
szülő
commit
59f0ea8873
1 módosított fájl, 0 hozzáadás és 1025 törlés
  1. 0 1025
      ultralytics/__init__.py

+ 0 - 1025
ultralytics/__init__.py

@@ -1,1025 +0,0 @@
-# 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="")