Anchors Annotator

Draw anchor points on detected objects to visualize trigger positions for zones and crossings.

Output
PixelFlow Anchors Annotator

Overview

The anchors() annotator draws small circles at specific anchor positions on each detection's bounding box. These anchor points are the same positions used by the zone and crossing trigger systems to determine if an object is inside a zone or has crossed a line. This is useful for debugging trigger strategies and understanding detection behavior.

Python
pf.annotators.anchors(image, detections)

Function Signature

Python
def anchors(    image: np.ndarray,    detections: Detections,    strategy: Union[str, List[str]] = None,    radius: Optional[int] = None,    thickness: Optional[int] = None,    colors: Optional[List[tuple]] = None) -> 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.
strategy str, List[str], or None None Which anchor(s) to draw. None = all 9 anchors.
radius int or None None Circle radius in pixels. None = auto-adapt.
thickness int or None None Circle outline thickness. None = -1 (filled).
colors List[tuple] or None None List of BGR colors. None = use default palette.

Returns:
np.ndarray - The input image with anchor points drawn (same array, modified in-place).

Basic Usage

Python
import cv2import pixelflow as pffrom ultralytics import YOLO# Load image and run detectionimage = cv2.imread("pedestrians.jpg")model = YOLO("yolo11n.pt")results = model.predict(image)detections = pf.from_ultralytics(results)# Draw all anchor points (9 per detection)image = pf.annotators.box(image, detections)image = pf.annotators.anchors(image, detections)cv2.imshow("Result", image)cv2.waitKey(0)

Anchor Positions

There are 9 anchor positions available on each bounding box:

Text only
┌─────────────────────────────────────┐│ top_left    top_center    top_right ││      ●          ●            ●      ││                                     ││ left_center    center   right_center││      ●          ●            ●      ││                                     ││bottom_left bottom_center bottom_right│      ●          ●            ●      │└─────────────────────────────────────┘
Strategy Position Common Use Case
center Center of bbox General object location
bottom_center Bottom center edge Pedestrian ground position
top_left Top-left corner Corner-based triggers
top_right Top-right corner Corner-based triggers
bottom_left Bottom-left corner Vehicle wheel position
bottom_right Bottom-right corner Vehicle wheel position
top_center Top center edge Head position tracking
left_center Left center edge Side-based triggers
right_center Right center edge Side-based triggers

Strategy Selection

Single Anchor Point

Python
# Draw only center pointsimage = pf.annotators.anchors(image, detections, strategy="center")# Draw only bottom center (common for pedestrians)image = pf.annotators.anchors(image, detections, strategy="bottom_center")

Multiple Anchor Points

Python
# Draw all four cornerscorners = ["top_left", "top_right", "bottom_left", "bottom_right"]image = pf.annotators.anchors(image, detections, strategy=corners)# Draw center and bottom centerimage = pf.annotators.anchors(image, detections, strategy=["center", "bottom_center"])

All Anchor Points (Default)

Python
# Draw all 9 anchor points (default when strategy=None)image = pf.annotators.anchors(image, detections)
Output
strategy=[corners]
Output
strategy="center"

Styling Options

Circle Radius

Python
# Small dotsimage = pf.annotators.anchors(image, detections, radius=3)# Large circlesimage = pf.annotators.anchors(image, detections, radius=10)

Filled vs Outline

Python
# Filled circles (default)image = pf.annotators.anchors(image, detections, thickness=-1)# Outline circlesimage = pf.annotators.anchors(image, detections, thickness=2)

Custom Colors

Python
# Single color for all anchorsimage = pf.annotators.anchors(    image, detections,    strategy="center",    colors=[(0, 255, 0)]  # Green)# Multiple colors per classcustom_colors = [(0, 255, 0), (0, 0, 255), (255, 0, 0)]image = pf.annotators.anchors(image, detections, colors=custom_colors)

Common Patterns

Debug Zone Triggers

Visualize which anchor point is being used for zone detection:

Python
# Zone uses bottom_center trigger strategyzones = pf.Zones()zones.add_zone(polygon, trigger_strategy="bottom_center")# Visualize the trigger pointimage = pf.annotators.box(image, detections)image = pf.annotators.anchors(image, detections, strategy="bottom_center")image = pf.annotators.zones(image, zones)

Debug Line Crossings

Python
# Crossing uses center triggercrossings = pf.Crossings()crossings.add_crossing(start, end, triggering_anchor="center")# Visualize the trigger pointimage = pf.annotators.box(image, detections)image = pf.annotators.anchors(image, detections, strategy="center")image = pf.annotators.crossings(image, crossings)

Pedestrian Ground Position

Python
# Show where pedestrians touch the groundimage = pf.annotators.box(image, detections)image = pf.annotators.anchors(    image, detections,    strategy="bottom_center",    radius=5,    colors=[(0, 255, 255)]  # Cyan dots)

Compare Multiple Strategies

Python
# Compare center vs bottom_center visuallyimage1 = image.copy()image2 = image.copy()pf.annotators.box(image1, detections)pf.annotators.anchors(image1, detections, strategy="center")pf.annotators.box(image2, detections)pf.annotators.anchors(image2, detections, strategy="bottom_center")

Notes

  • In-place modification: The input image is modified directly. Use image.copy() if you need the original preserved.
  • Adaptive sizing: Radius automatically scales with image size when not specified.
  • Filled by default: Uses thickness=-1 for filled circles unless specified otherwise.
  • Error handling: Invalid strategy strings are skipped gracefully without raising errors.
  • Zone/Crossing sync: Use the same strategy here as in your zone or crossing configuration to visualize trigger points accurately.

See Also

  • zones() - Draw zone boundaries
  • crossings() - Draw crossing lines
  • box() - Draw bounding boxes
  • Zones.add_zone() - Configure zone trigger strategies