DEV Community

Cover image for How to Code a Virtual Fence in Python for Security Systems
kora pertenson
kora pertenson

Posted on

How to Code a Virtual Fence in Python for Security Systems

Introduction
Wow, seriously --- have you ever walked past a house and thought, "If
only the fence could tell me who's at the gate"? I have. I was late for
a meeting, my neighbor's dog started barking, and I remember thinking: a
fence that actually knows stuff would be handy, right? That little
moment got me tinkering. I'll tell you how to build a simple virtual
fence in Python --- nothing sci-fi, just practical and surprisingly
satisfying.

Context
I once tried to retrofit a cheap camera with motion alerts, and it
worked... kinda. False alarms galore. That's when I learned that
boundary logic --- defining where something is allowed to be ---
matters more than just "motion detected." So you're gonna learn an
approachable way to code a virtual boundary, reduce noise, and make
alerts smarter. You're welcome.

Key concepts (casual list)

  • Geofencing basics --- what a virtual boundary actually means.\
  • Coordinate systems --- latitude/longitude vs. pixels (camera view).\
  • Thresholds & hysteresis --- stop the ping-pong of on/off alerts.\
  • Event classification --- is it a person, pet, or leaf?\
  • Integration hooks --- how to wire your fence to alerts or actuators.

How-to: Build the virtual fence (step by step, with tiny personal
riffs)

1. Geofencing basics

Think of a virtual fence as a polygon. You can store its coordinates in
a simple JSON file. For my first hack, I drew a box on an image, saved
the corners, and that became my "fence." You'd think you need fancy
tools --- nah, pencil and trial-and-error work fine.

2. Coordinate choice

If you're working with CCTV frames, use pixel coordinates. For outdoor
zones across multiple devices, use GPS. I mixed both once (don't do that
unless you enjoy headaches), so pick one and stick with it.

3. Hit detection

Use a standard algorithm (ray casting or winding number) to test if a
detected object's centroid is inside the polygon. I used a tiny Python
function the first time and it felt glorious. Example: when a delivery
guy steps inside the area, your code notices.

4. Thresholds & hysteresis

Don't alert on a single frame. Wait for N consecutive frames (say 3--5).
Also add a small cooldown so alerts aren't spammy. I learned this the
hard way --- the neighbor's cat crossed the frame and my phone went off
like five times. Not great.

5. Event classification

Plug a light classifier (mobile-friendly) to tag objects as "person",
"animal", or "unknown." Only trigger for types you care about. Quick
wins: a tiny MobileNet or even simple size/aspect heuristics. I once
filtered by bounding box size and cut alerts by half. Simple wins, you
know?


Mini example (extended Python code)

import json
import time

# Simple point-in-polygon function using ray casting
def point_in_polygon(x, y, polygon):
    num = len(polygon)
    j = num - 1
    inside = False
    for i in range(num):
        xi, yi = polygon[i]
        xj, yj = polygon[j]
        intersect = ((yi > y) != (yj > y)) and                     (x < (xj - xi) * (y - yi) / (yj - yi + 1e-9) + xi)
        if intersect:
            inside = not inside
        j = i
    return inside

# Load polygon (fence) from JSON
def load_polygon(path):
    with open(path, "r") as f:
        return json.load(f)

# Fake detection function (simulate detections)
def detect_objects(frame):
    # Replace this with a real detection model output
    return [{"x": 120, "y": 80, "label": "person"}]

# Main loop
def run_virtual_fence(fence_file):
    fence = load_polygon(fence_file)
    consecutive = 0
    cooldown = 0

    for frame in range(100):  # simulate 100 frames
        detections = detect_objects(frame)
        inside = any(
            point_in_polygon(det["x"], det["y"], fence) and det["label"] == "person"
            for det in detections
        )

        if inside and cooldown == 0:
            consecutive += 1
        else:
            consecutive = 0

        if consecutive >= 3:  # threshold
            print("🚨 Alert! Someone entered the virtual fence.")
            cooldown = 5  # cooldown for next alert
            consecutive = 0

        if cooldown > 0:
            cooldown -= 1

        time.sleep(0.1)

# Example JSON polygon file content (fence.json)
# [[50, 50], [200, 50], [200, 200], [50, 200]]

# Run the system
# run_virtual_fence("fence.json")
Enter fullscreen mode Exit fullscreen mode

This snippet shows how to:\

  • Load a polygon (your fence).\
  • Detect objects (fake detections here).\
  • Apply point-in-polygon logic.\
  • Trigger alerts after 3 consecutive detections.\
  • Add a cooldown to avoid alert spam.

Mini-case\
Think of your virtual fence like a doorman who gets bored easily: train
him to notice only the important stuff and to ignore pigeons. That's
thresholds + classification. If the doorman screams every time a
squirrel hops by, he's no use.


Practical resources (casual recommendations)\

  • For object detection: use lightweight models (MobileNet, YOLO-Nano).\
  • For mapping tools: a simple JSON schema is enough.\
  • For alerts: integrate with webhooks, MQTT, or email.\ Oh --- and if you ever need physical fence inspiration, check a local installer if you're also doing hardware --- for instance, folks hunting for a stylish barrier might look into Wrought Iron Fence in Chicago. Just saying.

Benefits (short, punchy bullets)\

  • Cuts false alarms --- fewer "oh no" moments, more sleep.\
  • Scalable --- one script can guard many cameras if you architect it right.\
  • Cheap wins --- you don't need an enterprise system to be safer.\
  • Customizable --- you decide what matters: packages, people, or pets.\
  • Fun project --- honestly, it's a geeky weekend well spent.

Extra note\
If you're posting about perimeter options or mixing virtual and physical boundaries, some homeowners compare styles --- like Wrought Iron Fence Chicago or Chicago Wrought Iron Fence --- those are neat when you want the real thing plus tech. (Yeah, I dropped those links in here because people ask about combining looks and function.)


Conclusion
Give it a try this week --- sketch a polygon on one camera, run a simple point-in-polygon test, add a 3-frame threshold, and see how it feels. You'll tweak it, promise. If you want, drop a comment below about what camera you're using and I'll share a tailored snippet. Go build you'll see!

Top comments (0)