RegionKit Open Editor →
tripwire computer vision line crossing object counting detection zones

What Is a Tripwire in Computer Vision?

A tripwire (or virtual tripwire) is a line drawn across a camera's field of view that triggers an event when an object crosses it. Learn how they work, when to use them, and how to define them with a browser-based tool.

· RegionKit

A virtual tripwire is a line drawn across a camera’s field of view that triggers an event — a count, an alert, a log entry — whenever a tracked object crosses it. The name comes from physical security tripwires; the virtual version works the same way without any hardware.

Tripwires are one of the most common spatial configurations in deployed CV systems, and one of the most misunderstood. This article explains how they work, the different variants, and how to define them accurately.

How a tripwire works

At its core, a tripwire is a geometry check run on each frame of a video stream:

  1. An object detector identifies objects and produces bounding boxes (or centroids)
  2. A tracker assigns persistent IDs to objects across frames
  3. For each tracked object, check whether its centroid (or a bounding box edge) has crossed the defined line between the previous frame and the current one
  4. If it has, fire an event

The “crossing” check is typically implemented as a sign change in the cross-product (or dot product) between the line’s direction vector and the vector from the line to the object’s position. When the sign flips from positive to negative (or vice versa), the object has crossed.

def crossed_line(prev_pt, curr_pt, line_start, line_end):
    """
    Returns True if the path from prev_pt to curr_pt crosses the line
    segment from line_start to line_end.
    """
    def cross_product_sign(a, b, p):
        return (b[0]-a[0])*(p[1]-a[1]) - (b[1]-a[1])*(p[0]-a[0])

    d1 = cross_product_sign(line_start, line_end, prev_pt)
    d2 = cross_product_sign(line_start, line_end, curr_pt)
    return (d1 > 0) != (d2 > 0)

Single tripwire vs dual tripwire

Single tripwire — One line, one event type. Any crossing triggers the same event regardless of direction. Use for presence detection (“someone crossed the perimeter”) or object counting where direction doesn’t matter.

Dual tripwire — Two closely spaced parallel lines. Track which line each object crosses first:

The gap between the two lines should be large enough that no single-frame position jump skips both lines, but small enough to fit in the monitored corridor. A 10–20 pixel gap (at typical camera resolutions) works well for pedestrians.

Placing tripwires effectively

Placement matters more than precise geometry. A tripwire at a door that doesn’t span the full doorway will miss objects that walk around its ends. A tripwire in the middle of an open corridor will catch everything that passes, including objects you didn’t intend to count.

Guidelines:

Drawing tripwires in RegionKit

Tripwires are drawn as Polyline annotations in RegionKit. A polyline is an open path — like a polygon but not closed — making it the natural shape for a crossing line.

  1. Press L or click the Polyline tool
  2. Click to place each vertex of the line (usually just two for a simple straight tripwire)
  3. Double-click or press Enter to commit
  4. Label it (entrance_in, entrance_out, etc.) and place it on a “Tripwires” layer

For dual tripwires, draw two parallel polylines labelled line_a and line_b. Export as native JSON and read both line coordinates in your tracking code.

Reading tripwire coordinates in Python

import json
import numpy as np

with open('scene.json') as f:
    scene = json.load(f)

tripwires = {}
for ann in scene['annotations']:
    if ann['type'] != 'polyline':
        continue
    pts = ann['data']['points']
    coords = list(zip(pts[::2], pts[1::2]))
    tripwires[ann.get('label', 'tripwire')] = coords

for name, pts in tripwires.items():
    line_start = np.array(pts[0])
    line_end   = np.array(pts[-1])
    print(f"Tripwire '{name}': {line_start}{line_end}")

Common implementation mistakes

Not using a tracker. A simple frame-by-frame detection without object IDs will fire on every frame where an object is near the line, generating dozens of events per crossing. Always use an object tracker (ByteTrack, DeepSORT, SORT) so each physical object has a persistent ID and you can detect the moment of crossing rather than continuous proximity.

Testing the centroid only. For large objects or objects moving at an angle, the centroid may not cross the line even when the object clearly does. Testing the leading edge of the bounding box (the edge in the direction of travel) gives better accuracy.

Ignoring the line’s orientation. Make sure your crossing direction logic matches the line’s drawn direction. In RegionKit, a polyline is stored as an ordered list of points — the direction from the first vertex to the last defines the “forward” direction for your sign-change calculation.


Related: How to Define Regions of Interest for Computer Vision · Detection Zone Editor

Try RegionKit — it's free

Browser-based ROI editor. No install, no account, no data upload.

Open the Editor