Ultralytics YOLO27: Join the waitlist.
Get Started

Object Counting in Regions with Ultralytics YOLO26#

The RegionCounter solution in Ultralytics YOLO26 tracks objects across video frames and, on every frame, counts the objects whose bounding-box center falls inside each region you define. Each region is drawn on the frame with its own live count, so you can monitor several zones, such as store aisles, road lanes, or production areas, with a single Python call or CLI command.



Watch: Object Counting in Different Regions using Ultralytics YOLO | Ultralytics Solutions

Why Use Region Counting?#

  • Several zones in one pass: Pass a dictionary of named polygons and each zone gets an independent count drawn on the frame, so one video stream covers every area you care about.
  • Tracking built in: The solution runs YOLO26 detection and object tracking internally, so there is no separate tracking pipeline to wire up.
  • Counts you can read programmatically: Every processed frame returns a results object with a dictionary of region counts, ready for dashboards, alerts, or logging.

Real-World Applications#

RetailMarket Streets
Ultralytics YOLO counting people inside drawn polygon regions in a retail storeUltralytics YOLO region counts overlaid on a crowded market street
Ultralytics YOLO People Counting in RegionsUltralytics YOLO Crowd Counting in Regions

How to Count Objects in Regions with Ultralytics YOLO#

Run the RegionCounter solution on a video source from the CLI or Python. A region can be a list of points (a single zone) or a dictionary that maps zone names to point lists. The Python example below counts objects in two named regions and writes the processed frames to an output video file:

Region counting using Ultralytics YOLO
# Run a region counting example
yolo solutions region show=True

# Pass a source video
yolo solutions region source="path/to/video.mp4"

# Pass a custom region
yolo solutions region region="[(20, 400), (1080, 400), (1080, 360), (20, 360)]"

RegionCounter() Arguments#

Here's a table with the RegionCounter arguments:

ArgumentTypeDefaultDescription
modelstrNonePath to an Ultralytics YOLO model file.
regionlist or dictNonePoints defining the region of interest, either a list of (x, y) tuples or a dictionary mapping region names to point lists for multiple regions (RegionCounter only). When None, solutions that require a region fall back to a predefined default.
line_widthint2Line thickness for the boxes, keypoints and counts the solution draws.
verboseboolTrueEnables the solution's per-frame log of input shape, class counts and processing speed. The tracking call itself is always silent.

The RegionCounter solution enables the use of object tracking parameters:

ArgumentTypeDefaultDescription
trackerstr'tracktrack.yaml'Specifies the tracking algorithm to use. Built-in options: botsort.yaml, bytetrack.yaml, ocsort.yaml, deepocsort.yaml, fasttrack.yaml, tracktrack.yaml.
conffloat0.25Sets the confidence threshold for detections; lower values allow more objects to be tracked but may include false positives.
ioufloat0.7Sets the Intersection over Union (IoU) threshold for filtering overlapping detections.
classeslistNoneFilters results by class index. For example, classes=[0, 2, 3] only tracks the specified classes.
devicestrNoneSpecifies the device for inference (e.g., cpu, cuda:0 or 0). Allows users to select between CPU, a specific GPU, or other compute devices for model execution.
imgszint or tuple640Target inference image size: an integer for a square or a (height, width) pair. Shapes are adjusted to the model stride.
max_detint300Maximum number of detections kept per frame before tracking, limiting the objects a solution processes in dense scenes.
quantizeint or strNoneInference precision: 16 (FP16) or 32/unset (FP32) for PyTorch and TorchScript models off CPU; other formats use the precision their artifact and runtime select. Replaces the deprecated half arg.

Additionally, the following visualization settings are supported:

ArgumentTypeDefaultDescription
showboolFalseIf True, displays the annotated images or videos in a window. Useful for immediate visual feedback during development or testing.
show_confboolTrueDisplays the confidence score for each detection alongside the label. Gives insight into the model's certainty for each detection.
show_labelsboolTrueDisplays labels for each detection in the visual output. Provides immediate understanding of detected objects.

How Region Counting Works#

The RegionCounter solution turns each region you pass into a polygon, with at least three points per region. A plain list of points becomes a single zone named Region#01, while a dictionary keeps your own zone names; each zone is drawn in its own color from the Ultralytics palette. Every frame is then processed in three steps:

  1. YOLO26 tracking detects and follows every object in the frame
  2. For each tracked object, the solution computes the bounding-box center and checks which region polygons contain it
  3. Each region's count is drawn at its center, and the counts reset before the next frame

Because counts restart every frame, the number shown on a region is its current occupancy, meaning how many objects are inside it right now, not a running total. To count objects crossing a boundary cumulatively, use the ObjectCounter solution instead.

Each call also returns a results object whose plot_im attribute holds the annotated frame and whose region_counts dictionary maps region names to their counts, so you can feed the numbers into your own application logic.

Conclusion#

The Ultralytics YOLO26 RegionCounter solution monitors live object counts in as many named zones as you need with a few lines of code. To go further, count boundary crossings with object counting, follow objects inside a single zone with TrackZone, or explore the other Ultralytics Solutions.

