garmentiq.segmentation.model_definition.sam

The Segment Anything model family.

Covers SAM 1, SAM 2.1, and SAM 3 behind one registry, together with their bundled configurations and processors. The model classes are imported lazily, so GarmentIQ still imports on a transformers release that predates a given generation, and asking for a model your release does not carry raises a clear ImportError.

The model classes themselves are re-exported from transformers and documented upstream, so they are not repeated here. They can be imported from this module directly:

from garmentiq.segmentation.model_definition.sam import (
    SamModel, Sam2Model, Sam3Model,
)

The full set is SamModel, SamConfig, SamProcessor, Sam2Model, Sam2Config, Sam2Processor, Sam2ImageProcessor, Sam3Model, Sam3Config, Sam3Processor, Sam3ImageProcessor, Sam3TrackerModel, Sam3TrackerConfig, and Sam3TrackerProcessor.

 1# garmentiq/segmentation/model_definition/sam/__init__.py
 2"""The Segment Anything model family.
 3
 4Covers SAM 1, SAM 2.1, and SAM 3 behind one registry, together with their bundled
 5configurations and processors. The model classes are imported lazily, so GarmentIQ
 6still imports on a `transformers` release that predates a given generation, and asking
 7for a model your release does not carry raises a clear `ImportError`.
 8
 9The model classes themselves are re-exported from `transformers` and documented
10upstream, so they are not repeated here. They can be imported from this module
11directly:
12
13    from garmentiq.segmentation.model_definition.sam import (
14        SamModel, Sam2Model, Sam3Model,
15    )
16
17The full set is `SamModel`, `SamConfig`, `SamProcessor`, `Sam2Model`, `Sam2Config`,
18`Sam2Processor`, `Sam2ImageProcessor`, `Sam3Model`, `Sam3Config`, `Sam3Processor`,
19`Sam3ImageProcessor`, `Sam3TrackerModel`, `Sam3TrackerConfig`, and
20`Sam3TrackerProcessor`.
21"""
22from .sam import (
23    load_sam_config,
24    load_sam_processor,
25    load_sam3_tracker,
26    load_sam3_tracker_config,
27    load_sam3_tracker_processor,
28    sam_family,
29    sam_capabilities,
30    sam_model_class,
31    SAM1_MODELS,
32    SAM2_MODELS,
33    SAM3_MODELS,
34    VALID_SAM_MODELS,
35    ALL_SAM_MODELS,
36    SAM_CAPABILITIES,
37    SAM_PROMPT_DEPTHS,
38)
39
40# Model classes come from transformers and are resolved on first access, so that
41# importing GarmentIQ does not require a transformers release new enough to
42# provide every SAM generation.
43_LAZY = {
44    "Sam3TrackerModel",
45    "Sam3TrackerConfig",
46    "Sam3TrackerProcessor",
47    "Sam3ImageProcessor",
48    "SamModel",
49    "SamConfig",
50    "SamProcessor",
51    "Sam2Model",
52    "Sam2Config",
53    "Sam2Processor",
54    "Sam2ImageProcessor",
55    "Sam3Model",
56    "Sam3Config",
57    "Sam3Processor",
58}
59
60
61def __getattr__(name):
62    """Defer transformers imports until a SAM class is actually requested."""
63    if name in _LAZY:
64        from . import sam
65
66        return getattr(sam, name)
67    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
68
69
70__all__ = [
71    "load_sam_config",
72    "load_sam_processor",
73    "load_sam3_tracker",
74    "load_sam3_tracker_config",
75    "load_sam3_tracker_processor",
76    "sam_family",
77    "sam_capabilities",
78    "sam_model_class",
79    "SAM1_MODELS",
80    "SAM2_MODELS",
81    "SAM3_MODELS",
82    "VALID_SAM_MODELS",
83    "ALL_SAM_MODELS",
84    "SAM_CAPABILITIES",
85    "SAM_PROMPT_DEPTHS",
86]
87
88
89def __dir__():
90    """List the lazily resolved model classes alongside the eager exports."""
91    return sorted(set(__all__) | _LAZY)
def load_sam_config(model_type: str = 'sam-vit-b', model_dir: Optional[str] = None):
251def load_sam_config(model_type: str = "sam-vit-b", model_dir: Optional[str] = None):
252    """
253    Reads and loads the configuration for a specified Segment Anything Model variant.
254
255    This function facilitates strictly offline initialization by dynamically locating the
256    `config.json` file associated with the chosen SAM variant within the local package
257    directory. It reads the JSON file securely and converts it into the Hugging Face
258    configuration object matching the variant's family, entirely bypassing external
259    network requests.
260
261    Configurations for SAM 1 (`sam-vit-*`), SAM 2.1 (`sam2.1-hiera-*`) and SAM 3 (`sam3`)
262    all ship with the package, so no Hugging Face access is needed. SAM 3 weights are still
263    gated, so download the checkpoint once and point `model_path` at it when loading the
264    model; `model_dir` here only overrides the bundled configuration.
265
266    Released SAM 3 configurations describe the video model and nest the image model under
267    `detector_config`. GarmentIQ segments still images, so that nested section is unwrapped
268    automatically.
269
270    Args:
271        model_type (str, optional): The identifier for the desired SAM variant. Must be one
272                                    of `["sam-vit-b", "sam-vit-l", "sam-vit-h",
273                                    "sam2.1-hiera-tiny", "sam2.1-hiera-small",
274                                    "sam2.1-hiera-base-plus", "sam2.1-hiera-large", "sam3"]`.
275                                    Default is `"sam-vit-b"`.
276        model_dir (str, optional): Path to a local directory containing the variant's
277                                   `config.json`, used to override the bundled configuration.
278                                   Default is None.
279
280    Raises:
281        ValueError: If the provided `model_type` is not within the supported variants list.
282        FileNotFoundError: If the corresponding offline `config.json` file cannot be located.
283
284    Returns:
285        Union[SamConfig, Sam2Config, Sam3Config]: The loaded configuration object ready to be
286                                                  passed into the matching SAM model class.
287    """
288    family = sam_family(model_type)
289    config_path = os.path.join(_variant_dir(model_type, model_dir), "config.json")
290
291    if not os.path.exists(config_path):
292        raise FileNotFoundError(f"Offline config missing at {config_path}.")
293
294    with open(config_path, "r") as f:
295        config_dict = json.load(f)
296
297    config_dict = _unwrap_detector_config(config_dict)
298
299    return _resolve(SAM_FAMILIES[family]["config_class"]).from_dict(config_dict)

