CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sahi

A vision library for performing sliced inference on large images/small objects

Pending
Overview
Eval results
Files

image-slicing.mddocs/

Image Slicing

SAHI's image slicing capabilities enable processing of large images by dividing them into smaller, overlapping patches. This approach significantly improves small object detection performance and enables processing of images that exceed memory or model input size limitations.

Capabilities

Slice Bounding Box Generation

Generates coordinate bounding boxes for slicing an image into overlapping crops with automatic parameter calculation.

def get_slice_bboxes(
    image_height: int,
    image_width: int,
    slice_height: Optional[int] = None,
    slice_width: Optional[int] = None,
    auto_slice_resolution: Optional[bool] = True,
    overlap_height_ratio: Optional[float] = 0.2,
    overlap_width_ratio: Optional[float] = 0.2,
) -> List[List[int]]:
    """
    Generate bounding boxes for slicing an image into crops.
    
    Parameters:
    - image_height (int): Height of the original image
    - image_width (int): Width of the original image  
    - slice_height (int, optional): Height of each slice
    - slice_width (int, optional): Width of each slice
    - auto_slice_resolution (bool): Auto-calculate slice dimensions from image size
    - overlap_height_ratio (float): Fractional vertical overlap between slices (0-1)
    - overlap_width_ratio (float): Fractional horizontal overlap between slices (0-1)
    
    Returns:
    List[List[int]]: List of slice bounding boxes as [xmin, ymin, xmax, ymax]
    """

Image Slicing

Slice an image into overlapping patches and save them with optional output directory management.

def slice_image(
    image: Union[str, Image.Image],
    output_file_name: Optional[str] = None,
    output_dir: Optional[str] = None,
    slice_height: int = 512,
    slice_width: int = 512,
    overlap_height_ratio: float = 0.2,
    overlap_width_ratio: float = 0.2,
    auto_slice_resolution: bool = True,
    min_area_ratio: float = 0.1,
    out_ext: Optional[str] = None,
    verbose: bool = False,
) -> SliceImageResult:
    """
    Slice image into overlapping crops with automatic file management.
    
    Parameters:
    - image: Image path (str) or PIL Image object
    - output_file_name (str, optional): Base name for output files
    - output_dir (str, optional): Directory for saving sliced images  
    - slice_height (int): Height of each slice in pixels
    - slice_width (int): Width of each slice in pixels
    - overlap_height_ratio (float): Vertical overlap ratio between slices
    - overlap_width_ratio (float): Horizontal overlap ratio between slices
    - auto_slice_resolution (bool): Auto-calculate optimal slice dimensions
    - min_area_ratio (float): Minimum area ratio for valid slices
    - out_ext (str, optional): Output file extension
    - verbose (bool): Print slicing progress
    
    Returns:
    SliceImageResult: Container with sliced images and metadata
    """

COCO Dataset Slicing

Slice COCO format datasets including images and annotations with proper annotation mapping and filtering.

def slice_coco(
    coco_annotation_file_path: str,
    image_dir: str,
    output_coco_annotation_file_name: str = "",
    output_dir: Optional[str] = None,
    ignore_negative_samples: bool = False,
    slice_height: int = 512,
    slice_width: int = 512,
    overlap_height_ratio: float = 0.2,
    overlap_width_ratio: float = 0.2,
    min_area_ratio: float = 0.1,
    verbose: bool = False,
) -> str:
    """
    Slice COCO dataset including images and annotations.
    
    Parameters:
    - coco_annotation_file_path (str): Path to COCO format JSON file
    - image_dir (str): Directory containing dataset images
    - output_coco_annotation_file_name (str): Name for output annotation file
    - output_dir (str, optional): Output directory for sliced dataset
    - ignore_negative_samples (bool): Skip slices without annotations
    - slice_height (int): Height of each slice
    - slice_width (int): Width of each slice  
    - overlap_height_ratio (float): Vertical overlap between slices
    - overlap_width_ratio (float): Horizontal overlap between slices
    - min_area_ratio (float): Minimum annotation area ratio to keep
    - verbose (bool): Print progress information
    
    Returns:
    str: Path to output COCO annotation file
    """

Automatic Slice Parameter Calculation

Automatically determine optimal slice parameters based on image resolution and orientation.

def get_auto_slice_params(
    height: int, 
    width: int
) -> Tuple[int, int]:
    """
    Automatically calculate slice parameters from image dimensions.
    
    Parameters:
    - height (int): Image height
    - width (int): Image width
    
    Returns:
    Tuple[int, int]: Optimal (slice_height, slice_width)
    """

Annotation Processing

Process annotations for slicing operations including coordinate transformations and filtering.

def annotation_inside_slice(
    annotation: Dict,
    slice_bbox: List[int],
    min_area_ratio: float = 0.1
) -> bool:
    """
    Check if annotation is sufficiently inside slice boundaries.
    
    Parameters:
    - annotation (Dict): COCO format annotation dictionary
    - slice_bbox (List[int]): Slice bounding box [xmin, ymin, xmax, ymax]  
    - min_area_ratio (float): Minimum area ratio threshold
    
    Returns:
    bool: True if annotation should be included in slice
    """

def process_coco_annotations(
    coco_annotation_list: List[Dict],
    slice_bbox: List[int],
    min_area_ratio: float = 0.1,
    full_shape: Optional[List[int]] = None
) -> List[Dict]:
    """
    Process COCO annotations for a specific slice.
    
    Parameters:
    - coco_annotation_list: List of COCO annotation dictionaries
    - slice_bbox: Slice bounding box coordinates
    - min_area_ratio: Minimum area ratio for keeping annotations
    - full_shape: Original image dimensions
    
    Returns:
    List[Dict]: Processed annotations with updated coordinates
    """