FAQ#

  • Ultralytics YOLO26 counts objects in regions by tracking every object in the frame and testing whether its bounding-box center lies inside each user-defined polygon. The count shown on a region is its current occupancy for that frame, not a cumulative total. Configuration options are listed in the RegionCounter() Arguments section.

  • Pass the region argument as a dictionary that maps zone names to point lists, as in the main example:

    from ultralytics import solutions
    
    region_points = {
        "region-01": [(50, 50), (250, 50), (250, 250), (50, 250)],
        "region-02": [(640, 640), (780, 640), (780, 720), (640, 720)],
    }
    regioncounter = solutions.RegionCounter(region=region_points, model="yolo26n.pt", show=True)

    Each named zone is drawn in its own color with an independent count.

  • The object returned by each regioncounter(im0) call carries a region_counts dictionary that maps region names to their counts, alongside plot_im (the annotated frame) and total_tracks (the number of tracked objects). Print the results object to inspect all available fields.

  • Yes. Pass the classes argument with the class indices to keep, for example classes=[0] to count only persons with a COCO-pretrained model. The full list of tracking-related arguments is in the RegionCounter() Arguments section.

  • RegionCounter shows how many objects are inside each polygonal zone on the current frame, while ObjectCounter counts objects cumulatively as they cross a line or region boundary, tracking in and out totals. Use RegionCounter for live occupancy of one or more zones and ObjectCounter for entry and exit counting; line-shaped regions are supported by ObjectCounter only.

Comments99