Reads and loads the configuration for a specified Segment Anything Model variant.

This function facilitates strictly offline initialization by dynamically locating the config.json file associated with the chosen SAM variant within the local package directory. It reads the JSON file securely and converts it into the Hugging Face configuration object matching the variant's family, entirely bypassing external network requests.

Configurations for SAM 1 (sam-vit-*), SAM 2.1 (sam2.1-hiera-*) and SAM 3 (sam3) all ship with the package, so no Hugging Face access is needed. SAM 3 weights are still gated, so download the checkpoint once and point model_path at it when loading the model; model_dir here only overrides the bundled configuration.

Released SAM 3 configurations describe the video model and nest the image model under detector_config. GarmentIQ segments still images, so that nested section is unwrapped automatically.

Arguments:
  • model_type (str, optional): The identifier for the desired SAM variant. Must be one of ["sam-vit-b", "sam-vit-l", "sam-vit-h", "sam2.1-hiera-tiny", "sam2.1-hiera-small", "sam2.1-hiera-base-plus", "sam2.1-hiera-large", "sam3"]. Default is "sam-vit-b".
  • model_dir (str, optional): Path to a local directory containing the variant's config.json, used to override the bundled configuration. Default is None.
Raises:
  • ValueError: If the provided model_type is not within the supported variants list.
  • FileNotFoundError: If the corresponding offline config.json file cannot be located.
Returns:

Union[SamConfig, Sam2Config, Sam3Config]: The loaded configuration object ready to be passed into the matching SAM model class.