Coordinate Transformation Utilities

Utilities for shifting bounding boxes and masks between coordinate systems.

def shift_bboxes(
    boxes: np.ndarray,
    shift_amount: List[int]
) -> np.ndarray:
    """
    Shift bounding boxes by specified offset.
    
    Parameters:
    - boxes (np.ndarray): Bounding boxes in xyxy format
    - shift_amount (List[int]): Shift offset [x_shift, y_shift]
    
    Returns:
    np.ndarray: Shifted bounding boxes
    """

def shift_masks(
    masks: List[List],
    shift_amount: List[int]
) -> List[List]:
    """
    Shift segmentation masks by specified offset.
    
    Parameters:
    - masks: List of COCO format segmentation masks
    - shift_amount: Coordinate shift [x_shift, y_shift]
    
    Returns:
    List[List]: Shifted segmentation masks
    """

Data Structures

SliceImageResult

Container for image slicing operation results with metadata and file paths.

class SliceImageResult:
    def __init__(
        self, 
        original_image_size: List[int], 
        image_dir: str
    ):
        """
        Initialize slice result container.
        
        Parameters:
        - original_image_size: Original image dimensions [height, width]
        - image_dir: Directory containing sliced images
        """
    
    @property
    def images(self) -> List[SlicedImage]: ...
    
    @property  
    def starting_pixels(self) -> List[List[int]]: ...

SlicedImage

Individual sliced image with metadata and coordinate information.

class SlicedImage:
    def __init__(
        self, 
        image: Image.Image, 
        coco_image: CocoImage, 
        starting_pixel: List[int]
    ):
        """
        Initialize sliced image with metadata.
        
        Parameters:
        - image: PIL Image of the slice
        - coco_image: COCO format image metadata
        - starting_pixel: Top-left coordinate [x, y] in original image
        """
    
    @property
    def image(self) -> Image.Image: ...
    
    @property
    def starting_pixel(self) -> List[int]: ...

Usage Examples

Basic Image Slicing

from sahi.slicing import slice_image, get_slice_bboxes
from PIL import Image

# Calculate slice bounding boxes
image = Image.open("large_image.jpg")
height, width = image.size

slice_bboxes = get_slice_bboxes(
    image_height=height,
    image_width=width,
    slice_height=640,
    slice_width=640,
    overlap_height_ratio=0.2,
    overlap_width_ratio=0.2
)

print(f"Generated {len(slice_bboxes)} slices")

# Slice image and save crops
result = slice_image(
    image="large_image.jpg",
    output_dir="sliced_images/",
    slice_height=640,
    slice_width=640,
    overlap_height_ratio=0.2,
    overlap_width_ratio=0.2,
    verbose=True
)

print(f"Created {len(result.images)} slice images")

Automatic Slice Parameter Selection

from sahi.slicing import slice_image

# Auto-calculate optimal slice dimensions
result = slice_image(
    image="very_large_image.jpg",
    output_dir="auto_sliced/",
    auto_slice_resolution=True,  # Enable auto-calculation
    overlap_height_ratio=0.15,
    overlap_width_ratio=0.15,
    verbose=True
)

COCO Dataset Slicing

from sahi.slicing import slice_coco

# Slice entire COCO dataset
output_path = slice_coco(
    coco_annotation_file_path="dataset/annotations.json",
    image_dir="dataset/images/", 
    output_dir="sliced_dataset/",
    output_coco_annotation_file_name="sliced_annotations.json",
    slice_height=512,
    slice_width=512,
    overlap_height_ratio=0.2,
    overlap_width_ratio=0.2,
    min_area_ratio=0.1,  # Keep annotations with >=10% area in slice
    ignore_negative_samples=False,  # Keep slices without annotations
    verbose=True
)

print(f"Sliced dataset saved to: {output_path}")

Custom Annotation Processing

from sahi.slicing import process_coco_annotations, annotation_inside_slice

# Load COCO annotations
annotations = [
    {
        "bbox": [100, 150, 50, 80],  # [x, y, width, height]
        "category_id": 1,
        "area": 4000,
        "id": 1
    }
]

# Define slice region
slice_bbox = [80, 120, 200, 250]  # [xmin, ymin, xmax, ymax]

# Check if annotation should be included
should_include = annotation_inside_slice(
    annotation=annotations[0],
    slice_bbox=slice_bbox,
    min_area_ratio=0.3
)

# Process annotations for slice
processed_annotations = process_coco_annotations(
    coco_annotation_list=annotations,
    slice_bbox=slice_bbox,
    min_area_ratio=0.1,
    full_shape=[1000, 1000]
)

print(f"Processed {len(processed_annotations)} annotations for slice")

Advanced Slicing Configuration

from sahi.slicing import slice_image

# Custom slicing with specific parameters
result = slice_image(
    image="satellite_image.tif",
    output_dir="satellite_slices/",
    output_file_name="satellite_slice",
    slice_height=1024,
    slice_width=1024,
    overlap_height_ratio=0.25,  # 25% overlap
    overlap_width_ratio=0.25,
    min_area_ratio=0.05,        # Keep small partial slices
    out_ext=".png",             # Convert format
    verbose=True
)

# Access individual slices
for i, sliced_image in enumerate(result.images):
    print(f"Slice {i}: starts at {sliced_image.starting_pixel}")
    # Process individual slice
    slice_pil = sliced_image.image

Install with Tessl CLI

npx tessl i tessl/pypi-sahi

docs

annotation-framework.md

cli.md

coco-integration.md

image-slicing.md

index.md

model-integration.md

postprocessing.md

prediction-functions.md

utilities.md

tile.json