Ask a question, share your results, or help someone else.

  1. pedmindsetpedmindsetGitHub

    Been trying to figure this out for a while now. I want to ask, can I use object counting in regions with instance sementation and tracking? You want to count vehicles that cross two specific regions, like so Object 001 crossed region A and region B. Is this possible to do

    1
    1. Glenn JocherGlenn JocherUltralytics

      @pedmindset yes, it is possible to count objects crossing multiple regions using Ultralytics YOLO11. You can utilize the RegionCounter class to define multiple regions and track objects across them. The objects' movement through these regions can be tracked using persistent IDs, enabling you to determine which object crossed which regions. For implementation details, refer to the Region Counting Guide.

      1
  2. amulyaamaggididivamiamulyaamaggididivamiGitHub
    import cv2
    from ultralytics import solutions
    
    # Load video file
    cap = cv2.VideoCapture("retail-store.mp4")
    assert cap.isOpened(), "Error reading video file"
    
    # Define the counting line coordinates (adjust as per your scene)
    region_points = [(1135, 714), (1134, 416)]
    
    # Get video properties
    w, h, fps = (int(cap.get(x)) for x in (
        cv2.CAP_PROP_FRAME_WIDTH,
        cv2.CAP_PROP_FRAME_HEIGHT,
        cv2.CAP_PROP_FPS,
    ))
    
    # Setup video writer for output
    video_writer = cv2.VideoWriter(
        "object_counting_output.mp4",
        cv2.VideoWriter_fourcc(*"mp4v"),
        fps,
        (w, h),
    )
    
    # Initialize the object counter
    counter = solutions.ObjectCounter(
        show=False,                 # Don't show live preview
        region=region_points,       # Line coordinates
        model="yolo11n.pt",         # YOLO model
        classes=[0],                # Class 0 = person
        line_width=3,
    )
    
    # Process video frame by frame
    while cap.isOpened():
        success, frame = cap.read()
        if not success:
            print("Video processing complete.")
            break
    
        # Run the counter on the frame
        results = counter(frame)
    
        # Write to output video
        video_writer.write(results.plot_im)
    
    # Cleanup
    cap.release()
    video_writer.release()
    cv2.destroyAllWindows()
    
    print(f"✅ Processing complete. Saved as 'object_counting_output.mp4'")

    I’m getting the count reversed — the number of people entering is shown as OUT, and those exiting are shown as IN. How can I fix this?

    1. RizwanMunawarRizwanMunawarGitHub

      @amulyaamaggididivami Hi, can you please try reversing the region coordinates, like mentioned? I believe this will work.

      region_points = [(1134, 416), (1135, 714)]
    2. Glenn JocherGlenn JocherUltralytics

      @SudhanshuBlaze IN/OUT for line counters is image-axis based, not compass: for a mostly vertical line, IN = motion to the right (+x) and OUT = left; for a mostly horizontal line, IN = down (+y) and OUT = up; you can relabel to N/S/E/W post-process like this:

      def label_dirs(results, p1, p2):
          (x1, y1), (x2, y2) = p1, p2
          vertical = abs(x1 - x2) < abs(y1 - y2)
          return ({"eastbound": results.in_count, "westbound": results.out_count} if vertical
                  else {"southbound": results.in_count, "northbound": results.out_count})

      Details of the IN/OUT logic are in the count_objects method of the ObjectCounter reference.

  3. Forlin12Forlin12GitHub

    Hello, I would like to know how it works to remove how many objects there are per instant region because I can't extract this information.

  4. SudhanshuBlazeSudhanshuBlazeGitHub

    Hi,

    I was wondering in the case of LINE counters, if there's a thumb rule to translate the IN, OUT count to North->South, East-> West, something like this. How do I know which direction is IN and which direction is OUT in the case of LINE counters?

    My coordinates: line_counter1 = [(842, 1434), (640, 2200)]
    line_counter2 = [(1028, 1304), (1094, 1038)]
    line_counter3 = [(1068, 1038), (684, 1048)]
    line_counter4 = [(2498, 546), (3276, 572)]
    line_counter5 = [(3244, 786), (3414, 904)]
    line_counter6 = [(1830, 958), (1668, 710)]

    Thanks in advance

  5. morusskmorusskGitHub

    Hey, I am trying to use solutions.RegionCounter() with conf less than 0.25 but it seems to be ignoring it, is that by design? If I use conf > 0.25 it is taken into account and counts only detections with confidence higher than conf in particular region but lower then 0.25 seems to be ignored and those detections have not chance of being counted by solutions.RegionCounter(). Please advice.

    1. RizwanMunawarRizwanMunawarGitHub

      @morussk Hi, thanks for sharing the details. The counting in region feature relies on object tracking rather than standalone predictions. As a result, detections with a confidence score below 0.25 are ignored by default.

      However, this behaviour can be modified by adjusting the track_high_thresh parameter. Currently, the Solutions class doesn’t support adjusting tracking configuration core options directly, but you can adjust it by cloning the code and modifying the tracker's configurations file.

      Note: We always recommend using the latest version of the Ultralytics Python package. You can update it by running: pip install -U ultralytics.

      Thanks.

      1
    1. Glenn JocherGlenn JocherUltralytics

      @dimasfadhila for region-based object counting in the Ultralytics example, we use models pre-trained on the COCO dataset by default, which includes 80 common object classes. You can see the full class list in our COCO dataset documentation. If you need to count custom objects, you'll want to train on your own dataset using YOLO's training mode.

  6. rejensrejensGitHub

    Process video

    while cap.isOpened(): success, im0 = cap.read() # Read the video frame. if not success: break im0 = region.count(im0) # Count the objects in different regions of frame. cv2.imshow("frame", im0) if cv2.waitKey(1) & 0xFF == ord('q'): break

    this successfully did count and display the objects inside the region, how can i retrieve the number of counts, seems region.count(im0) returns the image only.

    thanks

    1. Glenn JocherGlenn JocherUltralytics(edited)

      @rejens RegionCounter returns a results object, so call it on each frame and read the per-region counts from region_counts:

      results = region(im0)
      print(results.region_counts)  # e.g. {'Region#01': 3}
      im0 = results.plot_im

      The counts are for the current frame (they reset on every frame). Let me know if you need further clarification!

  7. DarkbutbrightDarkbutbrightGitHub

    hi,counter = solutions.ObjectCounter(paras),im0 = counter.count(im0),Can the type information, font size, and position of the count in the video be set?

    1. Glenn JocherGlenn JocherUltralytics(edited)

      @Darkbutbright yes, you can customize the text information, font size and position of the count by modifying the solution source code. For ObjectCounter, the counts are drawn in its display_counts() method (in ultralytics/solutions/object_counter.py) through the SolutionAnnotator, so you can adjust the text rendering there. You can also call the solution and draw your own text on the returned plot_im with cv2.putText(), using results.in_count and results.out_count. Let me know if you need further clarification!

    2. DarkbutbrightDarkbutbrightGitHub

      Thank you for your patient answer, but I really don't know where to get the detailed instructions (documents) of the solutions class. Could you please tell me how to get it (including more clear instructions for using other classes of yolo)?

    3. Glenn JocherGlenn JocherUltralytics

      @Darkbutbright thank you for your question! You can find detailed instructions and documentation for the solutions class and other YOLO functionalities in the Ultralytics Docs. For specific examples, such as region counting or object tracking, check the solutions guide or the respective sections in the repository. Let me know if you need assistance with a particular use case!

  8. kemalfrkkemalfrkGitHub

    Hello, select the area with mouse events how to write the code that counts these classes if it enters a class.Thanks

    1. Glenn JocherGlenn JocherUltralytics

      @kemalfrk to implement object counting in specific regions using mouse events, you can modify the region points dynamically by capturing mouse click events and updating the region coordinates in real-time. You can refer to the Ultralytics YOLOv8 region counting example for guidance on how to set up and use the RegionCounter. If you have further questions or need additional customization, feel free to ask!

  9. MuhammedEnesGurkanMuhammedEnesGurkanGitHub

    Hello, I use object counter but ı want to count only sheeps how can ı set classes_names to sheeps. Please help me

    1. Glenn JocherGlenn JocherUltralytics

      @MuhammedEnesGurkan to count only sheep, use the --classes argument to specify the class index for sheep in your model. For example, if sheep are class 2, run: python yolov8_region_counter.py --source "path/to/video.mp4" --classes 2. Adjust the class index as needed based on your model's class mapping.