def load_sam_processor( model_type: str = 'sam-vit-b', use_fast: Optional[bool] = None, model_dir: Optional[str] = None, backend: Optional[str] = None):
319def load_sam_processor(
320    model_type: str = "sam-vit-b",
321    use_fast: Optional[bool] = None,
322    model_dir: Optional[str] = None,
323    backend: Optional[str] = None,
324):
325    """
326    Loads the offline processor for a specified Segment Anything Model variant.
327
328    This function instantiates the processor matching the variant's family by reading
329    bundled preprocessor (and, for SAM 3, tokenizer) configuration files from the local
330    variant directory. Loading from a local path ensures the package remains completely
331    air-gapped. The image resizing backend can be selected to balance speed against
332    strict backward compatibility.
333
334    Args:
335        model_type (str, optional): The identifier for the desired SAM variant.
336                                    Default is `"sam-vit-b"`.
337        use_fast (bool, optional): Deprecated alias for `backend`, kept for backwards
338                                   compatibility. `True` maps to `"torchvision"` and `False`
339                                   maps to `"pil"`. Only applies to SAM 1. Default is None.
340        model_dir (str, optional): Path to a local directory containing the variant's
341                                   processor files, used to override the bundled ones.
342                                   Default is None.
343        backend (str, optional): Image resizing backend, either `"pil"` or `"torchvision"`.
344                                 `"torchvision"` is faster, while `"pil"` matches the
345                                 historical GarmentIQ default. Only applies to SAM 1.
346                                 Default is None, which resolves to `"pil"`.
347
348    Raises:
349        ValueError: If the provided `model_type` is not within the supported variants list,
350                    or if `backend` is neither `"pil"` nor `"torchvision"`.
351        FileNotFoundError: If the corresponding offline processor configuration cannot be
352                           located.
353
354    Returns:
355        Union[SamProcessor, Sam2Processor, Sam3Processor]: The instantiated processor ready
356                                                           for image and prompt transformations.
357    """
358    family = sam_family(model_type)
359    variant_dir = _variant_dir(model_type, model_dir)
360
361    if backend is None and use_fast is not None:
362        backend = "torchvision" if use_fast else "pil"
363    if backend is None:
364        # Historical GarmentIQ default. Selected explicitly so results stay identical
365        # across transformers releases, which have shifted their own default over time.
366        backend = "pil"
367    if backend not in ("pil", "torchvision"):
368        raise ValueError(
369            f"Invalid backend {backend!r}. Choose either 'pil' or 'torchvision'."
370        )
371
372    if family == "sam1":
373        processor_path = os.path.join(variant_dir, "preprocessor_config.json")
374        if not os.path.exists(processor_path):
375            raise FileNotFoundError(
376                f"Offline processor config missing at {processor_path}."
377            )
378        # transformers 5.4 replaced `use_fast` with `backend`; passing the deprecated
379        # flag to a newer release emits a warning, so select the kwarg by version.
380        backend_kwargs = (
381            {"backend": backend}
382            if _supports_backend_kwarg()
383            else {"use_fast": backend == "torchvision"}
384        )
385        # Loading from a local directory disables Hugging Face network calls
386        return _resolve("SamProcessor").from_pretrained(
387            processor_path, **backend_kwargs
388        )
389
390    if family == "sam2":
391        processor_path = os.path.join(variant_dir, "preprocessor_config.json")
392        if not os.path.exists(processor_path):
393            raise FileNotFoundError(
394                f"Offline processor config missing at {processor_path}."
395            )
396        with open(processor_path, "r") as f:
397            image_processor_dict = json.load(f)
398        # The bundled config names the deprecated `*Fast` class; build the image
399        # processor explicitly so loading stays offline and warning-free.
400        image_processor_dict.pop("image_processor_type", None)
401        image_processor = _resolve("Sam2ImageProcessor")(**image_processor_dict)
402        return _resolve("Sam2Processor")(image_processor=image_processor)
403
404    # SAM 3 bundles a tokenizer alongside the image processor, so the whole
405    # directory is handed to the processor loader.
406    return _resolve("Sam3Processor").from_pretrained(variant_dir)

Loads the offline processor for a specified Segment Anything Model variant.

This function instantiates the processor matching the variant's family by reading bundled preprocessor (and, for SAM 3, tokenizer) configuration files from the local variant directory. Loading from a local path ensures the package remains completely air-gapped. The image resizing backend can be selected to balance speed against strict backward compatibility.

Arguments:
  • model_type (str, optional): The identifier for the desired SAM variant. Default is "sam-vit-b".
  • use_fast (bool, optional): Deprecated alias for backend, kept for backwards compatibility. True maps to "torchvision" and False maps to "pil". Only applies to SAM 1. Default is None.
  • model_dir (str, optional): Path to a local directory containing the variant's processor files, used to override the bundled ones. Default is None.
  • backend (str, optional): Image resizing backend, either "pil" or "torchvision". "torchvision" is faster, while "pil" matches the historical GarmentIQ default. Only applies to SAM 1. Default is None, which resolves to "pil".
Raises:
  • ValueError: If the provided model_type is not within the supported variants list, or if backend is neither "pil" nor "torchvision".
  • FileNotFoundError: If the corresponding offline processor configuration cannot be located.
Returns:

