Label Annotator
Draw text labels on detected objects with templates, positioning, and multi-line support.
Overview
The label() annotator draws text labels on detected objects. It supports three modes: auto-generated labels from detection attributes, template strings with placeholders, and custom label lists. Labels can be positioned at 9 different locations relative to the bounding box and support multi-line text.
pf.annotators.label(image, detections)
Function Signature
def label( image: np.ndarray, detections: Detections, texts: Optional[Union[str, List[str]]] = None, position: str = 'top_left', font_scale: Optional[float] = None, padding: int = 6, line_spacing: int = 2, bg_color: Optional[Union[tuple, str]] = None, text_color: tuple = (255, 255, 255)) -> np.ndarray
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| image | np.ndarray | required | Input image in BGR format. Modified in-place. |
| detections | Detections | required | PixelFlow detections with bounding boxes. |
| texts | str, List[str], or None | None | Label text: None=auto, str=template, List=custom labels. |
| position | str | top_left | Label position relative to bbox (9 options). |
| font_scale | float or None | None | Font size multiplier. None = auto-adapt to image size. |
| padding | int | 6 | Padding in pixels around text inside background. |
| line_spacing | int | 2 | Extra spacing between lines for multi-line text. |
| bg_color | tuple or None | None | Background color (BGR). None = auto from class_id. |
| text_color | tuple | (255,255,255) | Text color in BGR format. Default is white. |
Returns:np.ndarray - The input image with labels drawn (same array, modified in-place).
Basic Usage
import cv2import pixelflow as pffrom ultralytics import YOLO# Load image and run detectionimage = cv2.imread("street.jpg")model = YOLO("yolo11n.pt")results = model.predict(image)detections = pf.from_ultralytics(results)# Draw labels (auto-generates "class_name: confidence")image = pf.annotators.box(image, detections)image = pf.annotators.label(image, detections)cv2.imshow("Result", image)cv2.waitKey(0)
Label Modes
Auto-Generated Labels (Default)
When texts=None, labels are automatically generated from detection attributes in the format class_name: confidence.
# Auto-generated: "person: 0.95", "car: 0.87", etc.image = pf.annotators.label(image, detections)
Template Strings
Pass a string with placeholders to create custom label formats. Available placeholders:
| Placeholder | Description | Example Output |
|---|---|---|
| {class_name} | Detection class name | person, car, dog |
| {confidence} | Confidence score (0-1) | 0.95 |
| {confidence:.1%} | Confidence as percentage | 95.0% |
| {class_id} | Numeric class identifier | 0, 1, 2 |
| {tracker_id} | Object tracking ID | 1, 2, 3 |
| {bbox} | Bounding box coordinates | (x1, y1, x2, y2) |
# Simple templateimage = pf.annotators.label(image, detections, "{class_name}")# Confidence as percentageimage = pf.annotators.label(image, detections, "{class_name}: {confidence:.1%}")# With tracker ID (for tracked objects)image = pf.annotators.label(image, detections, "ID:{tracker_id} {class_name}")
Multi-Line Labels
Include newline characters \n in templates for multi-line labels.
# Multi-line templatetemplate = """{class_name}Conf: {confidence:.0%}ID: {tracker_id}"""image = pf.annotators.label(image, detections, template)
Custom Label List
Pass a list of strings to assign specific labels to each detection. The list length should match the number of detections.
# Custom labels for each detectioncustom_labels = ["Primary Target", "Secondary", "Background Object"]image = pf.annotators.label(image, detections[:3], custom_labels)
Label Positioning
The position parameter controls where labels appear relative to the bounding box. There are 9 available positions:
┌─────────────────────────────────────┐│ top_left top_center top_right│├─────────────────────────────────────┤│ ││ center_left center center_right│ │├─────────────────────────────────────┤│bottom_left bottom_center bottom_right└─────────────────────────────────────┘
# Label above the box (default)image = pf.annotators.label(image, detections, position='top_left')# Label below the boximage = pf.annotators.label(image, detections, position='bottom_center')# Label centered inside the boximage = pf.annotators.label(image, detections, position='center')
Styling Options
Custom Colors
# Custom background color (BGR format)image = pf.annotators.label(image, detections, bg_color=(0, 100, 200))# Custom text color (black text on light background)image = pf.annotators.label( image, detections, bg_color=(200, 200, 200), text_color=(0, 0, 0))
Font and Spacing
# Larger font for presentationsimage = pf.annotators.label(image, detections, font_scale=1.2)# Compact labels with less paddingimage = pf.annotators.label(image, detections, padding=3)# More spacing between multi-line texttemplate = "{class_name}\n{confidence:.0%}"image = pf.annotators.label(image, detections, template, line_spacing=5)
Common Patterns
Box + Label (Most Common)
# Standard detection visualizationimage = pf.annotators.label(image, detections, position='bottom_center')image = pf.annotators.box(image, detections, thickness=4)
Object Tracking Display
# Show tracker IDs prominentlyimage = pf.annotators.box(image, detections)image = pf.annotators.label( image, detections, texts="#{tracker_id} {class_name}", position='top_center')
OCR Results Display
# Display detected text from OCRocr_texts = [d.ocr_data.text for d in detections if d.ocr_data]image = pf.annotators.box(image, detections)image = pf.annotators.label(image, detections, texts=ocr_texts)
Notes
-
In-place modification: The input image is modified directly. Use
image.copy()if you need the original preserved. -
Empty detections: If
detectionsis empty, the image is returned unchanged. - Adaptive sizing: Font scale automatically adapts to image resolution when not specified.
- Template fallbacks: Missing attributes in templates are replaced with default values (e.g., 'Unknown' for missing class_name).
-
Background colors: When
bg_color=None, colors are auto-assigned based on class_id for visual consistency.
See Also
-
box()- Draw bounding boxes (commonly used with labels) -
mask()- Draw segmentation masks -
anchors()- Draw anchor points on detections