Union[SamProcessor, Sam2Processor, Sam3Processor]: The instantiated processor ready for image and prompt transformations.

def load_sam3_tracker( model_path: str, model_dir: Optional[str] = None, device: Union[str, torch.device] = 'cpu'):
467def load_sam3_tracker(
468    model_path: str,
469    model_dir: Optional[str] = None,
470    device: Union[str, torch.device] = "cpu",
471):
472    """
473    Loads SAM 3's point-promptable tracker from a released SAM 3 checkpoint.
474
475    SAM 3 ships as a single checkpoint holding both the detector and the tracker, and the
476    two share one vision encoder that is stored only once under the detector's prefix. This
477    function reassembles the tracker by pairing `tracker_model.*` weights with the shared
478    `detector_model.vision_encoder.*` backbone, then verifies every expected tensor was
479    found so a mismatched checkpoint fails loudly instead of yielding a random model.
480
481    Use this when you want to prompt SAM 3 with points on a still image. For text or box
482    prompts use the detector via `Sam3Model` and `load_sam_config("sam3")` instead.
483
484    Args:
485        model_path (str): Local path to the SAM 3 `model.safetensors` checkpoint.
486        model_dir (str, optional): Directory holding `tracker_config.json`, used to
487                                   override the bundled configuration. Default is None.
488        device (Union[str, torch.device], optional): The device to load onto, e.g. `"cpu"`,
489                                                     `"cuda"`, or `"mps"`. Default is `"cpu"`.
490
491    Raises:
492        FileNotFoundError: If `model_path` does not exist.
493        ValueError: If the checkpoint does not contain the tensors the tracker expects, or
494                    if the requested `device` is unavailable.
495        ImportError: If the installed transformers release does not provide SAM 3.
496
497    Returns:
498        Sam3TrackerModel: The assembled tracker in evaluation mode, placed on `device`.
499    """
500    from safetensors.torch import load_file
501
502    from garmentiq.utils.device import resolve_device
503
504    if not os.path.exists(model_path):
505        raise FileNotFoundError(f"SAM 3 checkpoint not found at {model_path}.")
506
507    device = resolve_device(device)
508
509    model = _resolve("Sam3TrackerModel")(load_sam3_tracker_config(model_dir))
510    expected = model.state_dict()
511
512    if model_path.endswith(".safetensors"):
513        state_dict = load_file(model_path, device="cpu")
514    else:
515        state_dict = torch.load(model_path, map_location="cpu", weights_only=True)
516
517    shared_prefix = SAM3_DETECTOR_PREFIX + "vision_encoder."
518    neck_prefix = shared_prefix + "neck."
519    assembled = {}
520    for key, value in state_dict.items():
521        if key.startswith(neck_prefix):
522            # The detector has its own neck with the same layer names as the tracker's.
523            # Skip it: the tracker's neck is stored separately under `tracker_neck.`,
524            # and using the detector's would silently produce a garbage mask.
525            continue
526        if key.startswith(shared_prefix):
527            # The vision encoder backbone is shared, and stored once under the detector.
528            assembled[key[len(SAM3_DETECTOR_PREFIX) :]] = value
529        elif key.startswith(SAM3_TRACKER_NECK_PREFIX):
530            assembled[
531                "vision_encoder.neck." + key[len(SAM3_TRACKER_NECK_PREFIX) :]
532            ] = value
533        elif key.startswith(SAM3_TRACKER_PREFIX):
534            stripped = key[len(SAM3_TRACKER_PREFIX) :]
535            if stripped in expected:
536                assembled[stripped] = value
537
538    missing = set(expected) - set(assembled)
539    if missing:
540        raise ValueError(
541            f"SAM 3 tracker weights are incomplete: {len(missing)} of {len(expected)} "
542            f"tensors were not found in {model_path!r} "
543            f"(first missing: {sorted(missing)[:3]}). Check that the checkpoint is a "
544            f"full SAM 3 release."
545        )
546
547    model.load_state_dict(assembled, strict=True)
548    model = model.to(device)
549    model.eval()
550    return model

Loads SAM 3's point-promptable tracker from a released SAM 3 checkpoint.

SAM 3 ships as a single checkpoint holding both the detector and the tracker, and the two share one vision encoder that is stored only once under the detector's prefix. This function reassembles the tracker by pairing tracker_model.* weights with the shared detector_model.vision_encoder.* backbone, then verifies every expected tensor was found so a mismatched checkpoint fails loudly instead of yielding a random model.

Use this when you want to prompt SAM 3 with points on a still image. For text or box prompts use the detector via Sam3Model and load_sam_config("sam3") instead.

Arguments:
  • model_path (str): Local path to the SAM 3 model.safetensors checkpoint.
  • model_dir (str, optional): Directory holding tracker_config.json, used to override the bundled configuration. Default is None.
  • device (Union[str, torch.device], optional): The device to load onto, e.g. "cpu", "cuda", or "mps". Default is "cpu".
Raises:
  • FileNotFoundError: If model_path does not exist.
  • ValueError: If the checkpoint does not contain the tensors the tracker expects, or if the requested device is unavailable.
  • ImportError: If the installed transformers release does not provide SAM 3.
Returns:

Sam3TrackerModel: The assembled tracker in evaluation mode, placed on device.

def load_sam3_tracker_config(model_dir: Optional[str] = None):
409def load_sam3_tracker_config(model_dir: Optional[str] = None):
410    """
411    Reads and loads the bundled configuration for SAM 3's point-promptable tracker.
412
413    SAM 3's image model is an open-vocabulary detector prompted by text or boxes, and does
414    not accept points. The release also contains a tracker, whose prompt encoder is the
415    SAM-style one that understands points, boxes and masks. This function loads that
416    tracker's configuration so still images can be segmented from a click.
417
418    Args:
419        model_dir (str, optional): Path to a local directory containing
420                                   `tracker_config.json`, used to override the bundled
421                                   configuration. Default is None.
422
423    Raises:
424        FileNotFoundError: If the offline `tracker_config.json` cannot be located.
425        ImportError: If the installed transformers release does not provide SAM 3.
426
427    Returns:
428        Sam3TrackerConfig: The configuration for `Sam3TrackerModel`.
429    """
430    variant_dir = _variant_dir("sam3", model_dir)
431    config_path = os.path.join(variant_dir, "tracker_config.json")
432
433    if not os.path.exists(config_path):
434        # A directly downloaded SAM 3 release nests it inside the video config.
435        fallback = os.path.join(variant_dir, "config.json")
436        if os.path.exists(fallback):
437            with open(fallback, "r") as f:
438                nested = json.load(f).get("tracker_config")
439            if isinstance(nested, dict):
440                return _resolve("Sam3TrackerConfig").from_dict(nested)
441        raise FileNotFoundError(f"Offline tracker config missing at {config_path}.")
442
443    with open(config_path, "r") as f:
444        config_dict = json.load(f)
445
446    return _resolve("Sam3TrackerConfig").from_dict(config_dict)

Reads and loads the bundled configuration for SAM 3's point-promptable tracker.

SAM 3's image model is an open-vocabulary detector prompted by text or boxes, and does not accept points. The release also contains a tracker, whose prompt encoder is the SAM-style one that understands points, boxes and masks. This function loads that tracker's configuration so still images can be segmented from a click.

Arguments:
  • model_dir (str, optional): Path to a local directory containing tracker_config.json, used to override the bundled configuration. Default is None.
Raises:
  • FileNotFoundError: If the offline tracker_config.json cannot be located.
  • ImportError: If the installed transformers release does not provide SAM 3.
Returns:

Sam3TrackerConfig: The configuration for Sam3TrackerModel.

def load_sam3_tracker_processor():
449def load_sam3_tracker_processor():
450    """
451    Builds the processor for SAM 3's point-promptable tracker.
452
453    The tracker takes only geometric prompts, so unlike `load_sam_processor("sam3")` no
454    tokenizer is involved. The image processor is constructed from its defaults, which
455    keeps loading fully offline.
456
457    Raises:
458        ImportError: If the installed transformers release does not provide SAM 3.
459
460    Returns:
461        Sam3TrackerProcessor: The processor for `Sam3TrackerModel`.
462    """
463    image_processor = _resolve("Sam3ImageProcessor")()
464    return _resolve("Sam3TrackerProcessor")(image_processor=image_processor)

Builds the processor for SAM 3's point-promptable tracker.

The tracker takes only geometric prompts, so unlike load_sam_processor("sam3") no tokenizer is involved. The image processor is constructed from its defaults, which keeps loading fully offline.

Raises:
  • ImportError: If the installed transformers release does not provide SAM 3.
Returns:

Sam3TrackerProcessor: The processor for Sam3TrackerModel.

def sam_family(model_type: str) -> str:
142def sam_family(model_type: str) -> str:
143    """
144    Returns the Segment Anything family a variant belongs to.
145
146    Args:
147        model_type (str): A SAM variant identifier, e.g. `"sam-vit-b"`,
148                          `"sam2.1-hiera-tiny"`, or `"sam3"`.
149
150    Raises:
151        ValueError: If `model_type` is not a recognised SAM variant.
152
153    Returns:
154        str: One of `"sam1"`, `"sam2"`, or `"sam3"`.
155    """
156    for family, spec in SAM_FAMILIES.items():
157        if model_type in spec["models"]:
158            return family
159    raise ValueError(
160        f"Invalid model_type '{model_type}'. Choose from: {ALL_SAM_MODELS}"
161    )

Returns the Segment Anything family a variant belongs to.

Arguments:
  • model_type (str): A SAM variant identifier, e.g. "sam-vit-b", "sam2.1-hiera-tiny", or "sam3".
Raises:
  • ValueError: If model_type is not a recognised SAM variant.
Returns:

str: One of "sam1", "sam2", or "sam3".

def sam_capabilities(model_type: str) -> dict:
164def sam_capabilities(model_type: str) -> dict:
165    """
166    Reports which prompt types a SAM variant accepts natively.
167
168    Args:
169        model_type (str): A SAM variant identifier, e.g. `"sam-vit-b"` or `"sam3"`.
170
171    Raises:
172        ValueError: If `model_type` is not a recognised SAM variant.
173
174    Returns:
175        dict: Mapping of `"points"`, `"labels"`, `"boxes"`, and `"text"` to booleans.
176              SAM 1 and SAM 2 report `text=False` because they contain no text encoder,
177              and SAM 3 reports `points=False` because it accepts only text and box prompts.
178    """
179    return dict(SAM_CAPABILITIES[sam_family(model_type)])

Reports which prompt types a SAM variant accepts natively.

Arguments:
  • model_type (str): A SAM variant identifier, e.g. "sam-vit-b" or "sam3".
Raises:
  • ValueError: If model_type is not a recognised SAM variant.
Returns:

dict: Mapping of "points", "labels", "boxes", and "text" to booleans. SAM 1 and SAM 2 report text=False because they contain no text encoder, and SAM 3 reports points=False because it accepts only text and box prompts.

def sam_model_class(model_type: str):
182def sam_model_class(model_type: str):
183    """
184    Returns the Hugging Face model class matching a SAM variant.
185
186    Args:
187        model_type (str): A SAM variant identifier, e.g. `"sam2.1-hiera-tiny"`.
188
189    Raises:
190        ValueError: If `model_type` is not a recognised SAM variant.
191
192    Returns:
193        type: `SamModel`, `Sam2Model`, or `Sam3Model`.
194    """
195    return _resolve(SAM_FAMILIES[sam_family(model_type)]["model_class"])

Returns the Hugging Face model class matching a SAM variant.

Arguments:
  • model_type (str): A SAM variant identifier, e.g. "sam2.1-hiera-tiny".
Raises:
  • ValueError: If model_type is not a recognised SAM variant.
Returns:

type: SamModel, Sam2Model, or Sam3Model.

SAM1_MODELS = ['sam-vit-b', 'sam-vit-l', 'sam-vit-h']
SAM2_MODELS = ['sam2.1-hiera-tiny', 'sam2.1-hiera-small', 'sam2.1-hiera-base-plus', 'sam2.1-hiera-large']
SAM3_MODELS = ['sam3']
VALID_SAM_MODELS = ['sam-vit-b', 'sam-vit-l', 'sam-vit-h']
ALL_SAM_MODELS = ['sam-vit-b', 'sam-vit-l', 'sam-vit-h', 'sam2.1-hiera-tiny', 'sam2.1-hiera-small', 'sam2.1-hiera-base-plus', 'sam2.1-hiera-large', 'sam3']
SAM_CAPABILITIES = {'sam1': {'points': True, 'labels': True, 'boxes': True, 'text': False}, 'sam2': {'points': True, 'labels': True, 'boxes': True, 'text': False}, 'sam3': {'points': False, 'labels': False, 'boxes': True, 'text': True}, 'sam3-tracker': {'points': True, 'labels': True, 'boxes': True, 'text': False}}
SAM_PROMPT_DEPTHS = {'sam1': {'points': 3, 'labels': 2, 'boxes': 3}, 'sam2': {'points': 4, 'labels': 3, 'boxes': 3}, 'sam3': {'boxes': 3}, 'sam3-tracker': {'points': 4, 'labels': 3, 'boxes': 3}}